v1

Installation

Use the npm package manager to install react-native-datadome in your React Native project repository.

The React Native Fetch package uses the following dependency:

To install all dependencies, run:

npm install --save @datadome/react-native-datadome react-native-webview

iOS

For iOS, navigate to the ios folder and install pods.

cd ios/ && pod install

Setup

Import the package

The DataDomeFetch function is a replacement for the built-in fetch API and includes an interceptor to handle DataDome responses.

import { DataDome, DataDomeModal, DataDomeFetch } from '@datadome/react-native-datadome';

const fetch = DataDomeFetch;

Set client-side key

In order to identify the traffic, please get your Client side SDK Key from the Dashboard and add it to DataDome instance with the method setSdkKey

export default class MyApp extends Component {
  
  constructor(props) {
    super(props);
    DataDome.getInstance().setSdkKey("Client_Side_Key");
  }
}

Add modal for challenges

To display challenge pages, add a DataDomeModal component at the top of your views.
As a modal, it will be showed on top of the app when the SDK needs to show a challenge page.

In the DataDomeModal component, you need to define the ref of this component to the DataDome module instance.

export default class MyApp extends Component {
  render() {
    return (
    <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
      <DataDomeModal onRef={ref => (DataDome.getInstance().setContainerViewRef(ref))} />
      <Text>Hello, world!</Text>
    </View>
    );
  }
}

Usage

To enable the interceptor from DataDome, add the datadome option in fetch requests.

fetch("https://jsonplaceholder.typicode.com/posts/1", {
  method: 'GET',
  headers: h,
  datadome: true
})

For older React Native versions that do not include credentials in options, add this option.

fetch("https://jsonplaceholder.typicode.com/posts/1", {
  method: 'GET',
  headers: h,
  datadome: true,
  credentials: 'include' // or can also be 'same-origin'
})

Advanced setup

Share the DataDome cookie between the app and its WebViews

If your app uses WebViews to load DataDome-protected URLs, you must share the DataDome cookie between the app and its WebViews.
Since both contexts do not share the same cookie storage, the DataDome cookie would otherwise be lost when transitioning between them, resulting in repeated challenges for users.

From the app to a WebView instance

  1. Retrieve the last datadome cookie.
const cookie = await DataDome.getInstance().getStoredDatadomeCookie();
  1. Pass it to the WebView as a Cookie header.
<WebView
  source={{
    uri: url,
    headers: {
      'Cookie': cookie,
    },
  }}
/>

From a WebView instance to the app

  1. Inject code on the WebView to send cookies back to the app with postMessage. This will run once the page is loaded.
  2. Add an onMessage event listener to retrieve the cookie from the WebView. If you already use onMessage for other purposes, the type field ensures only the DataDome message is handled here.
  3. Save the datadome cookie value on the DataDome SDK with storeCookie.
const jsCode = 'window.ReactNativeWebView.postMessage(JSON.stringify({ type: "datadome-cookie", value: document.cookie }))';

<WebView source={{ uri: url, headers: { Cookie: datadomeCookie } }}
  style={{ flex: 1, width: 400 }}
  injectedJavaScript={jsCode}
  onMessage={(event) => {
    const message = JSON.parse(event.nativeEvent.data);
    if (message.type === 'datadome-cookie') {
      DataDome.getInstance().storeCookie(message.value);
    }
  }}
/>

📘 Note on sharedCookiesEnabled option

Keep sharedCookiesEnabled={false} (the default).

On iOS, setting sharedCookiesEnabled={true} triggers automatic cookie synchronization between NSHTTPCookieStorage and WKWebView at unpredictable times. This can create race conditions with DataDome's challenge resolution flow and result in repeated challenges.

If you require sharedCookiesEnabled={true} for other reasons, the manual postMessage sync above must be in place. It will prevent the race condition and ensure DataDome cookie state remains consistent.

Optional: Activate verbose logger

For investigation purposes, you may need to print additional logs to get more details about cookie injection, response format, or response status.
These logs may be helpful in case of issue investigation, such as challenge loop issues.

For investigation purposes, you may need to print additional logs to get more details about cookie injection, response format, or response status.
These logs may be helpful in case of issue investigation, such as challenge loop issues.

DataDome.getInstance().enableVerboseLogs(true);

By default, the verbose logger is disabled: only error logs will be printed by the SDK.

How to test

📘

To test your integration, you need to activate the protection on your endpoints

Force a captcha display

❗️

Do not use the BLOCKUA User-Agent in production

To test your integration, add the header User-Agent with the value BLOCKUA to your request. This will hint the remote protection module to block the current request. The plugin will react to the blocked request (403 code) and display a challenge.