Skip to main content
Version: 6.x.x

Getting Started

What is a WebView? Differences between a WebView and a Browser

Before we get started, we should talk about the differences between a WebView and a Browser.

A WebView is a tool that allows you to display web content within a mobile or desktop application. However, it is not a full browser. This means that many advanced browser features (such as managing multiple tabs, extensions, advanced security features, developer tools, etc.) may not be available or will need to be manually implemented.

If you wish to create an app that behaves like a browser, it is possible to do so using WebViews, but keep in mind that there will be limitations depending on the platform (Android, iOS, Windows, etc.). Each operating system has rules and restrictions that might affect your implementation. For example, advanced features such as file system access or handling custom HTTPS certificates may require additional configurations.

A WebView is primarily designed to embed web content into native apps, rather than providing a complete browsing experience like a full browser. If your project requires browser-like functionality, it's important to be aware of these differences and the potential challenges.

Here you can find a Browser example implemented using this plugin: https://github.com/pichillilorenzo/flutter_browser_app

Let's get started now!

Installation

Add flutter_inappwebview as a dependency in your pubspec.yaml file.

If you're running an application and need to access the binary messenger before runApp() has been called (for example, during plugin initialization), then you need to explicitly call the WidgetsFlutterBinding.ensureInitialized() first.

An example:

void main() {
// it should be the first line in main method
WidgetsFlutterBinding.ensureInitialized();

// rest of your app code
runApp(MyApp());
}

Requirements

Native WebView implementation

These are the native WebView classes used by the plugin to implement its features:

info

Since each platform has its own native implementation, keep in mind that in some cases they may behave differently.

Setup Android

If you are starting a new fresh app, you need to create the Flutter App with flutter create --androidx -i swift to add support for androidx, otherwise it won't work (see AndroidX Migration to migrate an existing app).

During the build, if Android fails with Error: uses-sdk:minSdkVersion 16 cannot be smaller than version 19 declared in library, it means that you need to update the minSdkVersion of your android/app/build.gradle file to at least 19.

Also, you need to add <uses-permission android:name="android.permission.INTERNET"/> in the android/app/src/main/AndroidManifest.xml file in order to give minimum permission to perform network operations in your application.

If you flutter created your project prior to version 1.12, you need to make sure to update your project in order to use the new Java Embedding API! Take a look at the official Flutter wiki: Upgrading pre 1.12 Android projects. Also, you can refer to the #343 issue.

Remember to add <meta-data> tag inside the <application> tag of your android/app/src/main/AndroidManifest.xml:

<meta-data
android:name="flutterEmbedding"
android:value="2" />

as mentioned in the 6th step of Full-Flutter app migration guide. Without this, the plugin will NOT work!!!

Also, note that to use the InAppWebView widget on Android, it requires Android API 20+ (see AndroidView) or Android API 19+ if you enable the useHybridComposition Android-specific option.

Support HTTP (non-HTTPS) request

Starting with Android 9 (API level 28), cleartext support is disabled by default:

ChromeSafariBrowser on Android 11+

If you want to use the ChromeSafariBrowser class on Android 11+ you need to specify your app querying for android.support.customtabs.action.CustomTabsService in your AndroidManifest.xml (you can read more about it here: https://developers.google.com/web/android/custom-tabs/best-practices#applications_targeting_android_11_api_level_30_or_above).

Enable Material Components for Android

To use Material Components when the user interacts with input elements in the WebView, follow the steps described in the Enabling Material Components instructions.

Setup iOS

If you are starting a new fresh app, you need to create the Flutter App with flutter create --androidx -i swift (see flutter/flutter#13422 (comment)), otherwise, you will get this message:

=== BUILD TARGET flutter_inappwebview OF PROJECT Pods WITH CONFIGURATION Debug ===
The "Swift Language Version" (SWIFT_VERSION) build setting must be set to a supported value for targets which use Swift. Supported values are: 3.0, 4.0, 4.2, 5.0. This setting can be set in the build settings editor.

If you still have this problem, try to edit iOS Podfile like this (see #15):

target 'Runner' do
use_frameworks! # required by simple_permission
...
end

post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['SWIFT_VERSION'] = '5.0' # required by simple_permission
config.build_settings['ENABLE_BITCODE'] = 'NO'
end
end
end

Instead, if you have already a non-swift project, you can check this issue to solve the problem: Friction adding swift plugin to objective-c project.

Support HTTP (non-HTTPS) request

You need to disable Apple Transport Security (ATS) feature. There're two options:

  • Disable ATS for a specific domain only (Official wiki): (add following codes to your Info.plist file)
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>www.yourserver.com</key>
<dict>
<!-- add this key to enable subdomains such as sub.yourserver.com -->
<key>NSIncludesSubdomains</key>
<true/>
<!-- add this key to allow standard HTTP requests, thus negating the ATS -->
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<!-- add this key to specify the minimum TLS version to accept -->
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
</dict>
  • Completely disable ATS (Official wiki): (add following codes to your Info.plist file)
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key><true/>
</dict>

Other useful Info.plist properties are:

  • NSAllowsLocalNetworking: A Boolean value indicating whether to allow loading of local resources (Official wiki);
  • NSAllowsArbitraryLoadsInWebContent: A Boolean value indicating whether all App Transport Security restrictions are disabled for requests made from web views (Official wiki).

Setup MacOS

To be able to make HTTP requests, you need to configure the macOS App Sandbox by enabling the Outgoing Connections (Client) option in your MacOS XCode Project, under Runner > Signing & Capabilities.

Here is an example of configuration:

MacOS App Sandbox example

For more details, check the Apple Official Guide.

Setup Windows

To be able to build on Windows, you must have the nuget CLI tool available on your Windows environment.

Follow the instructions here: https://learn.microsoft.com/en-us/nuget/install-nuget-client-tools?tabs=windows#nugetexe-cli

Add the folder location for the nuget.exe file to your Windows PATH environment variable.

Setup Web

To make it work properly on the Web platform, you need to add the web_support.js file inside the <head> of your web/index.html file:

<head>
<!-- ... -->
<script type="application/javascript" src="/assets/packages/flutter_inappwebview_web/assets/web/web_support.js" defer></script>
<!-- ... -->
</head>
Flutter widgets over iframe are not working!

When overlaying Flutter widgets on top of HtmlElementView widgets that respond to mouse gestures (handle clicks, for example), the clicks will be consumed by the HtmlElementView, and not relayed to Flutter.

The result is that Flutter widget's onTap (and other) handlers won't fire as expected, but they'll affect the underlying webview.

This is an issue of Flutter itself and not of this plugin.

To overcome this problem, you should use the official pointer_interceptor Flutter plugin. Check the pointer_interceptor plugin docs to understand how to use it.

Load files inside the assets folder

To be able to make visible your local asset files (images, javascript, css, etc.) to Flutter, you need to add them in the assets section of the pubspec.yaml file, otherwise they cannot be found. Read the official Flutter documentation Adding assets and images for more details.

Example of a pubspec.yaml file:

...

# The following section is specific to Flutter.
flutter:

# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true

assets:
- assets/index.html
- assets/css/
- assets/images/

...

Enable camera for HTML inputs

In order to be able to use camera, for example, for taking images through <input type="file" accept="image/*" capture> HTML tag, you need to ask camera permission. If you need to capture video and audio, you need to ask also microphone permission. To ask permissions, for example, you can use the permission_handler plugin!

Code example:

import 'package:permission_handler/permission_handler.dart';

Future main() async {
WidgetsFlutterBinding.ensureInitialized();
await Permission.camera.request();
await Permission.microphone.request(); // if you need microphone permission

runApp(MyApp());
}

Configure Android

On Android, you need to add these permissions in your AndroidManifest.xml file to be able to use camera for taking images and videos:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.VIDEO_CAPTURE" />
<uses-permission android:name="android.permission.AUDIO_CAPTURE" />

Also, you need to add the following code inside the <application> tag of your AndroidManifest.xml file:

<provider
android:name="com.pichillilorenzo.flutter_inappwebview_android.InAppWebViewFileProvider"
android:authorities="${applicationId}.flutter_inappwebview_android.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>

Configure iOS

On iOS, you need to add the following properties in your Info.plist file to be able to use camera for taking images and videos:

<key>NSMicrophoneUsageDescription</key>
<string>Flutter requires access to microphone.</string>

<key>NSCameraUsageDescription</key>
<string>Flutter requires access to camera.</string>

If you open this file In Xcode, then the NSMicrophoneUsageDescription property is represented by Privacy - Microphone Usage Description and NSCameraUsageDescription is represented by Privacy - Camera Usage Description.