@myrasec/eu-captcha-vue
This package provides an easy integration of EU CAPTCHA from Myra Security for Vue 3 and Nuxt.
842
| Install | |
|---|---|
npm install @myrasec/eu-captcha-vue |
|
| Latest Version: | 1.0.0 |
| Vue: | 3 |
| License: | BSD-2-Clause |
| Last Updated: | Feb 26, 2026 |
| Links: | npm |
Maintainer: charliekilo
This package provides an easy integration of EU CAPTCHA from Myra Security for Vue 3 and Nuxt.
For full documentation see docs.eu-captcha.eu.
You can sign up for free to get a sitekey.
Installation
npm i @myrasec/eu-captcha-vue
Basic usage
<script setup lang="ts">
import { EuCaptcha, isEuCaptchaDone } from "@myrasec/eu-captcha-vue";
const captchaSitekey = "EUCAPTCHA_SITE_KEY";
function handleSubmit(): void {
if (!isEuCaptchaDone()) {
// challenge not yet complete
return;
}
// proceed with form submission
}
</script>
<template>
<form @submit.prevent="handleSubmit">
<!-- your fields -->
<EuCaptcha :sitekey="captchaSitekey" />
<button type="submit">Submit</button>
</form>
</template>
You can test the integration using any fake sitekey. If a sitekey does not exist, the captcha runs with default parameters which allow traffic to pass.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
sitekey |
string |
— | Your public sitekey (required) |
theme |
string |
"light" |
Visual theme: "light" or "dark" |
width |
number |
330 |
Widget width in pixels |
height |
number |
100 |
Widget height in pixels |
widgetId |
string |
— | Custom widget ID. If omitted, an ID is auto-generated. Needed when calling euCaptcha.execute(). |
autostart |
boolean |
true |
Start the challenge automatically on mount. Set to false to defer until euCaptcha.execute(widgetId) is called. |
onComplete |
(token: string) => void |
— | Called with the encoded token when the challenge completes. |
onExpired |
() => void |
— | Called when the token expires (60 minutes after completion). |
onError |
() => void |
— | Called when the challenge fails due to a network or server error. |
Dark theme
<EuCaptcha :sitekey="captchaSitekey" theme="dark" />
Custom width
<EuCaptcha :sitekey="captchaSitekey" :width="280" />
Custom height
<EuCaptcha :sitekey="captchaSitekey" :height="60" />
Deferred execution
Set :autostart="false" and provide a widgetId, then trigger the challenge manually:
<EuCaptcha
:sitekey="captchaSitekey"
widget-id="my-captcha"
:autostart="false"
/>
<button @click="euCaptcha.execute('my-captcha')">Verify</button>
Callbacks
<EuCaptcha
:sitekey="captchaSitekey"
:on-complete="(token) => console.log('token:', token)"
:on-expired="() => console.log('token expired')"
:on-error="() => console.log('challenge error')"
/>
Querying state
Before submitting a form to a server, ensure EU CAPTCHA is done:
import { isEuCaptchaDone } from "@myrasec/eu-captcha-vue";
function handleSubmit(): void {
if (!isEuCaptchaDone()) {
// challenge not yet complete
return;
}
// proceed with form submission
}
Listening to state change
Listen for the euCaptchaDone window message to be notified when the challenge completes:
import { onMounted, onUnmounted } from "vue";
function listenForCaptchaDone(msg: MessageEvent): void {
if (msg.data.type === "euCaptchaDone") {
// enable submit button, update reactive state, etc.
}
}
onMounted(() => window.addEventListener("message", listenForCaptchaDone, false));
onUnmounted(() => window.removeEventListener("message", listenForCaptchaDone, false));
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 1.0.0 | >3.0.0 | BSD-2-Clause | |
| 0.0.6 | >3.0.0 | ||
| 0.0.5 | >3.0.0 | ||
| 0.0.4 | >3.0.0 | ||
| 0.0.3 | >3.0.0 | ||
| 0.0.2 | >3.0.0 | ||
| 0.0.1 | >3.0.0 |