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
})
""");
},
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 resulterror: 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');
},
),
);
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'
);
This evaluates the asset file contents directly rather than creating a script tag.
Critical Timing Consideration
Do NOT call injection methods during onWebViewCreated or onLoadStart events - the WebView is not ready yet!
✅ Use these methods in:
onLoadStopeventonProgressChangedwhen 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