Your React Native app
Render ReactNativeTurnstile and listen for verify, expire, error, and timeout events.
A wrapper for Cloudflare Turnstile that loads a tiny hosted Next.js app and bridges the widget into react-native-webview.
npm i react-native-turnstile react-native-webviewHow it works
The cookies used by Cloudflare Turnstile are incompatible with react-native-webview. This package circumvents that by loading a tiny Next.js app on Cloudflare that creates an interface between a WebView and the Turnstile widget.
Render ReactNativeTurnstile and listen for verify, expire, error, and timeout events.
The package loads this hosted site inside a WebView and posts Turnstile events back to native.
The challenge runs in a real browser context, then your app receives the token through onVerify.
Add the hosted domain to your Turnstile widget
You must add turnstile.1337707.xyz to your Turnstile domains list. This is the hosted instance on Cloudflare.
Installation
Install react-native-turnstile plus react-native-webview. Expo projects should install the WebView package through Expo first.
npm i react-native-turnstile react-native-webviewexpo install react-native-webview
npm i react-native-turnstileUsage
Pass your sitekey, handle onVerify, and optionally keep a reset ref for failed requests or expired tokens.
import { useRef } from "react";
import ReactNativeTurnstile, { resetTurnstile } from "react-native-turnstile";
const turnstileResetRef = useRef();
const result = await fetch("/path/to/some/api");
if (!result.ok) {
resetTurnstile(turnstileResetRef);
throw new Error(`Request failed with code ${result.status}`);
}
function TurnstileWidget() {
return (
<ReactNativeTurnstile
sitekey="xxxxxxxxxxxxxxxxxxx"
onVerify={token => console.log(token)}
resetRef={turnstileResetRef}
style={{ marginLeft: "auto", marginRight: "auto" }}
/>
);
}Turnstile tokens expire after 5 minutes. To automatically reset the challenge once they expire, set the autoResetOnExpire prop to true or reset the widget yourself using the onExpire callback.
Documentation
These props map to the Turnstile widget configuration, except backgroundColor, which sets the hosted page background inside the WebView. For more details on what each argument does, see the Cloudflare documentation.
| Name | Type | Description |
|---|---|---|
| sitekeyrequired | string | Sitekey of your Turnstile widget. |
| action | string | Optional action name passed to Turnstile. |
| cData | string | Optional custom payload passed to Turnstile. |
| theme | string | One of "light", "dark", or "auto". |
| size | string | One of "compact" or "normal". |
| tabIndex | number | Tab index for the widget. |
| responseField | boolean | Controls generation of the hidden input element. |
| responseFieldName | string | Changes the name of the hidden input element. |
| retry | string | One of "auto" or "never". |
| retryInterval | number | Interval of retries in milliseconds. |
| autoResetOnExpire | boolean | Automatically reset the widget when the token expires. |
| id | string | ID of the widget container. |
| backgroundColor | string | Background color of the hosted Turnstile page. Any CSS color value (default `#ffffff`). |
| resetRef | TurnstileResetRef | Ref used to inject a programmatic reset() call. |
| className | string | Provided to facilitate NativeWind classes. |
| style | StyleProp<ViewStyle> | Passed to the React Native View container. |
| Name | Arguments | Description |
|---|---|---|
| onVerifyrequired | token | Called when the challenge is passed. |
| onLoad | widgetId | Called when the widget is loaded. |
| onError | error | Called when an error occurs. |
| onExpire | token | Called when the token expires. |
| onTimeout | — | Called when the challenge expires. |