> 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/flutter/flutter-webapp-integration.md).

# 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
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/flutter/flutter-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.
