How to Write a Flutter Web Plugin
--
Introduction
Do you want to add support for a Flutter plugin? This article will show you how web support was added to the url_launcher plugin. Before you read this article, you should already be familiar with plugin development and the concepts in Developing plugin packages.
Example: package:url_launcher
First, let’s create an example app that uses package:url_launcher
, so you can verify that it works correctly.
Setup
In order to use web plugins, you need to be on the Flutter dev channel. Make sure that you’re on the dev channel by running:
$ flutter channel dev
$ flutter upgrade
Now, you need to enable web support so that Flutter can set up your app to run on the web:
$ flutter config --enable-web
Now, create a directory named url_launcher_example
(let’s assume ~/url_launcher_example
), and create a Flutter project in it:
$ mkdir “~/url_launcher_example”
$ cd “~/url_launcher_example”
$ flutter create .
Use package:url_launcher
Our example app will have just a button that launches google.com.
First, update the pubspec so that you depend on package:url_launcher
. In pubspec.yaml
, under dependencies
, add the line (highlighted in bold):
name: url_launcher_example
...
dependencies:
flutter:
sdk: flutter
url_launcher: 5.2.3
...
Now, replace the entire contents of lib/main.dart
with the following:
Verify that the app works by running it on your Android or iOS device, or simulator by running the app normally with flutter run
. The app should look like this screenshot. Try clicking the Launch! button and verify that it opens Google.
Now, you can run the same app on the web with flutter run -d chrome
. The app should open and render just like the mobile version, but clicking Launch! does nothing. Let’s start writing the web plugin for url_launcher
.
Creating package:url_launcher_web
Create a new directory called url_launcher_web
(let’s assume ~/url_launcher_web
):
$ mkdir “~/url_launcher_web”
$ cd “~/url_launcher_web”
Unfortunately, there is no template for web plugins currently (that is, you can’t use flutter create
), so you’ll have to create the plugin manually. But, before you start coding, some discussion is in order about how this is actually going to be implemented.
Looking into package:url_launcher
Let’s take a look at how package:url_launcher
is implemented, so you know what to do for package:url_launcher_web
. The main code can be found here. These are the main bits you should care about:
Almost all Flutter plugins are written like this. They create a MethodChannel
, and then the plugin works by sending a method call on the channel to the “platform-side” (that is, Android or iOS) of the plugin. So, the way this plugin works on Android is that there is some code, written in Java, that registers a MethodChannel
on the Android side. The MethodChannel
waits for method calls, which call the required Android code to launch a URL. In order to get this plugin working on the web, you need to do the same thing as in the Android and iOS implementations, create a MethodChannel
that waits for method calls, and when the MethodChannel
receives them, launches the given URL.
Implementing package:url_launcher_web
Web implementations of Flutter plugins are written as Dart packages. Let’s begin with the pubspec.yaml
. Assuming you’re in your url_launcher_web
directory you created earlier, create a file named pubspec.yaml
, and paste the following code in the file:
Some key things to note:
- The
platforms:
section contains a section forweb:
that declares the name of the class where you will implement the plugin, as well as the filename containing the class. - The
flutter_web_plugins
dependency lets you register the web implementation ofurl_launcher
.
We declared that our implementation will be a class named UrlLauncherPlugin
and be written in url_launcher_web.dart
, so let’s write that class now. Make sure you create a lib/
directory first, then edit lib/url_launcher_web.dart
, and paste the following code in the file:
There are several key points to note in our implementation, let’s go over them one by one.
Registering the plugin with registerWith
Just as on Android or iOS, web plugins need to do some initialization before the app runs. This is done in the static registerWith
method, which takes a Registrar
(which comes from package:flutter_web_plugins
).
In this case, we are registering a MethodChannel
to listen for incoming messages from the app. Note how we initialize the MethodChannel
with registrar.messenger
. All MethodChannel
s have a BinaryMessenger
that they use to send and receive messages. By default, a MethodChannel
uses the default BinaryMessenger
defined in Flutter. The BinaryMessenger
sends messages from the app to the platform side, but we are writing a plugin that is on the platform side and should receive messages from the app, so we need to initialize the MethodChannel
with a different BinaryMessenger
. Luckily, the Registrar
that is passed to the plugin in registerWith
has a messenger that does the right thing. By initializing our MethodChannel
with it, we now have a MethodChannel
that receives method calls from the app.
Handling method calls
The MethodChannel
we created registered handleMethodCall
as its method call handler. This means that any time the app-side MethodChannel
(the one created in package:url_launcher
) sends a method call to the platform-side MethodChannel
(the one we created in registerWith
) this method call handler is invoked.
If the handler receives a method call to the ‘launch’
method, then it invokes _launch
, which simply opens a new window with the given URL.
Using the web plugin in the example app
Our web plugin is looking good! Now, we need to use it from the example app we created earlier.
Modify the pubspec in ~/url_launcher_example
to add a dependency to ~/url_launcher_web
. Your change should look something like this. (Make sure to use the correct path for where you actually put your directories):
dependencies:
flutter:
sdk: flutter
url_launcher: 5.2.3
url_launcher_web:
path: ../url_launcher_web
Now, run the example app again with flutter run -d chrome
. Try clicking the Launch! button. It should open google.com in a new tab.
Congratulations! You successfully added web support to a Flutter plugin!