How to Write a Flutter Web Plugin
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.
First, let’s create an example app that uses
package:url_launcher, so you can verify that it works correctly.
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), and create a Flutter project in it:
$ mkdir “~/url_launcher_example”
$ cd “~/url_launcher_example”
$ flutter create .
Our example app will have just a button that launches google.com.
First, update the pubspec so that you depend on
dependencies, add the line (highlighted in bold):
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
Create a new directory called
url_launcher_web (let’s assume
$ 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.
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.
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:
platforms:section contains a section for
web:that declares the name of the class where you will implement the plugin, as well as the filename containing the class.
flutter_web_pluginsdependency lets you register the web implementation of
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
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
In this case, we are registering a
MethodChannel to listen for incoming messages from the app. Note how we initialize the
MethodChannels 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
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):
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!