### Install Wrangler (Global) Source: https://developers.cloudflare.com/turnstile/spin Install Wrangler globally for use in any project. ```bash npm install -g wrangler ``` -------------------------------- ### Complete explicit rendering example Source: https://developers.cloudflare.com/turnstile/get-started/client-side-rendering A full HTML example demonstrating explicit rendering of a Turnstile widget within a form. It includes basic setup and error handling callbacks. ```html Explicit Rendering
``` -------------------------------- ### Direct API Call Example (Widget Creation) Source: https://developers.cloudflare.com/turnstile/spin/index.md Example of creating a Turnstile widget using the Cloudflare API. ```bash curl -X POST "https://api.cloudflare.com/client/v4/accounts/{id}/challenges/widgets" \ --header "Authorization: Bearer " \ --header "Content-Type: application/json" \ --data '{"name": "my-widget", "domain": "example.com", "mode": "non-interactive"}' ``` -------------------------------- ### Install Turnstile Pages Plugin with bun Source: https://developers.cloudflare.com/turnstile/llms-full.txt Install the Turnstile Pages Plugin using bun. ```bash bun add @cloudflare/pages-plugin-turnstile ``` -------------------------------- ### Direct API Call Example (Worker Upload) Source: https://developers.cloudflare.com/turnstile/spin/index.md Example of uploading a Worker script using the Cloudflare API. ```bash curl -X PUT "https://api.cloudflare.com/client/v4/accounts/{id}/workers/scripts/{script_name}" \ --header "Authorization: Bearer " \ --form "content=@" ``` -------------------------------- ### Install cf-terraforming Tool Source: https://developers.cloudflare.com/turnstile/get-started/widget-management/terraform Install the `cf-terraforming` tool, which is used to import existing Cloudflare resources into Terraform state. ```bash go install github.com/cloudflare/cf-terraforming/cmd/cf-terraforming@latest ``` -------------------------------- ### Install Turnstile Skill for OpenCode Source: https://developers.cloudflare.com/turnstile/spin/index.md Installs the Turnstile skill locally for OpenCode by downloading the index.md file from the Cloudflare Turnstile documentation. ```bash # OpenCode mkdir -p .opencode/skills/turnstile-spin && \ curl -sSL https://developers.cloudflare.com/turnstile/spin/index.md \ -o .opencode/skills/turnstile-spin/SKILL.md ``` -------------------------------- ### Install Turnstile Pages Plugin with npm Source: https://developers.cloudflare.com/turnstile/llms-full.txt Install the Turnstile Pages Plugin using npm. ```bash npm i @cloudflare/pages-plugin-turnstile ``` -------------------------------- ### Check Wrangler Version Source: https://developers.cloudflare.com/turnstile/spin Verify if the Wrangler CLI is installed. If not, instructions are provided for installation. ```bash npx wrangler --version ``` -------------------------------- ### Install Wrangler (Node Project) Source: https://developers.cloudflare.com/turnstile/spin Install Wrangler as a development dependency for a Node.js project. ```bash npm install --save-dev wrangler ``` -------------------------------- ### Install Turnstile Pages Plugin with yarn Source: https://developers.cloudflare.com/turnstile/llms-full.txt Install the Turnstile Pages Plugin using yarn. ```bash yarn add @cloudflare/pages-plugin-turnstile ``` -------------------------------- ### Install Turnstile Pages Plugin with pnpm Source: https://developers.cloudflare.com/turnstile/llms-full.txt Install the Turnstile Pages Plugin using pnpm. ```bash pnpm add @cloudflare/pages-plugin-turnstile ``` -------------------------------- ### Install Wrangler Globally Source: https://developers.cloudflare.com/turnstile/spin Use this command to install the Wrangler CLI globally for use in any project type. ```bash #!/usr/bin/env bash npm install -g wrangler ``` -------------------------------- ### Install Turnstile Skill for Cursor Source: https://developers.cloudflare.com/turnstile/spin/index.md Installs the Turnstile skill locally for Cursor by downloading the index.md file from the Cloudflare Turnstile documentation. ```bash # Cursor mkdir -p .cursor/rules && \ curl -sSL https://developers.cloudflare.com/turnstile/spin/index.md \ -o .cursor/rules/turnstile-spin.md ``` -------------------------------- ### Example Report Summary Source: https://developers.cloudflare.com/turnstile/spin This is an example of a final summary report after completing the Turnstile integration. It lists created resources, validated checks, and next steps. ```text Turnstile Spin: complete. Created: • Widget "myproject (Spin)", sitekey 0x4AAAAAA... • Worker https://turnstile-siteverify-myproject.example.workers.dev • Frontend snippets at: - app/(auth)/signup/page.tsx - app/(auth)/login/page.tsx - app/contact/page.tsx • Skill saved at .claude/skills/turnstile-spin/SKILL.md Validated: ✓ Worker /health returns 200 ✓ Worker handles a dummy token with a structured error ✓ Widget hostname matches example.com Next: • Open one of the protected forms in a browser, solve the widget, and confirm the form submits successfully. • If you need to protect a new form later, prompt: "Use the turnstile-spin skill to add Turnstile to ." ``` -------------------------------- ### Install Turnstile Bundle with Degit Source: https://developers.cloudflare.com/turnstile/llms-full.txt Installs the canonical Turnstile bundle from cloudflare/skills using degit. This script handles argument parsing, directory creation, fetching the bundle, making scripts executable, and reporting the installation status. ```bash #!/usr/bin/env bash # Installs the canonical bundle from cloudflare/skills via degit. # Writes SKILL.md, scripts/, references/, templates/, tests/ into $TARGET_DIR. set -uo pipefail PATH_ARG="" while [[ $# -gt 0 ]]; do case $1 in --path) PATH_ARG="$2"; shift 2 ;; *) echo "persist-skill: unknown arg $1" >&2; exit 2 ;; esac done : "${PATH_ARG:?--path required}" TARGET_DIR=$(dirname "$PATH_ARG") mkdir -p "$TARGET_DIR" # Install the canonical bundle from cloudflare/skills via degit. This writes # SKILL.md, scripts/, references/, templates/, tests/ into $TARGET_DIR. if ! npx --yes degit cloudflare/skills/skills/turnstile-spin "$TARGET_DIR" >/dev/null 2>&1; then echo "persist-skill: degit failed; cannot fetch cloudflare/skills/skills/turnstile-spin." >&2 echo "persist-skill: ensure your network can reach github.com and try again, or install manually." >&2 echo "{\"status\":\"error\",\"reason\":\"degit_failed\"}" exit 1 fi if [ ! -f "$TARGET_DIR/SKILL.md" ]; then echo "persist-skill: bundle extracted but SKILL.md is missing at $TARGET_DIR/SKILL.md." >&2 echo "{\"status\":\"error\",\"reason\":\"skill_missing\"}" exit 1 fi # Make scripts executable so the agent can invoke them directly. if [ -d "$TARGET_DIR/scripts" ]; then chmod +x "$TARGET_DIR/scripts"/*.sh 2>/dev/null || true fi scripts_list=$(ls "$TARGET_DIR/scripts" 2>/dev/null | sed 's/.*/\"&\"/' | paste -sd, -) echo "persist-skill: wrote bundle to $TARGET_DIR" >&2 echo "{\"status\":\"ok\",\"path\":\"$PATH_ARG\",\"bundle_root\":\"$TARGET_DIR\",\"scripts\":[$scripts_list]}" exit 0 ``` -------------------------------- ### Client-side testing with dummy sitekey Source: https://developers.cloudflare.com/turnstile/troubleshooting/testing Replace your production sitekey with a test sitekey for client-side testing. This example shows how to use a visible widget test sitekey. ```html
``` ```html
``` -------------------------------- ### Install Wrangler for Node.js Projects Source: https://developers.cloudflare.com/turnstile/spin Use this command to install the Wrangler CLI as a development dependency in a Node.js project. ```bash #!/usr/bin/env bash npm install --save-dev wrangler ``` -------------------------------- ### Server-Side Integration for Rendering Forms Source: https://developers.cloudflare.com/turnstile/tutorials/excluding-turnstile-from-e2e-tests Integrate Turnstile credentials into your server-side rendering logic. This example shows how to get the correct sitekey using `getTurnstileCredentials` and pass it to the form template. ```javascript app.get('/your-form', (req, res) => { const { sitekey } = getTurnstileCredentials(req); res.render('form', { sitekey }); }); ``` -------------------------------- ### Example User Phrasing for Existing Widget Source: https://developers.cloudflare.com/turnstile/spin Users may phrase their need for assistance with an existing Turnstile widget in various ways. This example shows typical user statements. ```text "I already have a Turnstile sitekey but siteverify never worked, can you help wire it up?" "Set up Spin against my existing widget `0x4AAAAAAA...`" ``` -------------------------------- ### Install Wrangler Globally Source: https://developers.cloudflare.com/turnstile/spin Use this command to install Wrangler globally if you are in a Node.js project and `npx wrangler` fails with 'command not found'. ```bash npm install -g wrangler ``` -------------------------------- ### Client-Side Testing with Visible Widget Source: https://developers.cloudflare.com/turnstile/troubleshooting/testing/index.md Replace your production sitekey with a test sitekey for visible widget testing. This example uses the 'Always passes' test sitekey. ```html
``` -------------------------------- ### Install Turnstile Spin Skill Source: https://developers.cloudflare.com/turnstile/spin/index.md Installs the canonical Turnstile Spin skill bundle from Cloudflare's GitHub repository using degit. Ensures the SKILL.md file is present and makes shell scripts executable. ```bash #!/usr/bin/env bash # Installs the canonical Turnstile Spin skill bundle from cloudflare/skills via degit. # Writes SKILL.md, scripts/, references/, templates/, tests/ into $TARGET_DIR. set -uo pipefail PATH_ARG="" while [[ $# -gt 0 ]]; do case $1 in --path) PATH_ARG="$2"; shift 2 ;; *) echo "persist-skill: unknown arg $1" >&2; exit 2 ;; esac done : "${PATH_ARG:?--path required}" TARGET_DIR=$(dirname "$PATH_ARG") mkdir -p "$TARGET_DIR" # Install the canonical bundle from cloudflare/skills via degit. This writes # SKILL.md, scripts/, references/, templates/, tests/ into $TARGET_DIR. if ! npx --yes degit cloudflare/skills/skills/turnstile-spin "$TARGET_DIR" >/dev/null 2>&1; then echo "persist-skill: degit failed; cannot fetch cloudflare/skills/skills/turnstile-spin." echo "persist-skill: ensure your network can reach github.com and try again, or install manually." echo "{"status":"error","reason":"degit_failed"}" exit 1 fi if [ ! -f "$TARGET_DIR/SKILL.md" ]; then echo "persist-skill: bundle extracted but SKILL.md is missing at $TARGET_DIR/SKILL.md." echo "{"status":"error","reason":"skill_missing"}" exit 1 fi # Make scripts executable so the agent can invoke them directly. if [ -d "$TARGET_DIR/scripts" ]; then chmod +x "$TARGET_DIR/scripts"/*.sh 2>/dev/null || true fi scripts_list=$(ls "$TARGET_DIR/scripts" 2>/dev/null | sed 's/.*/"&"/' | paste -sd, -) echo "persist-skill: wrote bundle to $TARGET_DIR" >&2 echo "{"status":"ok","path":"$PATH_ARG","bundle_root":"$TARGET_DIR","scripts":[$scripts_list]}" exit 0 ``` -------------------------------- ### Install Wrangler Locally Source: https://developers.cloudflare.com/turnstile/spin If you are in a non-Node.js project (e.g., Hugo, vanilla HTML), install Wrangler as a development dependency locally. ```bash npm init -y npm install --save-dev wrangler ``` -------------------------------- ### Basic Explicit Rendering Example Source: https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/index.md Demonstrates a basic HTML structure with Turnstile's explicit rendering. The widget is rendered when the window loads. ```html Explicit Rendering
``` -------------------------------- ### Basic validation example (JavaScript) Source: https://developers.cloudflare.com/turnstile/get-started/server-side-validation An example of how to call the Siteverify API using JavaScript's fetch API to validate a Turnstile token. ```javascript const SECRET_KEY = "your-secret-key"; async function validateTurnstile(token, remoteip) { try { const response = await fetch( "https://challenges.cloudflare.com/turnstile/v0/siteverify", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ secret: SECRET_KEY, response: token, remoteip: remoteip, }), }, ); const result = await response.json(); return result; } catch (error) { console.error("Turnstile validation error:", error); return { success: false, "error-codes": ["internal-error"] }; } } ``` -------------------------------- ### Install Turnstile Skill for Claude Code Source: https://developers.cloudflare.com/turnstile/spin/index.md Installs the Turnstile skill locally for Claude Code by downloading the index.md file from the Cloudflare Turnstile documentation. ```bash # Claude Code mkdir -p .claude/skills/turnstile-spin && \ curl -sSL https://developers.cloudflare.com/turnstile/spin/index.md \ -o .claude/skills/turnstile-spin/SKILL.md ``` -------------------------------- ### Environment Configuration for Turnstile Keys Source: https://developers.cloudflare.com/turnstile/llms-full.txt Set up different Turnstile sitekeys and secret keys for various environments (development, test, production) using .env files. This example shows the structure for each environment. ```bash # .env.development TURNSTILE_SITEKEY=1x00000000000000000000AA TURNSTILE_SECRET_KEY=1x0000000000000000000000000000000AA # .env.test TURNSTILE_SITEKEY=2x00000000000000000000AB TURNSTILE_SECRET_KEY=2x0000000000000000000000000000000AA # .env.production TURNSTILE_SITEKEY=your-real-sitekey TURNSTILE_SECRET_KEY=your-real-secret-key ``` -------------------------------- ### Validate Turnstile Setup Source: https://developers.cloudflare.com/turnstile/spin Run a series of checks to validate the Turnstile integration, including authentication, widget configuration, and worker deployment. ```bash scripts/validate.sh ``` -------------------------------- ### Client-Side Testing with Invisible Widget Source: https://developers.cloudflare.com/turnstile/troubleshooting/testing/index.md Replace your production sitekey with a test sitekey for invisible widget testing. This example uses the 'Always passes' invisible test sitekey. ```html
``` -------------------------------- ### Complete HTML Example for Contact Form Source: https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/index.md A full HTML document demonstrating Turnstile integration in a contact form. Ensure the Turnstile API script is included in the head. ```html Implicit Rendering with Cloudflare Turnstile

Contact Us






``` -------------------------------- ### Explicit Rendering Setup Source: https://developers.cloudflare.com/turnstile/llms-full.txt Load the Turnstile script with render=explicit and use JavaScript to call turnstile.render() for programmatic widget creation. Configure using a JavaScript object. ```html
``` -------------------------------- ### Turnstile Pages Plugin Usage Example Source: https://developers.cloudflare.com/turnstile/llms-full.txt Example of using the Turnstile Pages Plugin in a Cloudflare Pages Function for request validation. It demonstrates how to configure the plugin with a secret key and process validated requests. ```typescript import turnstilePlugin from "@cloudflare/pages-plugin-turnstile"; /** * POST /api/submit-with-plugin */ export const onRequestPost = [ turnstilePlugin({ // This is the demo secret key. In prod, we recommend you store // your secret key(s) safely. secret: "0x4AAAAAAASh4E5cwHGsTTePnwcPbnFru6Y", }), // Alternatively, this is how you can use a secret key which has been stored as an environment variable // (async (context) => { // return turnstilePlugin({secret: context.env.SECRET_KEY})(context) // }), async (context) => { // Request has been validated as coming from a human const formData = await context.request.formData(); // Additional solve metadata data is available at context.data.turnstile return new Response( `Successfully verified! ${JSON.stringify(context.data.turnstile)}`, ); }, ]; ``` -------------------------------- ### Turnstile Widget with Tracking Parameters Source: https://developers.cloudflare.com/turnstile/additional-configuration/hostname-management/any-hostname Example of embedding a Turnstile widget with 'action' and 'cData' parameters for tracking widget usage sources and deployment locations. ```html
``` -------------------------------- ### Create Turnstile Widget via Cloudflare API Source: https://developers.cloudflare.com/turnstile/llms-full.txt Example using curl to create a Turnstile widget using the Cloudflare API. ```bash curl --request POST --url https://api.cloudflare.com/client/v4/accounts/{id}/challenges/widgets --header "Authorization: Bearer " --header "Content-Type: application/json" --data "{\"name\":\"myproject (Spin)\"}" ``` -------------------------------- ### Next.js Signup Form with Turnstile Callback Source: https://developers.cloudflare.com/turnstile/spin Another Next.js example using `onLoad` for the Turnstile callback. This approach sets the `onTurnstileSuccess` function when the Turnstile script is loaded. ```javascript import Script from "next/script"; import { useState } from "react"; declare global { interface Window { onTurnstileSuccess?: (token: string) => void; } } export default function SignupPage() { const [token, setToken] = useState(""); const [error, setError] = useState(""); async function handleSubmit(e: React.FormEvent) { e.preventDefault(); setError(""); const verify = await fetch("https://YOUR_WORKER_URL/", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ token }), }); const { success } = await verify.json(); if (!success) { setError("Verification failed. Try again."); return; } // On success, run the user's existing submit logic — whatever it was. /* existing submit logic */ } return ( <>