Cloudflare Docs
Visit Turnstile on GitHub
Set theme to dark (⇧+D)

Client-side render

You can initialize and customize the Turnstile widget on your web page via implicit or explicit rendering.

​​ Implicitly render the Turnstile widget

The HTML is scanned for elements that have a cf-turnstile class name:

<div class="cf-turnstile" data-sitekey="yourSitekey" data-callback="javascriptCallback"></div>

Once a challenge has been solved, a token is passed to the success callback. This token must be validated against our siteverify endpoint. A token can only be validated once and cannot be consumed twice.

To configure the challenge, refer to Configurations containing data attributes and render parameters.

Check out the demo and its source code.

​​ Protect forms

Turnstile is often used to protect forms on websites such as login forms, contact forms, and more. After inserting the JavaScript script tag, customers can embed <div class="cf-turnstile"></div> into their site to protect their forms.

For example:

<form action="/login" method="POST">
<input type="text" placeholder="username"/>
<input type="password" placeholder="password"/>
<div class="cf-turnstile" data-sitekey="<YOUR_SITE_KEY>"></div>
<button type="submit" value="Submit">Log in</button>

An invisible input with the name cf-turnstile-response is added and will be sent to the server with the other fields.

​​ Disable implicit rendering

You can disable implicit rendering by replacing the script from:


When using this option, HTML elements with the cf-turnstile class will not show a challenge. The turnstile.render function must be invoked using the following steps.

​​ Explicitly render the Turnstile widget

  1. Insert the JavaScript tag:
<script src="" async defer></script>
  1. Once the script is embedded, you will have access to a global function with multiple callback options you can customize. For the following function to work properly, the page must contain an HTML element with ID example-container.
    The challenge can be invoked explicitly with the following JavaScript snippet:
window.onloadTurnstileCallback = function () {
turnstile.render('#example-container', {
sitekey: '<YOUR_SITE_KEY>',
callback: function(token) {
console.log(`Challenge Success ${token}`);

Turnstile can be programmatically loaded by invoking the turnstile.render() function in the global window object.

The turnstile.render: function (container: string | HTMLElement, params: RenderParameters) render takes an argument to a HTML widget.

If the invocation is successful, the function returns a widgetId (string). If the invocation is unsuccessful, the function returns undefined.

Check out the demo and its source code.

​​ Access a widget’s state

In addition to the render() function, Turnstile supports obtaining the widget’s response from a widgetId via the turnstile.getResponse(widgetId: string) function.

​​ Reset a widget

If a given widget has timed out, expired or needs to be reloaded, you can use the turnstile.reset(widgetId: string) function to reset the widget.

​​ Remove a widget

Once a widget is no longer needed, it can be removed from the page using turnstile.remove(widgetId: string). This will not call any callback and will remove all related DOM elements.

​​ Configurations

JavaScript Render ParametersData AttributeDescription
sitekeydata-sitekeyEvery widget has a sitekey. This sitekey is associated with the corresponding widget configuration and is created upon the widget creation.
actiondata-actionA customer value that can be used to differentiate widgets under the same sitekey in analytics and which is returned upon validation. This can only contain up to 32 alphanumeric characters including _ and -.
cDatadata-cdataA customer payload that can be used to attach customer data to the challenge throughout its issuance and which is returned upon validation. This can only contain up to 255 alphanumeric characters including _ and -.
callbackdata-callbackA JavaScript callback that is invoked upon success of the challenge. The callback is passed a token that can be validated.
expired-callbackdata-expired-callbackA JavaScript callback that is invoked when the token expires and does not reset the widget.
timeout-callbackdata-timeout-callbackA JavaScript callback that is invoked when the challenge expires and resets the widget.
error-callbackdata-error-callbackA JavaScript callback that is invoked when there is a network error.
themedata-themeThe widget theme. Can take the following values: light, dark, auto.

The default is auto, which respects the user preference. This can be forced to light or dark by setting the theme accordingly.
tabindexdata-tabindexThe tabindex of Turnstile’s iframe for accessibility purposes. The default value is 0.
response-fielddata-response-fieldA boolean that controls if an input element with the response token is created, defaults to true.
response-field-namedata-response-field-nameName of the input element, defaults to cf-turnstile-response.
size data-sizeThe widget size. Can take the following values: normal, compact.
retry data-retryControls whether the widget should automatically retry to obtain a token if it did not succeed. The default is auto, which will retry automatically. This can be set to never to disable retry upon failure.
retry-interval data-retry-intervalWhen retry is set to auto, retry-interval controls the time between retry attempts in milliseconds. Value must be a positive integer less than 900000, defaults to 8000.

​​ Widget size

The Turnstile widget can have two different sizes when using the Managed or Non-interactive modes: