> For the complete documentation index, see [llms.txt](https://docs.hackle.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hackle.io/en/development-guide/react-native/webapp-integration.md).

# WebApp Integration

{% hint style="info" %}
This feature is supported in React Native SDK version 3.28.0 and above, and JavaScript SDK version 11.51.0 and above.

For information about WebApp, refer to the [documentation](/en/development-guide/faq/web-app-intergration.md).
{% endhint %}

{% hint style="warning" %}
Already integrating a WebApp?

If you were using the script-based method that requires modifying both React Native and JavaScript code, or if you are upgrading the plugin from 1.x to 2.x, refer to the [migration guide](/en/development-guide/react-native/webapp-integration/react-native-web-app-plugin-migration.md).
{% endhint %}

When rendering your own website through `WebView`, you can use the settings below to use the Hackle JavaScript SDK included in the website identically to the Hackle React Native SDK functions without modifying the website code.

When WebApp Integration is configured, all events that occur within the WebView are collected through the React Native SDK.

After completing the React Native SDK integration, follow the steps below.

{% stepper %}
{% step %}

### Add Plugin

{% hint style="warning" %}
You must install the plugin version that matches the React Native SDK version you are using.

* React Native SDK **4.x** → Plugin **2.x**
* React Native SDK **3.x** → Plugin **1.x**

Plugin 2.x does not work with React Native SDK 3.x.
{% endhint %}

<details>

<summary>Requirements by Plugin Version</summary>

<table><thead><tr><th width="177.421875">Plugin Version</th><th width="220">React Native SDK</th><th width="180">react-native-webview</th><th>React Native</th></tr></thead><tbody><tr><td>2.0.0 and above</td><td>4.0.0 and above, below 5.0.0</td><td>13.13.0 and above</td><td>0.74.0 and above</td></tr><tr><td>1.2.0</td><td>3.30.0 and above, below 4.0.0</td><td>13.13.0 and above</td><td>No restriction</td></tr><tr><td>1.1.0 and above, below 1.2.0</td><td>3.30.0 and above, below 4.0.0</td><td>11.0.0 and above</td><td>No restriction</td></tr><tr><td>1.0.0 and above, below 1.1.0</td><td>3.28.0 and above, below 4.0.0</td><td>11.0.0 and above</td><td>No restriction</td></tr></tbody></table>

Plugin version 2.0.0 and above requires Android API 24 and above, and iOS 13 and above.

If you are using React Native 0.81 or later but need to stay on plugin 1.x, use plugin version 1.1.1 or later.

</details>

[![](https://img.shields.io/npm/v/%40hackler%2Freact-native-webview-plugin)](https://www.npmjs.com/package/@hackler/react-native-webview-plugin)

{% tabs %}
{% tab title="npm" %}

```shell
# React Native SDK 4.x
npm install --save @hackler/react-native-webview-plugin@^2.0.0

# React Native SDK 3.x
npm install --save @hackler/react-native-webview-plugin@^1.2.0
```

{% endtab %}

{% tab title="yarn" %}

```shell
# React Native SDK 4.x
yarn add @hackler/react-native-webview-plugin@^2.0.0

# React Native SDK 3.x
yarn add @hackler/react-native-webview-plugin@^1.2.0
```

{% endtab %}
{% endtabs %}

#### iOS

```shell
cd ios
pod install
```

{% hint style="warning" %}
Make sure to run a clean build for the first build after installing the plugin.
{% endhint %}
{% endstep %}

{% step %}

### Inject WebView Bridge

{% tabs %}
{% tab title="Plugin 2.x (React Native SDK 4.x)" %}
Wrap `WebView` with `HackleWebViewBridge`. `HackleWebViewBridge` installs the bridge into the WebView and forwards requests sent by the website's Hackle JavaScript SDK to the React Native SDK.

```tsx
import { WebView } from 'react-native-webview';
import { createInstance, HackleProvider } from "@hackler/react-native-sdk";
import { HackleWebViewBridge } from '@hackler/react-native-webview-plugin';

// Hackle SDK initialization must be complete before injecting the WebApp bridge.
const hackleClient = createInstance("YOUR_APP_SDK_KEY");

function MyWebView() {
  return (
    <HackleProvider hackleClient={hackleClient}>
      <HackleWebViewBridge>
        // Use only a single react-native-webview object as the child element.
        <WebView source={{ uri: currentUrl }} />
      </HackleWebViewBridge>
    </HackleProvider>
  );
}
```

{% hint style="danger" %}
**The child of `HackleWebViewBridge` must be exactly one `WebView`.**
{% endhint %}
{% endtab %}

{% tab title="Plugin 1.x (React Native SDK 3.x)" %}
Add HackleWebViewConfig to the `nativeConfig` props of the react native webview.

You can create a config using the `createHackleWebViewConfig()` function.

```tsx
import { WebView } from 'react-native-webview';
import { createInstance, HackleProvider } from "@hackler/react-native-sdk";
import { createHackleWebViewConfig } from '@hackler/react-native-webview-plugin';

// Hackle SDK initialization must be complete before injecting the WebApp bridge.
const hackleClient = createInstance("YOUR_APP_SDK_KEY");

function MyWebView() {
  const hackleConfig = createHackleWebViewConfig();

  return (
    <HackleProvider hackleClient={hackleClient}>
      <WebView
        nativeConfig={hackleConfig}
        source={{ uri: currentUrl }}
      />
    </HackleProvider>
  );
}
```

{% hint style="info" %}
When you upgrade the React Native SDK to 4.x, you must also upgrade the plugin to 2.x. Refer to the [migration guide](/en/development-guide/react-native/webapp-integration/react-native-web-app-plugin-migration.md).
{% endhint %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
To use this feature, the **JavaScript web page must use the same App SDK Key**.
{% endhint %}
{% endstep %}

{% step %}

### Integrating Auto-collected Events from WebView

The `$page_view` and `$engagement` that occur in the website inside the WebView are disabled.

You can enable each auto-collected event when configuring the WebView bridge.

{% tabs %}
{% tab title="Plugin 2.x (React Native SDK 4.x)" %}
Configure it by passing props to `HackleWebViewBridge`.

```tsx
import { WebView } from 'react-native-webview';
import { createInstance, HackleProvider } from "@hackler/react-native-sdk";
import { HackleWebViewBridge } from '@hackler/react-native-webview-plugin';

// Hackle SDK initialization must be complete before injecting the WebApp bridge.
const hackleClient = createInstance("YOUR_APP_SDK_KEY");

function MyWebView() {
  return (
    <HackleProvider hackleClient={hackleClient}>
      <HackleWebViewBridge
        automaticScreenTracking
        automaticEngagementTracking
        automaticRouteTracking
      >
        <WebView source={{ uri: currentUrl }} />
      </HackleWebViewBridge>
    </HackleProvider>
  );
}
```

To set a value to `false`, specify it explicitly, like `automaticRouteTracking={false}`.
{% endtab %}

{% tab title="Plugin 1.x (React Native SDK 3.x)" %}
Configure it by passing `HackleWebViewConfig` to `createHackleWebViewConfig()`.

```tsx
import { WebView } from 'react-native-webview';
import { createInstance, HackleProvider } from "@hackler/react-native-sdk";
import { createHackleWebViewConfig } from '@hackler/react-native-webview-plugin';

// Hackle SDK initialization must be complete before injecting the WebApp bridge.
const hackleClient = createInstance("YOUR_APP_SDK_KEY");

function MyWebView() {
  const hackleConfig = createHackleWebViewConfig({
    automaticScreenTracking: true,
    automaticEngagementTracking: true,
    automaticRouteTracking: true,
  });

  return (
    <HackleProvider hackleClient={hackleClient}>
      <WebView
        nativeConfig={hackleConfig}
        source={{ uri: currentUrl }}
      />
    </HackleProvider>
  );
}
```

{% endtab %}
{% endtabs %}

#### Configuration Options

The option names and default values are the same for plugin 1.x and 2.x.

<table data-full-width="false"><thead><tr><th width="260.6715625">Option</th><th width="295.49">Description</th><th width="86.32953125">Default</th><th width="100.2484375">Supported Version</th></tr></thead><tbody><tr><td><code>automaticScreenTracking</code></td><td>Whether to collect <code>$page_view</code></td><td><code>false</code></td><td>1.0.0 +</td></tr><tr><td><code>automaticEngagementTracking</code></td><td>Whether to collect <code>$engagement</code></td><td><code>false</code></td><td>1.0.0 +</td></tr><tr><td><code>automaticRouteTracking</code></td><td>Whether to automatically collect page information</td><td><code>true</code></td><td>1.1.0 +</td></tr></tbody></table>

{% hint style="info" %}
Choose the collection method for page navigation.

* **Automatic collection**: Set `automaticScreenTracking`, `automaticEngagementTracking`, and `automaticRouteTracking` all to `true`.
* [**Manual collection**](/en/development-guide/javascript/event-tracking/js-track-page.md): Set `automaticScreenTracking` and `automaticEngagementTracking` to `true`. Set `automaticRouteTracking` to `false`.
  {% endhint %}
  {% endstep %}
  {% endstepper %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.hackle.io/en/development-guide/react-native/webapp-integration.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
