Skip to content
Cloudflare Docs

Widget configurations

Configure your Turnstile widget's appearance, behavior, and functionality using data attributes or JavaScript render parameters.

Rendering methods

Turnstile widgets can be implemented using implicit or explicit rendering.

Implicit rendering automatically scans your HTML for elements with the cf-turnstile class and renders the widget when the page loads. It is best used for simple implementations, static websites, or when you want widgets to appear immediately on page load.

How it works

  1. Add the Turnstile script to your page.
  2. Include <div class="cf-turnstile" data-sitekey="your-key"></div> elements.
  3. Widgets will render automatically when the page loads.
  4. Configure the widget using data-* attributes on the HTML element.
Example
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>" data-theme="light"></div>

Widget sizes

The Turnstile widget can have two different fixed sizes or a flexible width size when using the Managed or Non-Interactive modes.

SizeWidthHeightUse case
Normal300px65pxStandard implementation
Flexible100% (min: 300px)65pxResponsive design
Compact150px140pxSpace-constrained layouts
  • normal: The default size works well for most desktop and mobile layouts. Use this if you have adequate horizontal space on your website or form.
  • flexible: Automatically adapts to the container width while maintaining minimum usability. Use this for responsive designs that need to work across all screen sizes.
  • compact: Ideal for mobile interfaces, sidebars, or any space where horizontal space is limited. The compact widget is taller than normal to accommodate the smaller width.
Normal size (default)
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>"></div>
Flexible size
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>" data-size="flexible"></div>
Compact size
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>" data-size="compact"></div>

Theme options

Customize the widget's visual appearance to match your website's design.

  • auto (default): Automatically matches the visitor's system theme preference. Auto is recommended for most implementations as it respects the visitor's preferences and provides the best accessibility experience.
  • light: Light theme with bright colors and clear contrast. Light theme works best on bright backgrounds and provides high contrast for readability.
  • dark: Dark theme optimized for dark interfaces. Dark theme is ideal for dark interfaces, gaming sites, or applications with dark color schemes.
Auto theme (default)
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>"></div>
Light theme
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>" data-theme="light"></div>
Dark theme
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>" data-theme="dark"></div>

Appearance modes

Control when the widget becomes visible to visitors using the appearance mode.

  • always (default): The widget is always visible from page load. This is the best option for most implementations where you want your visitors to see the widget immediately as it provides clear visual feedback that security verification is in place.
  • execute: The widget only becomes visible after the challenge begins. This is useful for when you need to control the timing of widget appearance, such as showing it only when a visitor starts filling out a form or selecting a submit button.
  • interaction-only: The widget becomes visible only when visitor interaction is required and provides the cleanest visitor experience. Most visitors will never see the widget, but suspected bots will encounter the interactive challenge.
Always visible (default)
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>"></div>
Visible only after challenge begins
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>" data-appearance="execute"></div>
Visible only when interaction is needed
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>" data-appearance="interaction-only"></div>

Execution modes

Control when the challenge runs and a token is generated.

  • render (default): The challenge runs automatically after calling the render() function and provides immediate protection as soon as the widget loads. The challenge runs in the background while the page loads, ensuring the token is ready when the visitor submits data.

  • execute: The challenge runs after calling the turnstile.execute() function separately and gives you precise control over when verification occurs. This option is useful for multi-step forms, conditional verification, or when you want to defer the challenge until the visitor actually attempts to submit data. This can improve page load performance and visitor experience by only running verification when needed.

    Common scenarios

    • Multi-step forms: Run verification only on the final step.
    • Conditional protection: Only verify visitors who meet certain criteria.
    • Performance optimization: Defer verification to reduce initial page load time.
    • User-triggered verification: Let visitors manually start the verification process.
Auto execution (default)
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>"></div>
Manual execution
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>" data-execution="execute"></div>

Language configuration

Set the language for the widget interface.

  • auto (default): Uses the visitor's browser language preference.
  • Specific language codes: ISO 639-1 two-letter codes, such as es, fr, de.
  • Language and region: Combined codes for regional variants, such as en-US, es-MX, pt-BR.
Auto language (default)
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>"></div>
Specific language
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>" data-language="es"></div>
Language and country
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>" data-language="en-US"></div>

Callback configuration

Handle widget events with callbacks.

  • callback: Triggered when the challenge is successfully completed.
  • error-callback: Triggered when an error occurs during the challenge.
  • expired-callback: Triggered when a token expires (before timeout).
  • timeout-callback: Triggered when an interactive challenge times out.

The success callback receives a token that must be validated on your server using the Siteverify API. Tokens are single-use and expire after 300 seconds (five minutes).

<div class="cf-turnstile"
data-sitekey="<YOUR-SITE-KEY>"
data-callback="onSuccess"
data-error-callback="onError"
data-expired-callback="onExpired"
data-timeout-callback="onTimeout"></div>
<script>
function onSuccess(token) {
console.log('Challenge Success:', token);
}
function onError(errorCode) {
console.log('Challenge Error:', errorCode);
}
function onExpired() {
console.log('Token expired');
}
function onTimeout() {
console.log('Challenge timed out');
}
</script>

Best practices

  • Always implement the success callback to handle the token and proceed with form submission or next steps.
  • Use error callbacks for graceful error handling and visitor feedback.
  • Monitor expired tokens to refresh challenges before they become invalid.
  • Handle timeouts to guide visitors through challenge resolution.

Advanced configuration options

Retry behavior

Control how Turnstile handles failed challenges.

  • auto (default): Automatically retries failed challenges. Auto retry provides better visitor experience by automatically recovering from temporary network issues or processing errors.
  • never: Disables automatic retry. This requires manual intervention and gives you full control over error handling in applications that need custom retry logic.
  • retry-interval: Controls the time between retry attempts (default: 8000ms) and lets you balance between quick recovery and server load.
Auto retry (default)
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>"></div>
Disable retry
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>" data-retry="never"></div>
Custom retry interval (8000ms default)
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>" data-retry-interval="0000"></div>

Refresh behavior

Control how Turnstile handles token expiration and interactive timeouts.

  • refresh-expired: Controls behavior when tokens expire (auto, manual, never).
  • refresh-timeout: Controls behavior when interactive challenges timeout (auto, manual, never).

Benefits

  • auto refresh provides seamless visitor experience but uses more resources.
  • manual refresh gives visitors control but requires them to take action.
  • never refresh requires your application to handle all refresh logic.

Different strategies can be used for token expiration versus interactive timeouts based on your visitor experience requirements.

Auto refresh expired tokens (default)
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>"></div>
Manual refresh
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>" data-refresh-expired="manual"></div>
Auto refresh timeouts (default for Managed mode)
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>" data-refresh-timeout="auto"></div>

Custom data

Add custom identifiers and data to your challenges.

  • action: A custom identifier for analytics and differentiation (maximum 32 characters).
  • cData: Custom payload data returned during validation (maximum 255 characters).

Use cases

  • Action tracking: Differentiate between login, signup, contact forms, and more. in your analytics.
  • Visitor context: Pass visitor IDs, session information, or other contextual data.
  • A/B testing: Track different widget configurations or page variants.
  • Fraud detection: Include additional context for risk assessment.
Add custom action identifier
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>" data-action="login"></div>
Add custom data payload
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>" data-cdata="user-cdata"></div>

Form integration

Configure how Turnstile integrates with HTML forms.

When enabled, Turnstile automatically creates a hidden <input> element with the verification token. This gets submitted along with your other form data, making server-side validation straightforward.

  • response-field: Determines whether to create a hidden form field with the token (default: true)
  • response-field-name: Custom name for the hidden form field (default: cf-turnstile-response)

Benefits

  • Automatic form integration means that the token is included when the form is submitted, requiring no additional JavaScript.
  • Custom field names helps avoid conflicts with existing form fields.
  • Disabled response fields give you full control over token handling for complex form scenarios.
Custom response field name
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>" data-response-field-name="turnstile-token"></div>
Disable response field
<div class="cf-turnstile" data-sitekey="<YOUR-SITE-KEY>" data-response-field="false"></div>

Complete configuration reference

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 invoked upon success of the challenge. The callback is passed a token that can be validated.
error-callbackdata-error-callbackA JavaScript callback invoked when there is an error (e.g. network error or the challenge failed). Refer to Client-side errors.
executiondata-executionExecution controls when to obtain the token of the widget and can be on render (default) or on execute. Refer to Execution Modes for more information.
expired-callbackdata-expired-callbackA JavaScript callback invoked when the token expires and does not reset the widget.
before-interactive-callbackdata-before-interactive-callbackA JavaScript callback invoked before the challenge enters interactive mode.
after-interactive-callbackdata-after-interactive-callbackA JavaScript callback invoked when challenge has left interactive mode.
unsupported-callbackdata-unsupported-callbackA JavaScript callback invoked when a given client/browser is not supported by Turnstile.
themedata-themeThe widget theme. Can take the following values: light, dark, auto.

The default is auto, which respects the visitor preference. This can be forced to light or dark by setting the theme accordingly.
languagedata-languageLanguage to display, must be either: auto (default) to use the language that the visitor has chosen, or an ISO 639-1 two-letter language code (e.g. en) or language and country code (e.g. en-US). Refer to the list of supported languages for more information.
tabindexdata-tabindexThe tabindex of Turnstile's iframe for accessibility purposes. The default value is 0.
timeout-callbackdata-timeout-callbackA JavaScript callback invoked when the challenge presents an interactive challenge but was not solved within a given time. A callback will reset the widget to allow a visitor to solve the challenge again.
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.
sizedata-sizeThe widget size. Can take the following values: normal, flexible, 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 on 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.
refresh-expired data-refresh-expiredAutomatically refreshes the token when it expires. Can take auto, manual, or never, defaults to auto.
refresh-timeoutdata-refresh-timeoutControls whether the widget should automatically refresh upon entering an interactive challenge and observing a timeout. Can take auto (automatically refreshes upon encountering an interactive timeout), manual (prompts the visitor to manually refresh) or never (will show a timeout), defaults to auto. Only applies to widgets of Managed mode.
appearancedata-appearanceAppearance controls when the widget is visible. It can be always (default), execute, or interaction-only. Refer to Appearance modes for more information.
feedback-enableddata-feedback-enabledAllows Cloudflare to gather visitor feedback upon widget failure. It can be true (default) or false.

Examples

Responsive design widget
<div style="max-width: 500px;">
<div class="cf-turnstile" data-sitekey=<YOUR-SITE-KEY> data-size="flexible" data-theme="auto"></div>
</div>
Mobile-optimized compact widget
<div class="cf-turnstile" data-sitekey=<YOUR-SITE-KEY> data-size="compact" data-theme="light" data-language="en">
</div>