Nuxt 3/4 Module

Direct Captcha Guard

Bot protection using Cloudflare Turnstile with automatic fallback to Google reCAPTCHA. One component, multiple providers, seamless experience.

🛡️

Multi-Provider

Turnstile primary with reCAPTCHA fallback

Auto-Import

Component is globally available

🎯

TypeScript

Full type definitions included

🔄

Auto-Fallback

Seamless provider switching

Installation

Get up and running in just a few steps

1

Configure npm for GitHub Packages

Create an .npmrc file in your project root:

.npmrcbash
# .npmrc - Configure GitHub Package Registry
@directksa:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN
2

Install the package

bash
npm install @directksa/direct-captcha-guard
3

Configure environment variables

.envbash
# .env
TURNSTILE_SITE_KEY=your_turnstile_site_key
RECAPTCHA_V2_SITE_KEY=your_recaptcha_v2_site_key
RECAPTCHA_V3_SITE_KEY=your_recaptcha_v3_site_key
4

Add to Nuxt config

nuxt.config.tsts
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@directksa/direct-captcha-guard'],

  captchaGuard: {
    provider: 'turnstile',
    
    turnstile: {
      siteKey: process.env.TURNSTILE_SITE_KEY
    },
    
    recaptcha: {
      v2SiteKey: process.env.RECAPTCHA_V2_SITE_KEY,
      v3SiteKey: process.env.RECAPTCHA_V3_SITE_KEY,
      version: 'v2'
    },
    
    fallback: {
      enabled: true,
      to: 'recaptcha'
    }
  },

  app: {
    head: {
      script: [
        { src: 'https://challenges.cloudflare.com/turnstile/v0/api.js', async: true }
      ]
    }
  }
})
5

Start using it!

The <CaptchaGuard> component is now globally available!

Live Example

See the component in action with copy-paste ready code

Form Integration

Interactive Demo

Integrate captcha protection into your forms. The submit button is disabled until the captcha is verified. Try it out below!

vue
<template>
  <form @submit.prevent="handleSubmit">
    <input v-model="email" type="email" placeholder="Email" />
    <input v-model="password" type="password" placeholder="Password" />
    
    <CaptchaGuard @verified="onCaptchaVerify" />
    
    <button type="submit" :disabled="!captchaToken">
      Submit
    </button>
  </form>
</template>

<script setup lang="ts">
import type { CaptchaVerifiedPayload } from '@directksa/direct-captcha-guard'

const email = ref('')
const password = ref('')
const captchaToken = ref<string | null>(null)
const captchaMethod = ref<string | null>(null)

function onCaptchaVerify(payload: CaptchaVerifiedPayload | null) {
  if (payload) {
    captchaToken.value = payload.token
    captchaMethod.value = payload.method
  }
}

async function handleSubmit() {
  if (!captchaToken.value) return
  
  await $fetch('/api/submit', {
    method: 'POST',
    body: {
      email: email.value,
      password: password.value,
      captchaToken: captchaToken.value,
      captchaMethod: captchaMethod.value
    }
  })
}
</script>

Testing Failover

Simulate Cloudflare Turnstile being unavailable to test the automatic fallback to reCAPTCHA

To test the automatic fallback mechanism, you can block the Cloudflare Turnstile domain in your system's hosts file. This will simulate Turnstile being unavailable, triggering the fallback to Google reCAPTCHA.

🍎 macOS

Step 1: Edit hosts file

bash
# Open hosts file
sudo nano /etc/hosts

# Add this line at the end
127.0.0.1 challenges.cloudflare.com

# Save and exit (Ctrl+X, Y, Enter)

Step 2: Flush DNS cache

bash
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder

🪟 Windows

Step 1: Edit hosts file

bash
# Open PowerShell as Administrator
notepad C:\Windows\System32\drivers\etc\hosts

# Add this line at the end
127.0.0.1 challenges.cloudflare.com

# Save the file

Step 2: Flush DNS cache

bash
ipconfig /flushdns

🐧 Linux

Step 1: Edit hosts file

bash
# Open hosts file
sudo nano /etc/hosts

# Add this line at the end
127.0.0.1 challenges.cloudflare.com

# Save and exit (Ctrl+X, Y, Enter)

Step 2: Flush DNS cache

bash
sudo systemd-resolve --flush-caches
# or
sudo resolvectl flush-caches
⚠️
Remember to undo! After testing, remove the line from your hosts file and flush DNS again to restore normal Cloudflare Turnstile functionality.

Configuration Options

Complete reference of all available options with defaults

Module Configuration (nuxt.config.ts)

OptionTypeDefaultDescription
provider'turnstile' | 'recaptcha''turnstile'Primary captcha provider to use
turnstile.siteKeystringundefinedCloudflare Turnstile site key
recaptcha.v2SiteKeystringundefinedGoogle reCAPTCHA v2 site key
recaptcha.v3SiteKeystringundefinedGoogle reCAPTCHA v3 site key
recaptcha.version'v2' | 'v3''v2'Default reCAPTCHA version when fallback occurs
fallback.enabledbooleantrueEnable automatic fallback to secondary provider
fallback.to'recaptcha''recaptcha'Provider to fallback to when primary fails
scriptTimeoutnumber2000Timeout in ms for script loading before fallback

Component Props

PropTypeDefaultDescription
fallback'v2' | 'v3'config valueOverride the default reCAPTCHA version for this component instance

Events

EventPayloadDescription
@verifiedCaptchaVerifiedPayload | nullEmitted when captcha verification completes. Receives { token, method } on success or null on failure

TypeScript Types

ts
interface CaptchaVerifiedPayload {
  token: string  // Verification token to send to backend
  method: 'turnstile' | 'recaptcha-v2' | 'recaptcha-v3'
}