Working with WebView in Flutter

Ashish Garg
4 min readOct 12, 2021

--

As a mobile application developer, you will never want to cut down the user engagement within your app. You will not want your user to redirect to some other application and do some tasks over there. Let’s say you want to open a website, you will definitely not want to open a third-party browser app like, chrome or safari. For this case, flutter has a really awesome plugin webview_flutter to create WebView. Today I will talk about what else we can do with WebView apart from just open a URL.

Usages of WebView

A common scenario in which using WebView is helpful is when you want to provide information in your app that you might need to update, such as an end-user agreement or a user guide. Within your Flutter app, you can use the webview_flutter plugin to create WebView then use that to display your document that's hosted online.

When and why using WebView makes sense?

If money is involved in your app then payment is the most important thing to take care of above all. And let’s say you already have a secured existing payment flow on your website then it's not a bad idea to use that in your app. Here comes the use of WebView with which you can do it easily.

I am not saying you cannot implement a secured payment flow in flutter but to develop such a thing and testing alone will take days maybe weeks. There are many other scenarios where WebView can be useful.

Set Cookies/Headers for some authentication

Think of a case when you need to open your website in WebView within your app, you will not want a user to log in again on the website instead what you can do for your user is set the cookies or headers in your Webview.

First, create an object of WebViewController and Completer class, here Completer class is used for a future task. Then handle the callback of completer inside build method and then .complete method is to be called on the completer after the webview is created.

final Completer<WebViewController> _completer =
Completer<WebViewController>();
WebViewController _webViewController;

@override
Widget build(BuildContext context) {
_completer.future.then((controller) {
_webViewController = controller;
Map<String, String> header = {'cookie': 'token=$token'};
_webViewController.loadUrl(URL, headers: header);
});
return Scaffold(
body: Container(
child:
WebView(
debuggingEnabled: true,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (controller) async {
_completer.complete(controller);
})),
);
}

You can also try to set cookies inside onPageFinished by calling a method on webview controller.

webViewController.evaluateJavascript('document.cookie = "token=$token"');

Using JavaScript in WebView to share data

Your WebView is ready but now you might need your javascript code to somehow communicate with your Flutter. For example, you might need to send a message to show snack bar in your Webview you can do so through JavaScript Channels.

JavascriptChannel _javascriptChannel() {
return JavascriptChannel(
name: 'CHANNEL_NAME',
onMessageReceived: (JavascriptMessage message) {
if(message == 'SHOW_SNACKBAR'){
//show sncakbar or handle it the way you want
}
});
}

By default, javascript mode is disabled in WebView. We need to set the value of javascriptMode to unrestricted before working with javascript in WebView.

WebView(
...
javascriptMode: JavascriptMode.unrestricted,
javascriptChannels: <JavascriptChannel>{_javascriptChannel()},
...
);

Navigation in WebView

As you are getting better with WebView you might need to control the navigation now. For example, you want to block navigation for a particular URL or you might need to exit or do something when you hit a specific URL. You can do so by using navigation delegate in your WebView.

navigationDelegate: (NavigationRequest request) {
if (request.url.startsWith('SOME_URL')) {
print('blocking navigation to $request}');
return NavigationDecision.prevent;
}
return NavigationDecision.navigate;
},

Run HTML code in WebView

You might come across a problem where you might need to run some HTML inside your WebView. You can do this easily by converting your normal HTML string into URI with some encoding obviously and then converting it back to string and pass in .loadUrl method of WebView controller.

webViewController.loadUrl(Uri.dataFromString('HTML_STRING',mimeType:'text/html', encoding: Encoding.getByName('utf8')).toString());

Run jQuery command in WebView

Not just the HTML code but we can run jQuery too in our WebView. The Simplest example of jQuery can be an alert dialog. You can try it on google console by running a simple command alert('Hey Google!')

Now In WebView after the page loading is finished run this one line of code and see the result yourself.

webViewController.evaluateJavascript("javascript:(function() {"
"alert(\"Hey Google!\");"
"})()");

Bonus: You might consider to use hybrid composition in your WebView while working with some input/keyboard in it. Hybrid composition has built-in support for keyboard issues. Add this line of code in initState method to overcome these problems. For more info you can read here.

If(Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();

Conclusion

In this article, I have shared with you some of the problems I had solved while working with the WebView in Flutter. Hope you find it useful.

Comment down here if you have anything to ask or connect with me on LinkedIn and Twitter.

Do not forget to hit the clap👏 button.

--

--