@svelte-put/cloudflare-turnstile
Introduction
This implementation of Cloudflare Turnstile utilizes Svelte action. If you are looking for a component-oriented solution, check out ghostdevv/svelte-turnstile instead.
Installation
npm install --save-dev @svelte-put/cloudflare-turnstile@^0.1.3
pnpm add -D @svelte-put/cloudflare-turnstile@^0.1.3
yarn add -D @svelte-put/cloudflare-turnstile@^0.1.3
Quick Start
<script lang="ts">
import { turnstile } from '@svelte-put/cloudflare-turnstile';
import { PUBLIC_CLOUDFLARE_TURNSTILE_SITE_KEY } from '$env/static/public';
let token: string;
$: console.log(`Token:`, token);
</script>
<div
use:turnstile
turnstile-sitekey={PUBLIC_CLOUDFLARE_TURNSTILE_SITE_KEY}
turnstile-theme="auto"
turnstile-size="normal"
turnstile-language="en"
turnstile-response-field-name="turnstile"
turnstile-response-field
on:turnstile={(e) => (token = e.detail.token)}
/>
<p class="text-center">
Captured Token: <span class="bg-success-surface text-success-text px-2">{token ?? 'pending'}</span>
</p>
PUBLIC_CLOUDFLARE_TURNSTILE_SITE_KEY="1x00000000000000000000AA"
Configuration Attributes
As seen in Quick Start, @svelte-put/cloudflare-turnstile
can be customized by adding turnstile-*
attributes, where *
are properties as described in Cloudflare Turnstile’s client configuration documentation, except for *-callback
properties, which can be specified via Svelte event handler syntax on:turnstile:*
(more in Events).
If you have Typescript language server set up correctly, you should get autocomplete / intellisense for these turnstile-*
attributes.
The turnstile-sitekey
is the only mandatory property. In Quick Start, it is set via environment variable PUBLIC_CLOUDFLARE_TURNSTILE_SITE_KEY
, assuming usage with SvelteKit. See more in SvelteKit’s docs on static public env.
<div
use:turnstile
turnstile-sitekey="1x00000000000000000000AA"
turnstile-theme="auto"
turnstile-size="normal"
turnstile-language="en"
turnstile-response-field-name="turnstile"
turnstile-response-field
turnstile-action="customer-feedback"
turnstile-cData="customer-id-123"
turnstile-execution="render"
turnstile-tabindex="0"
turnstile-retry="auto"
turnstile-retry-interval="8000"
turnstile-refresh-expired="auto"
turnstile-appearance="always"
/>
Additionally, you may provide the turnstile-script-src
attribute, which specifies the URL to load Turnstile script from. The default URL is shown in below code snippet.
<div
use:turnstile
turnstile-sitekey="1x00000000000000000000AA"
turnstile-script-src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit"
/>
Finally, there are two readonly
attributes that will be dynamically added by the turnstile
at runtime: turnstile-widget-id
is one returned from Cloudflare Turnstile API, and turnstile-rendered
is added if the widget is successfully rendered.
<div [...truncated...] turnstile-widget-id="..." turnstile-rendered></div>
Events
As seen Quick Start, turnstile
is a CustomEvent invoked upon success of the challenge. The event detail contains a token that should be sent to backend for validation. other turnstile:*
CustomEvents are mapped directly to those found in Cloudflare Turnstile’s documentation.
type TurnstileEventDetail<T extends Record<string, any> = Record<string, never>> = {
widgetId: string;
turnstile: Turnstile;
} & T;
type TurnstileEventAttributes = {
'on:turnstile'?: (event: CustomEvent<TurnstileEventDetail<{ token: string }>>) => void;
'on:turnstile:error'?: (event: CustomEvent<TurnstileEventDetail<{ code: string }>>) => void;
'on:turnstile:expired'?: (event: CustomEvent<TurnstileEventDetail>) => void;
'on:turnstile:before-interactive'?: (event: CustomEvent<TurnstileEventDetail>) => void;
'on:turnstile:after-interactive'?: (event: CustomEvent<TurnstileEventDetail>) => void;
'on:turnstile:unsupported'?: (event: CustomEvent<TurnstileEventDetail>) => void;
'on:turnstile:timeout'?: (event: CustomEvent<TurnstileEventDetail>) => void;
};
Notice the event detail provides access to widgetId
and the turnstile
object, which is helpful if you need to execute custom JS such as reset the widget or check if it is expired.
<script lang="ts">
import { turnstile } from '@svelte-put/cloudflare-turnstile';
import type { TurnstileEventAttributes } from '@svelte-put/cloudflare-turnstile';
const handleTurnstile: TurnstileEventAttributes['on:turnstile'] = (e) => {
const { token, turnstile, widgetId } = e.detail;
// ...
};
</script>
<div use:turnstile turnstile-sitekey="1x00000000000000000000AA" on:turnstile={handleTurnstile}>
The turnstile
object has the following interface:
type Turnstile = {
render: (element: string | HTMLElement, config: TurnstileConfig) => string;
reset: (widgetId: string) => void;
remove: (widgetId: string) => void;
getResponse: (widgetId: string) => string | undefined;
isExpired: (widgetId: string) => boolean;
execute: (container: string | HTMLElement, config?: TurnstileConfig) => void;
};
Backend Integration (with SvelteKit)
Coming soon...
Happy turning in style! 👨💻