LogoBetter Captcha

Vue

Using better-captcha with Vue

Installation

npm i @better-captcha/vue

Basic Usage

<template>
  <ReCaptcha sitekey="your-site-key" />
</template>

<script setup lang="ts">
import { ReCaptcha } from "@better-captcha/vue/provider/recaptcha";
</script>

Imperative Handle

Vue uses template refs or the useCaptcha composable for reactive access to the imperative handle.

<template>
  <ReCaptcha
    ref="recaptchaRef"
    sitekey="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI"
    @ready="onReady"
  />
  <button @click="execute">Execute</button>
  <button @click="reset">Reset</button>
  <button @click="logResponse">Log response</button>
</template>

<script setup lang="ts">
import { useCaptcha } from "@better-captcha/vue";
import { ReCaptcha, type ReCaptchaHandle } from "@better-captcha/vue/provider/recaptcha";

const { captchaRef, handle, execute, reset } = useCaptcha<ReCaptchaHandle>();

const recaptchaRef = captchaRef;

const onReady = (readyHandle: ReCaptchaHandle) => {
  console.log("Captcha ready", readyHandle);
};

const logResponse = () => {
  console.log(handle.value?.getResponse());
};
</script>

The useCaptcha() composable keeps a stable handle reference and exposes helpers like execute and reset. You can also access the handle directly via template refs.

Lifecycle Callbacks

All captcha components support three lifecycle callbacks via Vue events.

<template>
  <ReCaptcha 
    sitekey="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI"
    @ready="handleReady"
    @solve="handleSolve"
    @error="handleError"
  />
</template>

<script setup lang="ts">
import { ReCaptcha, type ReCaptchaHandle } from "@better-captcha/vue/provider/recaptcha";

const handleReady = (handle: ReCaptchaHandle) => {
  console.log("Captcha is ready", handle);
};

const handleSolve = (token: string) => {
  console.log("Captcha solved with token:", token);
  // Send token to your backend for verification
};

const handleError = (error: Error) => {
  console.error("Captcha error:", error);
};
</script>
EventParametersDescription
@ready(handle: Handle) => voidEmitted when the widget is rendered and ready (receives handle)
@solve(token: string) => voidEmitted when the challenge is solved with the response token
@error(error: Error) => voidEmitted when an error occurs during initialization or solving

Manual Rendering

By default, captchas automatically render on mount. For more control, disable auto-rendering and trigger it manually.

<template>
  <ReCaptcha 
    ref="recaptchaRef" 
    sitekey="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI" 
    :autoRender="false" 
  />
  <button @click="showCaptcha">Show Captcha</button>
</template>

<script setup lang="ts">
import { ref } from "vue";
import { ReCaptcha } from "@better-captcha/vue/provider/recaptcha";

const recaptchaRef = ref(null);

const showCaptcha = () => {
  recaptchaRef.value?.render();
};
</script>

Common Props

PropTypeRequiredDescription
sitekeystringYour provider's site key
optionsobjectProvider-specific configuration options
autoRenderbooleanWhether to render automatically on mount (default: true)
scriptOptionsobjectScript loading configuration (see Script Options)
@readyeventEvent when widget is ready
@solveeventEvent when challenge is solved
@erroreventEvent when an error occurs

Handle Methods

All providers implement these methods on the handle:

Prop

Type

Available Providers

ProviderImport Path
ReCaptcha@better-captcha/vue/provider/recaptcha
HCaptcha@better-captcha/vue/provider/hcaptcha
Turnstile@better-captcha/vue/provider/turnstile
Friendly Captcha@better-captcha/vue/provider/friendly-captcha
Private Captcha@better-captcha/vue/provider/private-captcha
Captcha Fox@better-captcha/vue/provider/captcha-fox
Prosopo@better-captcha/vue/provider/prosopo
CapWidget@better-captcha/vue/provider/cap-widget

See the Provider Documentation for provider-specific options and configuration.

On this page