Explainers

Cloudflare Turnstile Widget Customization: Themes and Render Modes

Cloudflare Turnstile gives site owners control over how the verification widget looks and behaves. Sites choose between visible and invisible modes, light and dark themes, and explicit or implicit rendering. These choices change the user experience but not the solving process — CaptchaAI handles all Turnstile configurations with a 100% success rate.

Widget Modes

Turnstile offers three operational modes:

Managed Mode

The default mode. Cloudflare decides whether to show a visible challenge:

<div class="cf-turnstile" data-sitekey="0x4AAAA..." data-theme="light"></div>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
  • Shows a small widget (similar in size to reCAPTCHA checkbox)
  • May auto-complete without user interaction if risk is low
  • May show a brief challenge animation if risk is moderate
  • User never sees image grids or complex puzzles

Non-Interactive Mode

Runs entirely in the background with no user interaction:

<div class="cf-turnstile" data-sitekey="0x4AAAA..." data-appearance="interaction-only"></div>
  • No visible widget unless interaction is needed
  • Cloudflare's challenge runs silently via JavaScript
  • If the silent check passes, the token is generated automatically
  • Falls back to an interactive widget only if the silent check fails

Invisible Mode

Completely hidden. Triggered programmatically:

turnstile.execute('0x4AAAA...', {
  action: 'login',
  cData: 'custom-data'
});
  • No visible element on the page
  • Site calls turnstile.execute() at the appropriate moment
  • Token is generated and passed via callback
  • User never sees any widget

Visual Themes

Theme Appearance HTML attribute
Light White background, dark text data-theme="light"
Dark Dark background, light text data-theme="dark"
Auto Matches user's system preference data-theme="auto"

Themes affect only the visual appearance. CaptchaAI solving is not impacted by theme selection.

Widget Sizes

Size Dimensions HTML attribute
Normal 300×65 px data-size="normal"
Flexible Adapts to container width data-size="flexible"
Compact 150×140 px data-size="compact"

Render Modes

Sites choose how the Turnstile script initializes:

Implicit Rendering

The script auto-renders widgets found in the DOM:

<div class="cf-turnstile" data-sitekey="0x4AAAA..."></div>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>

The script scans for elements with class cf-turnstile and renders widgets automatically.

Explicit Rendering

The script loads but doesn't render until called:

<script src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit" async defer></script>
<script>
  turnstile.render('#captcha-container', {
    sitekey: '0x4AAAA...',
    callback: function(token) {
      document.getElementById('cf-token').value = token;
    }
  });
</script>

Explicit rendering is common in SPAs where the widget container doesn't exist in the initial HTML.

Configuration Attributes

Full list of data-* attributes supported on the widget div:

Attribute Values Default Purpose
data-sitekey Site key string Required Identifies the Turnstile configuration
data-theme light, dark, auto auto Visual theme
data-size normal, flexible, compact normal Widget dimensions
data-language ISO code (e.g., en, ja) Auto-detected Widget text language
data-callback Function name Called with token on success
data-error-callback Function name Called on error
data-expired-callback Function name Called when token expires
data-action Action label Identifies the page action
data-cdata Custom data string Passed through to verification
data-appearance always, execute, interaction-only always When to show the widget
data-retry auto, never auto Whether to auto-retry on failure
data-retry-interval Milliseconds 8000 Delay between auto-retries
data-tabindex Number 0 Tab order for accessibility

How Each Mode Affects Solving

CaptchaAI solves all Turnstile modes identically. You submit the same parameters:

Parameter Value
key Your CaptchaAI API key
method turnstile
sitekey The Turnstile site key (0x4AAAA...)
pageurl The page URL

Extracting the Site Key

Regardless of render mode, the site key appears in one of these locations:

# Implicit: data-sitekey attribute
site_key = page.eval_on_selector(
    ".cf-turnstile", "el => el.dataset.sitekey"
)

# Explicit: in the turnstile.render() call
# Search page source for sitekey
import re
source = page.content()
match = re.search(r"sitekey['\"]?\s*[:=]\s*['\"]?(0x[A-Za-z0-9]+)", source)
site_key = match.group(1) if match else None

Token Handling by Mode

Mode Token delivery How to capture
Managed Hidden input cf-turnstile-response Read from form field
Non-Interactive Same hidden input Read from form field
Invisible Callback function Intercept callback or read injected field
Explicit Callback function parameter Intercept callback

When using CaptchaAI, you inject the token into the appropriate location:

# For managed/non-interactive: set the hidden input
page.evaluate(f"""
    document.querySelector('[name="cf-turnstile-response"]').value = '{token}';
""")

# For explicit with callback: trigger the callback
page.evaluate(f"window.turnstileCallback('{token}')")

Troubleshooting

Issue Cause Fix
Can't find site key Explicit rendering, key in JS bundle Search page source and scripts for 0x4 prefix
Widget not rendering SPA — container doesn't exist yet Wait for the container element before extracting
Token field name differs Site uses custom field name Inspect the form to find the correct field
Auto-retry conflicts data-retry="auto" refreshes widget Inject token before the widget auto-retries

FAQ

Does the Turnstile theme affect solving difficulty?

No. Theme is purely visual. CaptchaAI's solving process is independent of the widget's appearance.

Is invisible Turnstile harder to solve than managed?

No. CaptchaAI solves all modes with the same parameters and the same 100% success rate. The mode only affects how the widget appears to users.

How do I handle explicit rendering in automation?

Wait for the turnstile.render() call to execute (watch for the widget iframe to appear), extract the site key from the render call or the resulting widget element, then proceed normally.

Next Steps

Solve any Turnstile widget configuration — get your CaptchaAI API key for 100% Turnstile success rate.

Discussions (0)

No comments yet.