Skip to content

Vue 3 / Nuxt

Install and use the @myrasec/eu-captcha-vue package to embed EU CAPTCHA in your Vue 3 or Nuxt application.

Package Version
@myrasec/eu-captcha-vue 1.0.0

Server-side verification is identical regardless of frontend framework — see Server-Side Verification.


Installation

npm i @myrasec/eu-captcha-vue

Basic usage

<script setup>
import { EuCaptcha, isEuCaptchaDone } from "@myrasec/eu-captcha-vue";

const captchaSitekey = "EUCAPTCHA_SITE_KEY";
</script>

<template>
  <form @submit.prevent="handleSubmit">
    <!-- your fields -->
    <EuCaptcha :sitekey="captchaSitekey" />
    <button type="submit">Submit</button>
  </form>
</template>

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.

Checking completion before submit

import { isEuCaptchaDone } from "@myrasec/eu-captcha-vue";

function handleSubmit() {
  if (!isEuCaptchaDone()) {
    // challenge not yet complete
    return;
  }

  // proceed with form submission
}

Callbacks

Use onComplete, onExpired, and onError to react to widget events without listening for window messages manually:

<EuCaptcha
  :sitekey="captchaSitekey"
  :on-complete="(token) => { verified = true; }"
  :on-expired="() => { verified = false; }"
  :on-error="() => { errorMsg = 'CAPTCHA failed. Please try again.'; }"
/>

Deferred execution

Set :autostart="false" and provide a widgetId to suppress the automatic challenge, then trigger it programmatically:

<EuCaptcha
  :sitekey="captchaSitekey"
  widget-id="login-captcha"
  :autostart="false"
  :on-complete="(token) => submitForm(token)"
/>

<button @click="(window as any).euCaptcha.execute('login-captcha')">
  Verify and submit
</button>

Listening for completion

If you prefer to use the euCaptchaDone window message — for example to enable a submit button from outside the component — listen for it with onMounted/onUnmounted:

import { onMounted, onUnmounted } from "vue";

function listenForCaptchaDone(msg) {
  if (msg.data.type === "euCaptchaDone") {
    submitEnabled.value = true;
  }
}

onMounted(() => window.addEventListener("message", listenForCaptchaDone, false));
onUnmounted(() => window.removeEventListener("message", listenForCaptchaDone, false));

Retrieving the token

Once complete, the widget injects a hidden input into the surrounding <form>:

<input type="hidden" name="eu-captcha-response" value="<token>" />

If you are submitting via fetch or axios, read the token from the DOM or use the onComplete prop:

const token = document.querySelector('input[name="eu-captcha-response"]')?.value ?? "";

Pass it to your server endpoint and verify it with the verification API.