Track WebViews
WebView tracking links the CSQ SDK to the JavaScript tag running inside the WebView.
Usage
Section titled UsageTo enable WebView tracking, few steps are required:
- Inject the Contentsquare Tracking Tag in WebView mode in the web pages loaded in your app's WebViews. For more information on this step, refer to 📚 Mobile Apps WebView Tracking Documentation.
- Make sure JavaScript is enabled in your WebViews.
- Wrap your WebView widget with
CSQWebViewWrapperwidget and implement it as explained below.
Implementation
Section titled ImplementationThe implementation can be done in two different ways depending on how your WebView allows the injection of scripts. These two different ways relies of two subtypes of WebViewWrapperDelegate:
UserScriptWebViewWrapperDelegateto inject the required Contentsquare script through User Scripts. Choose this if you use theflutter_inappwebviewpackage.JSChannelWebViewWrapperDelegateto inject the required Contentsquare script through JavaScript channel. Choose this if you use packages likewebview_flutterorflutter_webview_plugin.
Examples
Section titled ExamplesThis example uses the flutter_inappwebview ↗ InAppWebView widget.
import 'package:contentsquare/csq.dart';
CSQWebViewWrapper( delegate: UserScriptWebViewWrapperDelegate( builder: (BuildContext context, String userScript) { return InAppWebView(
initialOptions: InAppWebViewGroupOptions( crossPlatform: InAppWebViewOptions( javaScriptEnabled: true, ), ), initialUrlRequest: URLRequest( url: Uri.parse(url), ), initialUserScripts: UnmodifiableListView([ UserScript( // Inject the script properly // by setting the `userScript` as source source: userScript, // Set the injectionTime as AT_DOCUMENT_START injectionTime: UserScriptInjectionTime.AT_DOCUMENT_START, ), ]), ); }, ),)This example uses the webview_flutter ↗ WebViewWidget widget.
import 'package:contentsquare/csq.dart';
webViewController.setJavaScriptMode(JavaScriptMode.unrestricted);CSQWebViewWrapper( delegate: JSChannelWebViewWrapperDelegate(
addJavaScriptChannel: (WebViewJSChannelHandler handler) {
webViewController.addJavaScriptChannel( handler.channelName, onMessageReceived: (jsMessage) { handler.onMessageReceived(jsMessage.message); }, ); },
builder: (context) { return WebViewWidget(controller: webViewController); }, ),);Optional: detect the WebView context on dual-context pages
If the same page is served both in a regular browser and inside your app's WebView (dual-context tracking), the page usually selects which Contentsquare tag to load with an isWebView() guard. That guard must detect the WebView context before the page's tag script runs — otherwise the browser tag loads instead of the WebView tag (a tag "race condition") and native and web tracking are not linked.
With JSChannelWebViewWrapperDelegate (for example when using webview_flutter), the SDK cannot inject a document-start script, so the reliable early signal is the user agent. Apply handler.userAgent to the controller before loading the URL:
addJavaScriptChannel: (WebViewJSChannelHandler handler) { // Set the user agent before loading the page so the page // can detect the WebView context early. webViewController.setUserAgent(handler.userAgent);
webViewController.addJavaScriptChannel( handler.channelName, onMessageReceived: (jsMessage) { handler.onMessageReceived(jsMessage.message); }, );},Validate WebView tracking
Section titled Validate WebView trackingTo validate the tracking of WebViews, refer to the platform-specific instructions.

