# WebApp Integration

{% hint style="info" %}
This feature is supported in Flutter SDK 2.13.0 and above, and JavaScript SDK 11.25.1 and above.
{% endhint %}

{% hint style="info" %}
For information about WebApps, refer to the [documentation](/en/development-guide/faq/web-app-intergration.md).
{% endhint %}

When rendering your own website via `InAppWebView`, you can configure the Hackle JavaScript SDK embedded in the website to work identically to the Hackle Flutter SDK features without modifying the website code by applying the following settings.

In this case, all Hackle events are collected through the Flutter SDK.

{% hint style="danger" %}
For `initialUserScripts`, **it is not guaranteed to be called before the web page loads on Android**, so you must load the page from the `controller` returned in `onWebViewCreated`.
{% endhint %}

{% hint style="danger" %}
If your website fires events at `beforeunload` or `unload` and closes the WebView at that point, events may not fire correctly or unexpected behavior such as OS popups may occur.

To fire events during these lifecycle hooks, use Flutter InAppWebView's [**KeepAlive**](https://inappwebview.dev/docs/webview/keep-alive/) feature to keep the WebView object alive at the native level even after it is removed from the Flutter widget tree, which ensures events are fired correctly.
{% endhint %}

```dart
import 'dart:collection';

import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:hackle/hackle.dart';

final keepAlive = InAppWebViewKeepAlive();

InAppWebView(
  initialSettings: InAppWebViewSettings(
    javaScriptEnabled: true,
  ),
  keepAlive = keepAlive,
  initialUserScripts: UnmodifiableListView<UserScript>([
    UserScript(
      source: HackleApp.getWebBridgeScript(),
      injectionTime: UserScriptInjectionTime.AT_DOCUMENT_START,
      forMainFrameOnly: true
    )]),
  onWebViewCreated: (controller) {
    controller.loadUrl(urlRequest: URLRequest(url: WebUri('YOUR_WEB_URL')));
  },
  onJsPrompt: (controller, jsPromptRequest) async {
    if(HackleApp.isInvocableCommandInWebView(jsPromptRequest.message)) {
      var result = await HackleApp.handleWebInterfaceCommand(jsPromptRequest.message);
      return JsPromptResponse(action: JsPromptResponseAction.CONFIRM, handledByClient: true, value: result);
    } else {
      return JsPromptResponse(handledByClient: false);
    }
  },
);
```

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

The Hackle Flutter WebView configuration uses Android `Javascript Userscript` and similar mechanisms to interact with the Hackle JavaScript SDK.
{% endhint %}

## Integrating Auto-collected Events from WebView

{% hint style="info" %}
This feature is supported in Flutter SDK 2.26.0 and above, and JavaScript SDK 11.51.0 and above.
{% endhint %}

`$page_view` events occurring on the website inside the WebView are disabled by default. You can enable auto-collected events by configuring `HackleWebViewConfig` when setting up the WebView bridge.

```dart
import 'dart:collection';

import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:hackle/hackle.dart';

final webViewConfig = HackleWebViewConfig.builder()
  .automaticScreenTracking(true)
	.automaticEngagementTracking(true)
  .build();

...
UserScript(
  source: HackleApp.getWebBridgeScript(webViewConfig: webViewConfig),
  injectionTime: UserScriptInjectionTime.AT_DOCUMENT_START,
  forMainFrameOnly: true
)]),
...
```

### Configuration Options

<table data-full-width="false"><thead><tr><th width="213.57421875">Config</th><th width="295.48828125">Description</th><th width="125.8125">Default</th><th width="108.09765625">Supported Version</th></tr></thead><tbody><tr><td><code>automaticScreenTracking</code></td><td>Whether to collect <code>$page_view</code> events occurring on the website</td><td><code>false</code></td><td>2.26.0+</td></tr><tr><td><code>automaticEngagementTracking</code></td><td>Whether to collect <code>$engagement</code> events occurring on the website</td><td><code>false</code></td><td>2.28.0+</td></tr><tr><td><code>automaticRouteTracking</code></td><td>Whether to automatically collect page information occurring on the website</td><td><code>true</code></td><td>2.28.0+</td></tr></tbody></table>


---

# Agent Instructions: 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:

```
GET https://docs.hackle.io/en/development-guide/flutter/flutter-webapp-integration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
