Cloudflare Turnstile is a verification tool, much like CAPTCHA. It was added to the sign up form 12 December 2025.
Overview
- We use managed mode with proper race condition handling. The widget runs verification in the background, only showing a challenge UI when Cloudflare determines it’s necessary (managed mode).
- Server-side validation: We validate Turnstile tokens server-side with Cloudflare’s API before calling Supabase. This provides granular control (CAPTCHA only on sign-up, not also sign-in and password reset as Supabase requires) while maintaining security.
To reiterate: we no longer use Supabase’s built-in CAPTCHA feature because it’s so wide-sweeping. All validation happens in our server action before calling Supabase.
Implementation details
We use Turnstile’s managed variant, which:
- Runs invisibly by default: Most legitimate users never see a CAPTCHA challenge.
- Shows challenges when needed: Cloudflare automatically displays a challenge if it detects suspicious behaviour (managed mode).
- Handles race conditions: The form waits for token generation before submission, preventing premature form submits.
- Provides clear feedback: Users see "Verifying..." state while waiting, and error messages if verification fails.
Security model
Why this is secure even though Supabase doesn't know about the CAPTCHA:
- Server-side validation gate: The
signUpAction validates the Turnstile token with Cloudflare's API before calling Supabase.
- No token means no sign-up: If validation fails, the function returns early and Supabase is never called.
- Secret key validation: The server uses
TURNSTILE_SECRET_KEY (never exposed to clients) to verify tokens with Cloudflare.
- Bots can’t bypass: Even if a bot bypasses the frontend, they can’t produce a valid token without solving the challenge.
Environment variables
Turnstile verification requires three environment variables:
NEXT_PUBLIC_TURNSTILE_SITEKEY: Cloudflare Turnstile site key (public, used client-side)