Inline WebView
InAppWebView renders a WebView inside the Flutter widget tree. It is the right choice when the WebView belongs to a screen and should participate in that screen's layout and lifecycle.
Initial content
Use one of the initial content options:
InAppWebView(
initialUrlRequest: URLRequest(
url: WebUri('https://example.com'),
),
)InAppWebView(
initialFile: 'assets/website/index.html',
)InAppWebView(
initialData: InAppWebViewInitialData(
data: '<h1>Hello</h1>',
baseUrl: WebUri('https://example.com/'),
),
)Use only one initial content source for a WebView. Later navigation should be performed through the controller.
Settings
Prefer initialSettings for new code:
InAppWebView(
initialSettings: InAppWebViewSettings(
javaScriptEnabled: true,
mediaPlaybackRequiresUserGesture: true,
disableAutocorrection: true,
),
)initialOptions and the older option classes remain available for compatibility, but they are deprecated. Settings that are not supported by a platform are ignored or use that platform's fallback behavior. Check runtime capability before depending on a platform-specific setting.
Useful settings include:
disableAutocorrectionfor editable HTML elements;containerIdfor a named storage profile where the platform supports it;proxySettingsfor per-WebView proxy configuration where supported;javaScriptBridgeEnabledand origin allowlists for bridge control;useHybridCompositionon Android when choosing a platform-view mode;writingToolsBehavioron Apple platforms where Writing Tools are available.
JavaScript
final result = await controller.evaluateJavascript(
source: 'document.title',
);For a structured asynchronous JavaScript operation, use callAsyncJavaScript. Treat returned values as nullable and validate their shape before using them in application logic.
JavaScript bridge
Register a handler from Dart:
controller.addJavaScriptHandler(
handlerName: 'appBridge',
callback: (arguments) {
return {'ok': true, 'received': arguments};
},
);Call it from the page:
window.flutter_inappwebview.callHandler('appBridge', {action: 'refresh'});Only expose handlers that the page is allowed to call. For untrusted or multi-tenant content, use the bridge origin allowlist and validate every argument in Dart.
Keep the controller and WebView identity stable
Do not create a new InAppWebView controller or InAppWebViewKeepAlive inside build(). Rebuilding the widget is normal; recreating the native WebView is expensive and can reset page state, JavaScript state, and scroll position. See Preload and reuse for route transitions.