Seamless Bot Protection: Integrating Cloudflare Turnstile with Nuxt 3
Cloudflare Turnstile offers a modern, visual CAPTCHA-free approach to shield your web applications and forms from malicious bots. For developers working with Nuxt 3, integrating this powerful solution is streamlined through the dedicated nuxt-turnstile
module. This guide walks you through the process, from initial setup to component integration.
1. Install the Nuxt Turnstile Module
Begin by adding the nuxt-turnstile
module to your project dependencies. Open your terminal within your Nuxt 3 project directory and execute one of the following commands:
npm install nuxt-turnstile
# or
yarn add nuxt-turnstile
2. Configure Your Cloudflare Turnstile Widget
To obtain the necessary keys for your application, you’ll need to set up a Turnstile widget on Cloudflare:
- Access Cloudflare: Log in to your Cloudflare account. If you don’t have one, you can create a free account.
- Navigate to Turnstile: Head to the “Turnstile” section in your Cloudflare dashboard.
- Add a New Widget: Click on “Add Widget.” You’ll be prompted to configure your new widget.
- Define Site Details:
- Provide a descriptive name for your site or project.
- Crucially, add your application’s domain(s) (hostnames). Even for testing, you can use a free temporary domain if you don’t have a production one yet. Click “Add hostnames,” enter your domain, and confirm.
- Retrieve Your Keys: Once configured, Cloudflare will generate two essential keys:
- Site Key (Public): Used on your frontend.
- Secret Key (Private): Used for backend validation.
Keep these keys secure, especially the secret key.
3. Configure Nuxt 3 Project Environment
Next, integrate your Cloudflare Turnstile keys into your Nuxt 3 project’s configuration:
- Create/Update
.env
file: In the root of your project, ensure you have a.env
file. Add your Site Key and Secret Key to this file. Remember, the values below are placeholders:TURNSTILE_SITE_KEY = 'your_cloudflare_site_key_here' TURNSTILE_SECRET_KEY = 'your_cloudflare_secret_key_here'
- Update
nuxt.config.ts
: Modify yournuxt.config.ts
file to include thenuxt-turnstile
module and expose the keys viaruntimeConfig
:export default defineNuxtConfig({ // Add the turnstile module modules: ["@nuxtjs/turnstile"], // Configure runtime environment variables runtimeConfig: { turnstile: { secretKey: process.env.TURNSTILE_SECRET_KEY, // Keep secret key server-side }, public: { turnstile: { siteKey: process.env.TURNSTILE_SITE_KEY, // Expose site key publicly } } } })
4. Integrate Turnstile into Your Nuxt Component
Now you’re ready to place the Turnstile widget within your application’s components, typically on forms (e.g., login, registration, contact forms).
Here’s an example of integrating NuxtTurnstile
into a basic login form:
<script setup lang="ts">
import { ref } from 'vue'
const form = ref({
email: '',
password: ''
})
const turnstileToken = ref('') // Reactive variable to store the Turnstile token
const handleSubmit = () => {
if (!turnstileToken.value) {
alert('Please complete the Turnstile challenge before submitting!')
return
}
// Your form submission logic goes here,
// including sending turnstileToken.value to your backend for verification.
console.log('Form submitted:', {
...form.value,
turnstileToken: turnstileToken.value
})
}
</script>
<template>
<form
class="max-w-sm mx-auto space-y-6 p-6 border rounded-xl shadow-lg bg-white"
@submit.prevent="handleSubmit"
>
<h2 class="text-2xl font-bold text-center">Login</h2>
<div>
<label class="block text-sm font-medium mb-1">Email</label>
<input
v-model="form.email"
type="email"
placeholder="Enter your email"
class="w-full px-3 py-2 border rounded-md focus:ring focus:ring-blue-400"
required
/>
</div>
<div>
<label class="block text-sm font-medium mb-1">Password</label>
<input
v-model="form.password"
type="password"
placeholder="Enter your password"
class="w-full px-3 py-2 border rounded-md focus:ring focus:ring-blue-400"
required
/>
</div>
<!-- The NuxtTurnstile component -->
<NuxtTurnstile
v-model="turnstileToken"
:options="{
theme: 'auto', // or 'light', 'dark'
size: 'normal', // or 'compact'
action: 'login', // A custom action name for analytics
language: 'pt-BR' // Set the widget language
}"
/>
<button
type="submit"
class="w-full py-2 px-4 bg-blue-600 text-white font-semibold rounded-lg shadow hover:bg-blue-700 transition"
>
Login
</button>
</form>
</template>
When rendered, the NuxtTurnstile
component will display a discreet challenge (often invisible to legitimate users) that verifies the user is human. The generated token is then bound to turnstileToken.value
.
Backend Token Validation
Crucially, after a user submits the form and you receive the turnstileToken
on your backend, you must validate this token with Cloudflare using your Secret Key. This step ensures the token is legitimate and prevents bots from bypassing the frontend check.
By following these steps, you can effectively integrate Cloudflare Turnstile into your Nuxt 3 application, enhancing security without sacrificing user experience.