Skip to main content

JavaScript Injection

ZikZak InAppWebView provides multiple methods for injecting JavaScript code into your WebView.

Four Primary Injection Methods​

1. evaluateJavascript​

Evaluates JavaScript code and returns the result.

Supported Platforms: Android, iOS

onLoadStop: (controller, url) async {
var result = await controller.evaluateJavascript(
source: "document.title"
);
print('Page title: $result');

// Execute complex JavaScript
var json = await controller.evaluateJavascript(source: """
JSON.stringify({
title: document.title,
url: window.location.href,
userAgent: navigator.userAgent
})
""");
},
note

Returns dynamic type - handles JSON-serializable values (integers, strings, booleans, objects).

2. callAsyncJavaScript​

Executes asynchronous JavaScript functions with parameters.

Supported Platforms: Android, iOS

onLoadStop: (controller, url) async {
var result = await controller.callAsyncJavaScript(
functionBody: """
var response = await fetch(arguments[0]);
return await response.text();
""",
arguments: {'url': 'https://api.example.com/data'}
);

if (result != null && result.value != null) {
print('Response: ${result.value}');
}
if (result != null && result.error != null) {
print('Error: ${result.error}');
}
},

Returns CallAsyncJavaScriptResult containing:

  • value: The successful result
  • error: Any error that occurred

3. injectJavascriptFileFromUrl​

Loads external JavaScript files via URL.

Supported Platforms: Android, iOS

await controller.injectJavascriptFileFromUrl(
urlFile: WebUri('https://code.jquery.com/jquery-3.6.0.min.js'),
scriptHtmlTagAttributes: ScriptHtmlTagAttributes(
id: 'jquery-script',
onLoad: () {
print('jQuery loaded successfully');
},
onError: () {
print('Failed to load jQuery');
},
),
);
tip

Requires ScriptHtmlTagAttributes.id to be set for callbacks to work.

4. injectJavascriptFileFromAsset​

Loads JavaScript files from Flutter asset folders.

Supported Platforms: Android, iOS

await controller.injectJavascriptFileFromAsset(
assetFilePath: 'assets/js/custom-script.js'
);
note

This evaluates the asset file contents directly rather than creating a script tag.

Critical Timing Consideration​

IMPORTANT

Do NOT call injection methods during onWebViewCreated or onLoadStart events - the WebView is not ready yet!

✅ Use these methods in:

  • onLoadStop event
  • onProgressChanged when progress == 100
  • Other events confirming page readiness
// ❌ WRONG - Too early!
onWebViewCreated: (controller) async {
await controller.evaluateJavascript(source: 'alert("Hello")');
},

// ✅ CORRECT - Page is ready
onLoadStop: (controller, url) async {
await controller.evaluateJavascript(source: 'alert("Hello")');
},

Complete Example​

import 'package:flutter/material.dart';
import 'package:zikzak_inappwebview/zikzak_inappwebview.dart';

class JavaScriptInjectionExample extends StatefulWidget {

_JavaScriptInjectionExampleState createState() =>
_JavaScriptInjectionExampleState();
}

class _JavaScriptInjectionExampleState
extends State<JavaScriptInjectionExample> {

InAppWebViewController? webViewController;


Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('JavaScript Injection'),
actions: [
IconButton(
icon: Icon(Icons.play_arrow),
onPressed: _executeJavaScript,
),
],
),
body: InAppWebView(
initialUrlRequest: URLRequest(
url: WebUri('https://flutter.dev'),
),
onWebViewCreated: (controller) {
webViewController = controller;
},
onLoadStop: (controller, url) async {
// Inject jQuery from CDN
await controller.injectJavascriptFileFromUrl(
urlFile: WebUri('https://code.jquery.com/jquery-3.6.0.min.js'),
);

// Inject custom script from assets
await controller.injectJavascriptFileFromAsset(
assetFilePath: 'assets/js/custom.js',
);
},
),
);
}

Future<void> _executeJavaScript() async {
if (webViewController != null) {
// Get page information
var title = await webViewController!.evaluateJavascript(
source: 'document.title'
);

// Call async function
var result = await webViewController!.callAsyncJavaScript(
functionBody: """
return new Promise((resolve) => {
setTimeout(() => {
resolve('Delayed result');
}, 1000);
});
""",
);

print('Title: $title');
print('Async result: ${result?.value}');
}
}
}

Asset Configuration​

Don't forget to add your JavaScript files to pubspec.yaml:

flutter:
assets:
- assets/js/custom.js
- assets/js/helper.js

Next Steps​

  • JavaScript Communication - Two-way Dart ↔ JavaScript communication
  • User Scripts (coming soon) - Inject scripts before page loads
  • Content Worlds (coming soon) - Isolated JavaScript execution