Switch to light mode

Cloudflare Turnstile Setup Guide (2026): Add CAPTCHA-Free Bot Protection

- 6 min read

Web form with a Cloudflare Turnstile bot verification widget shown before the submit button

Setting Up Cloudflare Turnstile

Turnstile is Cloudflare’s alternative to reCAPTCHA. It runs a set of background checks (browser behavior, request patterns, device signals) instead of asking users to click traffic lights or type distorted text. Most visitors never see a challenge at all. It’s free, and it’s a straightforward way to stop automated form spam without adding friction to a real user’s checkout, signup, or contact form.

Prerequisites

  • A Cloudflare account (the zone doesn’t need to be on Cloudflare’s DNS, Turnstile works independently)
  • A form you control the frontend and backend submission handling for

Getting Your Site Keys

  1. In the Cloudflare dashboard, go to Turnstile and add a new site.
  2. Enter the domain(s) the widget will run on.
  3. Cloudflare issues two keys: a site key (public, goes in your HTML) and a secret key (private, used server-side to verify the token).

Adding the Widget

Drop the widget div anywhere before your submit button:

<div class="cf-turnstile" data-sitekey="YOUR_SITE_KEY"></div>

Load Cloudflare’s script once, anywhere on the page (the <head> or right before </body> both work):

<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>

On submit, Turnstile automatically adds a hidden field named cf-turnstile-response to the form. That token is what gets verified server-side.

Verifying the Token Server-Side

The widget alone doesn’t block anything, it just generates a token. Verification has to happen on your backend, or the check is trivial to bypass:

POST https://challenges.cloudflare.com/turnstile/v0/siteverify
  secret: YOUR_SECRET_KEY
  response: <the cf-turnstile-response value from the form submission>

The response comes back with a success: true/false field. Reject the submission server-side if success is false, before doing anything else with the form data.

Common Pitfalls

  • Verifying only on the frontend. The widget rendering and the token existing proves nothing by itself. If the secret-key verification step is skipped, a bot can simply submit the form without ever loading the widget.
  • Forgetting the token expires. Tokens are single-use and expire after a short window. If a user takes a long time filling out a form before submitting, the token can go stale, causing a false rejection. Consider re-running the widget’s execute() method right before submission for longer forms.
  • One secret key hardcoded across environments. Use separate site/secret key pairs for staging and production so a compromised staging key doesn’t affect production traffic.
  • Widget not rendering: almost always a domain mismatch between what’s registered in the Turnstile site settings and the domain the page is actually served from (including www vs non-www).

Turnstile is a low-effort addition for any public form (contact, signup, application) that’s getting spam submissions, and it doesn’t cost real users the friction that traditional CAPTCHAs do.

© 2024 Shawn Mayzes. All rights reserved.