Conditionally enforce Turnstile
This tutorial explains how to conditionally enforce Turnstile based on the incoming request, such as a pre-shared secret in a header or a specific IP address.
You may have setups such as automation that cannot load or run the Turnstile challenge. Using HTMLRewriter, this tutorial will demonstrate how to conditionally handle the client-side widget and Siteverify API when specific criteria are met.
This tutorial will modify the existing Turnstile demo ↗ to conditionally remove the existing script and widget container elements.
export default {  async fetch(request) {    // ...
    if (request.headers.get("x-bypass-turnstile") === "VerySecretValue") {      class RemoveHandler {        element(element) {          element.remove();        }      }
      return new HTMLRewriter()        // Remove the script tag        .on(          'script[src="https://challenges.cloudflare.com/turnstile/v0/api.js"]',          new RemoveHandler(),        )       // Remove the container used in implicit rendering        .on(          '.cf-turnstile',          new RemoveHandler(),        )       // Remove the container used in explicit rendering        .on(          '#myWidget',          new RemoveHandler(),        )        .transform(body);    }
    return new Response(body, {      headers: {        "Content-Type": "text/html",      },    });  },};We will exit early in our validation if the same logic we used to remove the client-side elements is present.
async function handlePost(request) {  if (request.headers.get("x-bypass-turnstile") === "VerySecretValue") {    return new Response('Turnstile not enforced on this request')  }  // Proceed with validation as normal!  const body = await request.formData();  // Turnstile injects a token in "cf-turnstile-response".  const token = body.get('cf-turnstile-response');  const ip = request.headers.get('CF-Connecting-IP');  // ...}With these changes, Turnstile will not be enforced on requests with the header x-bypass-turnstile: VerySecretValue present.
After running npm run dev in the project folder, you can test the changes by running the following command:
curl -X POST http://localhost:8787/handler -H "x-bypass-turnstile: VerySecretValue"Turnstile not enforced on this requestWas this helpful?
- Resources
- API
- New to Cloudflare?
- Directory
- Sponsorships
- Open Source
- Support
- Help Center
- System Status
- Compliance
- GDPR
- Company
- cloudflare.com
- Our team
- Careers
- © 2025 Cloudflare, Inc.
- Privacy Policy
- Terms of Use
- Report Security Issues
- Trademark