You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
For other agents, see the table in [`SKILL.md`](./SKILL.md#step-8--persist-the-skill).
40
+
For other agents, see the table in [`SKILL.md`](./SKILL.md#step-11--persist-the-skill).
36
41
37
42
## Sync with the docs page
38
43
39
-
The canonical source of truth is `src/content/docs/turnstile/spin/index.mdx` in the `cloudflare-docs` repo. This skill mirrors that content with the JSX stripped out. CI keeps them in sync on each docs release; if you are hand-editing, mirror your change to both places.
44
+
The canonical source of truth is `src/content/docs/turnstile/spin.mdx` in the `cloudflare-docs` repo. This skill mirrors that content with the JSX stripped out. CI keeps them in sync on each docs release; if you are hand-editing, mirror your change to both places.
For Astro projects. The form posts directly to the Worker. Astro frontmatter handles config substitution at build time.
3
+
For Astro projects. The widget renders in a page; siteverify lives in an Astro Action, an API route, or a Pages Function. Astro frontmatter reads the sitekey from env at build time; the secret stays server-only.
Copy file name to clipboardExpand all lines: skills/turnstile-spin/references/hugo.md
+41-8Lines changed: 41 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# Hugo
2
2
3
-
For Hugo static sites. Use a partial for the widget so it can be referenced from any layout or content file.
3
+
For Hugo static sites. The widget renders on any page that includes the partial; siteverify happens at whatever backend handles your form submissions (a Cloudflare Pages Function, a Worker, an external API, or a form host with a server-side hook).
4
4
5
5
```html title="layouts/partials/turnstile.html"
6
6
<script
@@ -9,12 +9,12 @@ For Hugo static sites. Use a partial for the widget so it can be referenced from
if (!success) returnnewResponse("forbidden", { status:403 });
59
+
60
+
// process subscribe
61
+
returnnewResponse("ok");
62
+
}
63
+
```
64
+
65
+
Set the secret with `npx wrangler pages secret put TURNSTILE_SECRET` (or via the dashboard's Pages → your project → Settings → Environment variables → Add secret).
66
+
67
+
**External backend**: any Node/Ruby/Python/Go handler can do the same call. See the [vanilla-html reference](./vanilla-html.md) for non-Cloudflare-specific snippets.
68
+
37
69
## Variant: shortcode for content files
38
70
39
71
If you want to drop the widget into Markdown content (not just layouts), create a shortcode:
Copy file name to clipboardExpand all lines: skills/turnstile-spin/references/nextjs-app.md
+45-17Lines changed: 45 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# Next.js (App Router)
2
2
3
-
For `app/`-directory Next.js projects. The widget needs to run on the client, so the page or component must be `"use client"`.
3
+
For `app/`-directory Next.js projects. The widget needs to run on the client, so the page or component must be `"use client"`. The siteverify call lives server-side, either in a Server Action or an API route.
4
4
5
5
```tsx title="app/signup/page.tsx"
6
6
"use client";
@@ -22,13 +22,13 @@ export default function SignupPage() {
const res =awaitfetch("https://YOUR_WORKER_URL/", {
25
+
const res =awaitfetch("/api/signup", {
26
26
method: "POST",
27
27
headers: { "Content-Type": "application/json" },
28
28
body: JSON.stringify({ token }),
29
29
});
30
30
const data =awaitres.json();
31
-
if (data.success) {
31
+
if (data.ok) {
32
32
// proceed
33
33
}
34
34
}
@@ -44,7 +44,7 @@ export default function SignupPage() {
44
44
<div
45
45
className="cf-turnstile"
46
46
data-sitekey="YOUR_SITEKEY"
47
-
data-action="turnstile-spin-v1"
47
+
data-action="turnstile-spin-v2"
48
48
data-callback="onTurnstileSuccess"
49
49
/>
50
50
<buttontype="submit"disabled={!token}>
@@ -58,32 +58,60 @@ export default function SignupPage() {
58
58
59
59
`data-callback` expects a string referencing a global function. The `useEffect` wires `window.onTurnstileSuccess` so the widget can call back into React state.
if (!success) returnnewResponse("forbidden", { status: 403 });
79
+
80
+
// existing signup logic runs here
81
+
returnResponse.json({ ok: true });
82
+
}
83
+
```
84
+
61
85
## Variant: Server Action
62
86
63
87
If you are using Server Actions, do the siteverify call from the action itself. The widget still goes in a client component, but the verify call moves server-side:
0 commit comments