Chidume Nnamdi I'm a software engineer with over six years of experience. I've worked with different stacks, including WAMP, MERN, and MEAN. My language of choice is JavaScript; frameworks are Angular and Node.js.

Render webpages using the Flutter WebView plugin

6 min read 1690

Rendering Webpages Using Flutter WebView

Google created Flutter to simplify the way we create apps, making it possible for our apps to run on different platforms without any need for porting code or rewriting our already existing apps.

Doing this is no easy feat, because each native operating system has something unique about it and they are numerous. Google can’t support much all of them. So, Google made Flutter configurable, in a way that plugins can be developed by other developers.

Now, one of the common widgets we have is the WebView widget. This WebView widget allows us to load webpages.

How can we use this same widget in Flutter when we need it? flutter.dev solved the issue for us. They developed a Flutter plugin for that: it is webview_flutter.

What is Flutter WebView?

webview_flutter is a Flutter plugin that provides a WebView widget on Android and iOS. This plugin is used to display webpages on both Android and iOS devices.

In this article, we will learn how to use the webview_flutter in a Flutter project.

We will learn how to use the webview_flutter plugin to load webpages from its URL or a local source.

Requirements

We will be building a Flutter project, so we will need a few tools already installed in our machine.

Flutter

This is a Flutter SDK used to run and compile Flutter projects. Go to Flutter’s docs to select the Flutter SDK based on your operating system:

The links contain instructions on how to install the Flutter SDK on your machine. After the installation, make sure that flutter is in your global path. Run the command flutter --help to test that the Flutter SDK is installed and accessed globally in your machine.

We made a custom demo for .
No really. Click here to check it out.

VS Code

VS Code is a powerful modern code editor brought to us by Microsoft. It has an extension that can help you use Flutter from your VS Code with ease. Install Flutter’s extension in your VS Code.

Android Studio

If you want to run and test your apps in Android, then you need to have Android Studio installed on your machine. Then, we need to install Flutter and Dart plugins:

Make sure everything is installed and running. In the next section, we will set up a Flutter project.

Setting up your Flutter project

Now, we will create a Flutter project. We will use the flutter CLI tool to do this.
The name of our Flutter project will be webviewprj. Run the below command:

flutter create webviewprj

Flutter will create a project in the folder webviewprj and then install dependencies.
Open this project in VS Code. If you don’t use VS Code, you can do everything from the terminal, but you must open the project in your preferred code editor:

cd webviewprj

If you are using VS Code, there will be no need to do the above. Just go to View in the top menu and click on Terminal to open VS Code integrated terminal.

Adding webview_flutter dependency

Next, we will add webview_flutter dependency to our project.

Open the pubspec.yaml file in the root of your project and add the below lines to it:

dependencies:
  flutter:
    sdk: flutter
  webview_flutter:

Saving the pubspec.yaml file will cause the VS Code to install the dependency. If you are not using VS Code, run the below command in your terminal to install the webview_flutter dependency:

flutter pub get webview_flutter

flutter pub contains commands for managing Flutter packages.

flutter pub get gets packages in a Flutter project. In this case, it gets the webview_flutter package in our Flutter project.

Next, we set the minimum SDK version needed for the webview_flutter plugin. Open android/app/build.gradle in your project and add the below configuration code to the android → defaultConfig section:

android {
    defaultConfig {
        minSdkVersion 19
    }
}

webview_flutter works from Android v19 upward to the latest Android version.

Using webview_flutter

webview_flutter exports a WebView class. This class initiates and creates a new web view and renders the set webpage (via its URL) inside the WebView widget. The WebView can be controlled using a WebViewController that is passed to the onWebViewCreated callback once the WebView is created.
To render the WebView widget, we need to import the webview_flutter package:

import 'package:webview_flutter/webview_flutter.dart';

Then, we render the WebView widget like this:

WebView(
    initialUrl: 'https://medium.com'
);

This will load the page https://medium.com and render it in the WebView widget. The WebView widget will render https://medium.com just like a browser will render the page. The initialUrl param passed to the WebView tells WebView the URL of the webpage to load and render.
There are other params that we can pass to WebView. Let’s see them below:

N.B., the below params and their descriptions were culled from WebView class library docs.

  • onWebViewCreated: This is a function that is invoked once the web view is created
  • initialUrl: This is a string that holds the URL of the webpage to be loaded and rendered on the WebView
  • javascriptMode: This sets whether JavaScript is enabled in the WebView
  • javascriptChannels: The set of JavascriptChannels available to JavaScript code running in the WebView
  • navigationDelegate: A delegate function that decides how to handle navigation actions
  • onPageStarted: Invoked when a page starts loading
  • onPageFinished: Invoked when a page has finished loading
  • onProgress: Invoked when a page is loading
  • debuggingEnabled: Controls whether WebView debugging is enabled. By default, it is set to false
  • gestureNavigationEnabled: A Boolean value indicating whether horizontal swipe gestures will trigger back-forward list navigations. By default, it is set to false
  • allowsInlineMediaPlayback: Controls whether inline playback of HTML5 videos is allowed on iOS. This field is ignored on Android because Android allows it by default. Its default value is false

N.B., The javascriptMode and autoMediaPlaybackPolicy parameters must not be null.

Creating widget pages

Now, we will create two widget pages in our app: HomePage and WebViewPage. HomePage page will hold two buttons. Each button when clicked will open the WebViewPage page. This WebViewPage page will render a WebView, passing the webpage URL to the WebView widget.

Let’s create them. Already, Flutter has generated some code for us. We will do away with other widgets except the MyApp widget.
Open the lib/main.dart file and edit it to the below code:

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'dart:io';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage()
    );
  }
}

See that we render HomePage in the MyApp widget. This makes the HomePage render when the app is opened.

Let’s code the HomePage widget:

class HomePage extends StatelessWidget {
  void _handleURLButtonPress(BuildContext context, String url, String title) {
    Navigator.push(context,
        MaterialPageRoute(builder: (context) => WebViewPage(url, title)));
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("WebView Flutter Example"),
      ),
      body: Center(
          child: Column(
        children: [
          MaterialButton(
            color: Colors.blue,
            child: Text(
              "Open pub.dev",
              style: TextStyle(color: Colors.white70, fontWeight: FontWeight.bold),
            ),
            onPressed: () {
              _handleURLButtonPress(
                  context, "https://pub.dev", "pub.dev");
            },
          ),
          MaterialButton(
            color: Colors.blue,
            child: Text(
              "Open Medium.com",
              style: TextStyle(color: Colors.white70, fontWeight: FontWeight.bold),
            ),
            onPressed: () {
              _handleURLButtonPress(
                  context, "https://medium.com", "Medium.com");
            },
          ),
        ],
      )),
    );
  }
}

See that this HomePage renders two buttons MaterialButton. Each button is set to call the function _handleURLButtonPress when clicked.

The first button, Open pub.dev, calls the _handleURLButtonPress, passing through the context, "https://pub.dev", and "pub.dev". The "https://pub.dev" is the URL of the webpage loaded and rendered by WebView. "pub.dev" will be the AppBar title of the WebViewPage.

The second button, Open Medium.com, will call the function _handleURLButtonPress with the params context, https://medium.com.com (the webpage URL that the WebView widget will load and render), and Medium.com (title of the WebViewPage page).

The function _handleURLButtonPress launches the WebViewPage widget page. It will pass the URL and title of the page to the WebViewPage.

Let’s code the WebViewPage widget:

class WebViewPage extends StatefulWidget {
  final String url;
  final String title;

  WebViewPage(this.url, this.title);

  @override
  WebViewPageState createState() =>
      WebViewPageState(this.url, this.title);
}

class WebViewPageState extends State<WebViewPage> {
  final String url;
  final String title;

  WebViewPageState(this.url, this.title);

  @override
  void initState() {
    super.initState();
    // Enable hybrid composition.
    if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(this.title),
        ),
        body: Column(children: [
          Expanded(
              child: WebView(
                  initialUrl: this.url,
                  javascriptMode: JavascriptMode.unrestricted
              )
          )
        ])
    );
  }
}

The WebViewPage is a stateful widget, and WebPageState is the logic and internal state for the WebViewPage.

The WebViewPage constructor takes url and title. It passes it to WebViewPageState in the createState method.

When the WebViewPageState renders WebView, it passes initialUrl to the WebView with this.url as its value.

The JavaScript mode javascriptMode is set to JavascriptMode.unrestricted. This JavaScript mode enables the webpages to run JavaScript.

Running the app

Now, we are done with the coding. We will run the app. To do that, run the below command in the terminal:

flutter run

If you are using VS Code, right-click on the lib/main.dart and click on either Run Without Debugging or Start Debugging.

N.B., make sure you have your emulator running.

This will compile the app on run it on your phone emulator.

Homepage

Flutter WebView Homepage

Click on Open pub.dev

Flutter WebView Pub.Dev Example 1

Flutter WebView Pub.Dev Example 2

Flutter WebView Pub.Dev Example 3

Click on Open Medium.com

Flutter WebView Medium Example 1

Flutter WebView Medium Example 2 Flutter WebView Medium Example 3

 

Conclusion

We learned a lot in this tutorial.

First, we started by introducing WebView and how the same could be ported to Flutter. Next, we introduced webview_flutter, and also learned how to set up a Flutter project and install the webview_flutter dependency. Later on, we built widgets to render and display the webpages https://blog.logrocket.com and https://logrocket.com on a WebView widget from the webview_flutter plugin.

With this webview_flutter plugin, we will be able to render and display webpages in our Flutter application.

Take a look at the source code in GitHub.

: Full visibility into your web apps

LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.

.

References

Chidume Nnamdi I'm a software engineer with over six years of experience. I've worked with different stacks, including WAMP, MERN, and MEAN. My language of choice is JavaScript; frameworks are Angular and Node.js.

Leave a Reply