Track WebViews (Beta)
Once the WebView Tracking Tag is implemented in the web pages, you need to wrap any tracked WebView in the ContentsquareWebViewTrackerBuilder
Widget. See:
- WebView Flutter if you are using the official WebView plugin
- Generic API if you are using any other package
WebView Flutter
Section titled WebView FlutterIf you are using the official WebView plugin, the following code can be used to track a webview:
ContentsquareWebViewTrackerBuilder( builder: (context, tracker) { return WebView( initialUrl: 'https://your_tracked_webview.com', javascriptMode: JavascriptMode.unrestricted, javascriptChannels: tracker.javascriptChannels, onWebViewCreated: tracker.onWebViewCreated, onPageFinished: tracker.onPageFinished, ); },)
Generic API
Section titled Generic APITo use a custom WebView package, you can use the ContentsquareWebViewTrackerBuilder.custom
widget constructor.
The builder gives you a tracker of which you need to consider the following elements:
tracker.registerWebViewController
tracker.javascriptChannels
: Register these channels which are used to communicate between Contentsquare and your WebViewtracker.initializeWebViewTracking
: This must be called after initializeWebViewTracking and when thejavascriptChannels
are registered.
See the following section for a concrete example of implementation with the flutter_inappwebview package.
Implementation examples
Section titled Implementation examplesIf you are using the flutter_inappwebview, the following code can be used to track a webview:
ContentsquareWebViewTrackerBuilder( builder: (context, tracker) { return InAppWebView( initialUrlRequest: URLRequest( url: Uri.parse('https://your_tracked_webview.com'), ), onWebViewCreated: (controller) { // 1. Register the ContentsquareWebViewController by mapping InAppWebView's controller tracker.registerWebViewController( ContentsquareWebViewController( evaluateJavascript: (source) async { return '${await controller.evaluateJavascript(source: source)}'; }, currentUrl: () async => '${await controller.getUrl()}', javascriptChannelCall: (channelName, data) { return 'window.flutter_inappwebview.callHandler("$channelName", $data)'; }, ), );
// 2. Register the javascript channels for (final javascriptChannel in tracker.javascriptChannels) { controller.addJavaScriptHandler( handlerName: javascriptChannel.name, callback: (args) { return javascriptChannel.onMessageReceived(args.first); }, ); } }, onLoadStop: (controller, uri) async { // 3. Initialize the tracking. // // This MUST be called AFTER the controller is registered and the javascript // channels are available await tracker.startPageTracking(); }, ); },)
If you are using the webview_flutter, the following code can be used to track a webview:
Start by defining a WebViewTrackerInitializer
widget:
class WebViewTrackerInitializer extends StatefulWidget { const WebViewTrackerInitializer({ Key? key, required this.initialUrl, required this.tracker, required this.webviewController, required this.child, }) : super(key: key);
final String initialUrl; final ContentsquareWebViewTracker tracker; final WebViewController webviewController;
final Widget child;
@override State<WebViewTrackerInitializer> createState() => _WebViewTrackerInitializerState();}
class _WebViewTrackerInitializerState extends State<WebViewTrackerInitializer> { Future<void> _initTracking() async { final tracker = widget.tracker; final controller = widget.webviewController;
// 0. Enable Javascript injection await controller.setJavaScriptMode(JavaScriptMode.unrestricted);
// 1. Register the ContentsquareWebViewController by mapping it to WebViewController tracker.registerWebViewController( ContentsquareWebViewController( evaluateJavascript: (source) async { return '${await controller.runJavaScriptReturningResult(source)}'; }, currentUrl: controller.currentUrl, javascriptChannelCall: (channelName, data) { return 'window.$channelName.postMessage($data)'; }, ), );
// 2. Register the javascript channels for (final javascriptChannel in tracker.javascriptChannels) { await controller.addJavaScriptChannel( javascriptChannel.name, onMessageReceived: (javascriptMessage) { javascriptChannel.onMessageReceived(javascriptMessage.message); }, ); }
await controller.setNavigationDelegate( NavigationDelegate( onPageFinished: (_) async { // 3. Initialize the tracking every time a new page has finished loading // // This will be called AFTER the controller is registered and the // javascript channels are available since we register the controller // and the javascript channels BEFORE loading the initial url. await tracker.startPageTracking(); }, ), );
await controller.loadRequest(Uri.parse(widget.initialUrl)); }
@override void initState() { super.initState(); _initTracking(); }
@override Widget build(BuildContext context) => widget.child;}
Which you can then use to track your webview:
ContentsquareWebViewTrackerBuilder( builder: (context, tracker) { return WebViewTrackerInitializer( initialUrl: 'https://your_tracked_webview.com', tracker: tracker, webviewController: webviewController, child: WebViewWidget(controller: webviewController), ); },)
If you are using the webview_flutter v2 or v3, the following code can be used to track a webview:
ContentsquareWebViewTrackerBuilder( builder: (context, tracker) { return WebView( initialUrl: 'https://your_tracked_webview.com', // 0. Enable Javascript injection javascriptMode: JavascriptMode.unrestricted, // 1. Register the ContentsquareWebViewController by mapping it to WebViewController onWebViewCreated: (controller) { tracker.registerWebViewController( ContentsquareWebViewController( evaluateJavascript: controller.runJavascriptReturningResult, javascriptChannelCall: (channelName, data) { return 'window.$channelName.postMessage($data)'; }, ), ); }, // 2. Register the javascript channels javascriptChannels: { for (final channel in tracker.javascriptChannels) JavascriptChannel( name: channel.name, onMessageReceived: (message) => channel.onMessageReceived( message.message, ), ), }, onPageFinished: (_) async { // 3. Initialize the tracking every time a new page has finished loading await tracker.startPageTracking(); } ); },)
Validate WebView tracking
Section titled Validate WebView trackingValidation - Flutter side
Section titled Validation - Flutter sideOnce you arrive on the screen with the tracked WebView, you should see the following log:
┌───────────────────────────────────────────────────────────────────────────────│ ℹ️ INFO ℹ️ (CSLIB) [Tracked WebView]├───────────────────────────────────────────────────────────────────────────────│ WebView tracking enabled on WebView with initialUrl:│ https://your.tracked.website└───────────────────────────────────────────────────────────────────────────────
Validation - Web side
Section titled Validation - Web sideOnce you arrive on the screen with the tracked WebView, you should see the following log:
┌───────────────────────────────────────────────────────────────────────────────│ ℹ️ INFO ℹ️ (CSLIB) [Tracked WebView] ⟶ Event "sendMessage"├───────────────────────────────────────────────────────────────────────────────│ {"message":"ready, v:06c8d9bbfdf0e4bb9041b784e95c751873654cb0"}└───────────────────────────────────────────────────────────────────────────────