# Common Patterns ## Form Integration ### Basic Form (Implicit Rendering) ```html
``` ### Controlled Form (Explicit Rendering) ```javascript ``` ## Framework Patterns ### React ```tsx import { useState } from 'react'; import Turnstile from '@marsidev/react-turnstile'; export default function Form() { const [token, setToken] = useState(null); return (
{ e.preventDefault(); if (!token) return; await fetch('/api/submit', { method: 'POST', body: JSON.stringify({ 'cf-turnstile-response': token }) }); }}> ); } ``` ### Vue / Svelte ```vue token = e.detail.token} /> ``` ## Server Validation ### Cloudflare Workers ```typescript interface Env { TURNSTILE_SECRET: string; } export default { async fetch(request: Request, env: Env): Promise { if (request.method !== 'POST') { return new Response('Method not allowed', { status: 405 }); } const formData = await request.formData(); const token = formData.get('cf-turnstile-response'); if (!token) { return new Response('Missing token', { status: 400 }); } // Validate token const ip = request.headers.get('CF-Connecting-IP'); const result = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ secret: env.TURNSTILE_SECRET, response: token, remoteip: ip }) }); const validation = await result.json(); if (!validation.success) { return new Response('CAPTCHA validation failed', { status: 403 }); } // Process form... return new Response('Success'); } }; ``` ### Pages Functions ```typescript // functions/submit.ts - same pattern as Workers, use ctx.env and ctx.request export const onRequestPost: PagesFunction<{ TURNSTILE_SECRET: string }> = async (ctx) => { const token = (await ctx.request.formData()).get('cf-turnstile-response'); // Validate with ctx.env.TURNSTILE_SECRET (same as Workers pattern above) }; ``` ## Advanced Patterns ### Pre-Clearance (Invisible) ```html
``` ### Token Refresh on Expiry ```javascript let widgetId = window.turnstile.render('#container', { sitekey: 'YOUR_SITE_KEY', 'refresh-expired': 'manual', 'expired-callback': () => { console.log('Token expired, refreshing...'); window.turnstile.reset(widgetId); } }); ``` ## Testing ### Environment-Based Keys ```javascript const SITE_KEY = process.env.NODE_ENV === 'production' ? 'YOUR_PRODUCTION_SITE_KEY' : '1x00000000000000000000AA'; // Always passes const SECRET_KEY = process.env.NODE_ENV === 'production' ? process.env.TURNSTILE_SECRET : '1x0000000000000000000000000000000AA'; ```