@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