Spam Protection

Cloudflare Turnstile

Protect your forms with Cloudflare's low-friction CAPTCHA alternative

Cloudflare Turnstile helps protect your forms from automated spam without relying on traditional image puzzles. Static Forms supports Cloudflare Turnstile on paid plans and verifies tokens server-side using your saved secret key.

Need the strategic overview?

If you're evaluating Turnstile or want a rollout checklist, read the Cloudflare Turnstile best practices guide. If you're implementing now, this page has the exact setup details.

Paid Feature

Cloudflare Turnstile is available on Pro and Agency plans. Upgrade your plan if you want to use it in production.

Why teams choose Cloudflare Turnstile

  • ✅ Minimal user interruption
  • ✅ No Google dependency
  • ✅ Strong default experience for modern sites

What Static Forms expects

  • ✅ Cloudflare Turnstile secret key saved in dashboard
  • ✅ Site key kept in your form HTML or frontend app
  • ✅ Token submitted as cf-turnstile-response

Create Your Cloudflare Turnstile Widget

1

Open the Cloudflare dashboard

Go to Cloudflare Turnstile and create a widget for your site.

2

Register your domains

Add the domains where your form will run, including localhost if you want to test locally.

3

Copy your keys

Cloudflare gives you a site key and a secret key. The site key is public and goes in your form code. The secret key stays in Static Forms settings.

4

Save your secret key in Static Forms

Open the form's Security tab, switch to Cloudflare Turnstile, paste your secret key, and save.

Implementation Checklist

  • Create your Turnstile widget and copy both keys
  • Register production, staging, preview, and localhost domains as needed
  • Save only the secret key in the form's Security tab
  • Add the widget with your site key in the frontend
  • Confirm your form submits cf-turnstile-response
  • Run a real submission test before launch

Framework setup

Turnstile does not require a React package. In React and Next.js, you load Cloudflare's script, render the widget client-side, and append cf-turnstile-response before posting to Static Forms.

Framework Examples

Choose the version that matches your stack. Each example uses the correct widget script, response field, and Static Forms submission flow.

contact-form.html

Key Points

  • Use the site key in your HTML, not the secret key
  • Keep the token field name as cf-turnstile-response
  • Save the secret key only in Static Forms dashboard settings
  • Render with execution: 'execute' and call turnstile.execute() from your submit handler so the token is freshly minted at submit time — Turnstile tokens expire 300s after issuance, so render-on-load can fail on slow uploads or long forms

Stable error codes for retry logic

On captcha failures, /submit returns a JSON body with a stable code field. Switch on it from your client to retry intelligently:

  • captcha_required — no token was sent
  • captcha_expired_or_reused — token aged out or was already redeemed; refresh and retry
  • captcha_failed — rejected for another reason (wrong secret, bad signature)

Environment Variables

Keep the site key in a public frontend environment variable and save the secret key only in Static Forms settings.

Bash

React Notes

  • Use the explicit render script (?render=explicit) so you control when the widget mounts
  • Render with execution: 'execute' + appearance: 'interaction-only' — most users see no widget at all
  • Call window.turnstile.execute(widgetId) inside your submit handler and await the callback to get a fresh token
  • Call window.turnstile.remove(widgetId) in your useEffect cleanup to avoid orphaned widgets in Cloudflare's registry

Troubleshooting

Cloudflare Turnstile token rejected

Make sure the token is submitted as cf-turnstile-response and that the secret key saved in Static Forms matches the widget site key you are using.

Widget does not load

Confirm the Cloudflare Turnstile script is loaded, your domain is allowed in Cloudflare, and any ad blockers or CSP rules are not blocking the Cloudflare challenge domain.

Compare providers

Want to compare options? See the Spam Protection overview, reCAPTCHA guide, and ALTCHA guide.