---
title: React Turnstile - Props
---

## Props

These are the props you can pass to the `Turnstile` component.

| **Prop**              | **Type** | **Description**                                                                                                                                                                                                                                                                                                     |
| --------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `siteKey`             | string   | Your sitekey key, get one from [here](https://developers.cloudflare.com/turnstile/get-started/).                                                                                                                                                                                                                    |
| `options`             | object   | Widget render parameters. More info [below](/props#render-options).                                                                                                                                                                                                                                                 |
| `scriptOptions`       | object   | You can customize the injected `script` tag with this prop. It allows you to add `"async"`, `"defer"`, `"nonce"` attributes to the script tag. You can also control whether the injected script will be added to the document body or head with `appendTo` attribute. More info [below](/props#scriptoptions-prop). |
| `onWidgetLoad`        | function | Callback invoked after a successful render of the widget. The callback is passed the widget ID. It does not trigger when the widget is reset.                                                                                                                                                                       |
| `onSuccess`           | function | Callback invoked upon success of the challenge. The callback is passed a token that can be validated.                                                                                                                                                                                                               |
| `onExpire`            | function | Callback invoked when a challenge expires. Read the [Cloudflare docs](https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/#refreshing-a-widget) for more info about handling expired widgets.                                                                                             |
| `onError`             | function | Callback invoked when there is an error (e.g. network error or the challenge failed). Refer to [Client-side errors](https://developers.cloudflare.com/turnstile/reference/client-side-errors). The argument is normally a Cloudflare error code, but it can also be a validation message. More info [below](/props#onerror-argument).                    |
| `onBeforeInteractive` | function | Callback invoked before the challenge enters interactive mode.                                                                                                                                                                                                                                                      |
| `onAfterInteractive`  | function | Callback invoked when challenge has left interactive mode.                                                                                                                                                                                                                                                          |
| `onUnsupported`       | function | Callback invoked when a given client/browser is not supported by Turnstile.                                                                                                                                                                                                                                         |
| `onTimeout`       | function | Callback that is invoked when the Turnstile widget times out.                                                                                                                                                                                                                                         |
| `rerenderOnCallbackChange` | boolean | Controls whether the widget re-renders when callback props change. Default to `false`. When `true`, widget re-renders when callbacks change (useful for dynamic callbacks). **Important:** When set to `true`, wrap callback functions with `useCallback` to prevent unnecessary re-renders. |
| `as`                  | string   | Define the HTML tag of the widget container. Default to `"div"`.                                                                                                                                                                                                                                                    |
| `injectScript`        | boolean  | Controls if the script is automatically injected or not. If you want to inject the script manually, set this property to `false`. Default to `true`.                                                                                                                                                                |
| `onLoadScript`        | function | Callback invoked when the script is loaded.                                                                                                                                                                                                                                                                         |

<Info>
  You can pass any valid HTML prop such as `className`, `id`, or `style`, based on the `as` prop.
</Info>

### `onError` argument

Most failures reach `onError` as a Cloudflare [error code](https://developers.cloudflare.com/turnstile/troubleshooting/client-side-errors/error-codes/): a string of digits such as `"400020"` or `"300010"`.

Invalid render parameters are the exception. Turnstile validates them before creating the widget — an empty `siteKey`, an unknown `theme`, a malformed `action`, and so on — and signals the failure by throwing instead of calling the error callback. The component forwards those failures to `onError` as well, so a misconfigured prop is not silently swallowed, but the argument is then the validation message rather than a code:

```
[Cloudflare Turnstile] Invalid input for parameter "sitekey", got "".
```

These messages are free-form English text produced by `api.js` and can change between its versions, so do not parse or match on them. If you branch on the argument or forward it to error tracking, treat anything that is not a code as an opaque message:

```tsx
<Turnstile
  siteKey="{{ siteKey }}"
  onError={error => {
    if (/^\d+$/.test(error)) {
      handleErrorCode(error) // a Cloudflare error code
    } else {
      reportMisconfiguration(error) // an api.js validation message
    }
  }}
/>
```

When `onError` is not provided, invalid render parameters are logged with `console.error` instead.

### Render Options

| **Option**          | **Type** | **Default**               | **Description**                                                                                                                                                                                                                                                                                                                                       |
| ------------------- | -------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `action`            | string   | `undefined`               | A 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 `-`.                                                                                                                                 |
| `cData`             | string   | `undefined`               | A 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 `-`.                                                                                                                            |
| `theme`             | string   | `"auto"`                  | The widget theme. You can choose between `"light"`, `"dark"` or `"auto"`.                                                                                                                                                                                                                                                                             |
| `language`          | string   | `"auto"`                  | Language 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](https://developers.cloudflare.com/turnstile/reference/supported-languages/) for more information. |
| `tabIndex`          | number   | `0`                       | The `tabindex` of Turnstile’s iframe for accessibility purposes.                                                                                                                                                                                                                                                                                      |
| `responseField`     | boolean  | `true`                    | A boolean that controls if an input element with the response token is created.                                                                                                                                                                                                                                                                       |
| `responseFieldName` | string   | `"cf-turnstile-response"` | Name of the input element.                                                                                                                                                                                                                                                                                                                            |
| `size`              | string   | `"normal"`                | The widget size. Can take the following values: `"normal"`, `"compact"`, `"flexible"`, or `"invisible"`. Normal: 300x65px, compact: 150x140px, flexible: 100% width (min: 300px) x 65px. `"invisible"` will show no widget and is only to be used with invisible type widgets.                                                                       |
| `retry`             | string   | `"auto"`                  | Controls 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.                                                                                                                                  |
| `retryInterval`     | number   | `8000`                    | When `retry` is set to `"auto"`, `retryInterval` controls the time between retry attempts in milliseconds. The value must be a positive integer less than `900000`. When `retry` is set to `"never"`, this parameter has no effect.                                                                                                                   |
| `refreshExpired`    | string   | `"auto"`                  | Automatically refreshes the token when it expires. Can take `"auto"`, `"manual"` or `"never"`. Read the [Cloudflare docs](https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/#refreshing-a-widget) for more info about handling expired widgets.                                                                           |
| `refreshTimeout`    | string   | `"auto"`                  | The refresh mode to use when the widget times out. The default is `"auto"`. `"never"` will never refresh the widget, `"manual"` will prompt the user with a refresh button.                                                                                                                                                                           |
| `execution`         | string   | `"render"`                | Execution controls when to obtain the token of the widget and can be on `render` or on `execute`. With `"execute"`, the widget container occupies no space until you call the `execute()` ref method; after that it becomes visible according to `size` and `appearance`. Read the [Cloudflare docs](https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/#execution-modes) for more info.                                                                                                           |
| `appearance`        | string   | `"always"`                | Appearance controls when the widget is visible. It can be `"always"`, `"execute"`, or `"interaction-only"`. Read the [Cloudflare docs](https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/#appearance-modes) for more info.                                                                                                |
| `offlabelShowPrivacy` | boolean | `true`                   | Controls whether an unbranded (Offlabel, Enterprise only) widget displays the privacy link. Read the [Cloudflare docs](https://developers.cloudflare.com/turnstile/additional-configuration/offlabel/) for more info.                                                                                                                                 |
| `offlabelShowHelp`  | boolean  | `true`                    | Controls whether an unbranded (Offlabel, Enterprise only) widget displays the help link. Read the [Cloudflare docs](https://developers.cloudflare.com/turnstile/additional-configuration/offlabel/) for more info.                                                                                                                                    |

<Info>
  Read the [Cloudflare docs](https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/#configurations) to get more info about this options.
</Info>

### `scriptOptions` prop

| **Option**           | **Type** | **Default**                 | **Description**                                                                                                       |
| -------------------- | -------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `id`                 | string   | `"cf-turnstile-script"`     | Custom ID of the injected script.                                                                                     |
| `nonce`              | string   | `undefined`                 | Custom nonce for the injected script. This option has no effect if `injectScript` is set to false.                    |
| `defer`              | boolean  | `true`                      | Define if set the injected script as defer.  This option has no effect if `injectScript` is set to false.             |
| `async`              | boolean  | `true`                      | Define if set the injected script as async.  This option has no effect if `injectScript` is set to false.             |
| `appendTo`           | string   | `"head"`                    | Define if inject the script in the head or in the body.  This option has no effect if `injectScript` is set to false. |
| `onLoadCallbackName` | string   | `"onloadTurnstileCallback"` | Custom name of the onload callback.  This option has no effect if `injectScript` is set to false.                     |
| `onError`            | function | `undefined`                 | Callback invoked when script fails to load (e.g. Cloudflare has an outage).                                           |
| `crossOrigin`        | string   | `undefined`                 | Custom crossOrigin for the injected script.                                                                           |

#### Performance tip: preconnect to Cloudflare

Cloudflare [recommends](https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/) adding a `preconnect` resource hint so the browser establishes an early connection to the Turnstile servers, speeding up the widget load:

```html
<link rel="preconnect" href="https://challenges.cloudflare.com" />
```

Place it in your document `<head>`, ideally server-rendered. For example, in a Next.js (App Router) root layout:

```tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <head>
        <link rel="preconnect" href="https://challenges.cloudflare.com" />
      </head>
      <body>{children}</body>
    </html>
  )
}
```

<Info>
  The library does not inject this hint for you: the `<Turnstile />` component injects the Turnstile script when it mounts, and a preconnect emitted from JavaScript at that same moment would provide little to no benefit. The hint is only effective when it is present in the HTML before the script loads, which only your app can guarantee.
</Info>
