Progressive web application as a share option in Android

Progressive Web Applications are becoming more and more powerful and now can be registered as a share intent on Android devices. This means that any Android application can share directly to your web app through the standard native sharing dialog.

Website in the native share intent dialog

It also works the other way around. Your PWA can trigger the native share dialog and send data to other applications. This brings them one step closer to native apps.

In this article we will focus on becoming the share target.

Can a progressive web app be registered as a share option in Android?

For a long time this wasn’t an option. But with the release of Chrome 71 on Android there is an experimental support of the Web Share Target API. Your PWA can appear in the sharing menu. How cool is that?

Let’s have a look at what you need to get your website into the Android sharing dialog:

  1. Manifest
  2. Service Worker
  3. Share target

Becoming progressive

The first steps are really about becoming a progressive web application. The share intent will be registered when the user “installs” the app by saving it to the home screen – either from a popup or manually.

Important note: Your website needs to be served over HTTPS.

Add to home screen popup dialog

For that you will need a website manifest and a registered service worker. Firstly, let’s have a look at a simple manifest.json.

{
  "short_name": "Sharing Demo",
  "name": "Web Target Sharing Demo",
  "icons": [
    {
      "src": "/android-chrome-192x192.png",
      "type": "image/png",
      "sizes": "192x192"
    },
    {
      "src": "/android-chrome-512x512.png",
      "type": "image/png",
      "sizes": "512x512"
    }
  ],
  "start_url": "/",
  "background_color": "#ffffff",
  "display": "standalone",
  "theme_color": "#ffffff"
}

You can read about all the different values and options in more detail here. After that, we will need to link to our manifest in our HTML files. So add the following into head section of your page.

<link rel="manifest" href="/manifest.json">

The Second thing for an app to become a PWA is a registered service worker with a fetch event. It doesn’t need to do much, it just has to be there. The simplest way to do that is to create service-worker.js with an empty fetch listener.

self.addEventListener('fetch', function(event) {});

It won’t do anything but it is everything we need for now. Next, we will register the service worker in our page.

if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/service-worker.js')
      .then(function(reg){
        console.log("Service worker registered.");
     }).catch(function(err) {
        console.log("Service worker not registered. This happened:", err)
    });
 }

Nice work! It wasn’t too hard and we changed a simple website into a progressive web app. If you are using HTTPS you should be able to see the Add to home screen popup when you visit your website.

Add to home screen prompt for progressive web apps

You can use Chrome Dev Tools to check on the manifest and see if the app can be installed. Go to Application -> Manifest or use Lighthouse and see the Installable section of the report.

Adding web share target

Converting your website to a progressive web application was actually the hard part. Registering the share intent so your app will appear in the native dialog is super easy.

You need to add the following lines into your manifest.json that we created previously.

  "share_target":
  {
    "action": "/share",
    "params":
    {
      "title": "title",
      "text": "text",
      "url": "url"
    }
  },

Every time a user will share something through the dialog the request will go to /share endpoint of your website with query parameters of title, text, and url.

Note: If you are sharing something from mobile Chrome the URL actually comes through as a text.

Now we put everything together and this is the final version of the manifest.json file with registered share_target section.

{
  "short_name": "Sharing Demo",
  "name": "Web Target Sharing Demo",
  "icons": [
    {
      "src": "/android-chrome-192x192.png",
      "type": "image/png",
      "sizes": "192x192"
    },
    {
      "src": "/android-chrome-512x512.png",
      "type": "image/png",
      "sizes": "512x512"
    }
  ],
  "share_target":
  {
    "action": "/share",
    "params":
    {
      "title": "title",
      "text": "text",
      "url": "url"
    }
  },
  "start_url": "/",
  "background_color": "#ffffff",
  "display": "standalone",
  "theme_color": "#ffffff"
}

After that, you can use any method of reading the query parameters that suits your needs. Either server-side like this with Ruby on Rails:

def share
  @url = params[:url]
  @title = params[:title]
  @text = params[:text]
end

or client-side with a bit of good old javascript:

var parsedUrl = new URL(window.location.toString());
console.log('Title shared: ' + parsedUrl.searchParams.get('name'));
console.log('Text shared: ' + parsedUrl.searchParams.get('description'));
console.log('URL shared: ' + parsedUrl.searchParams.get('link'));

I’m a big fan of progressive web apps and the web share target makes the integration with your mobile workflow much smoother. It comes with a few caveats of being experimental so the API will most likely change or it could totally disappear. Also, keep in mind that (at the moment) it’s supported only on Android devices and your Apple users won’t benefit from it . The proposal takes iOS into account though so maybe some time in the future. I’ve been waiting for this feature for a while and I’m super-excited that it made it to the Android community.


Would you like to get the most interesting content about programming every Monday?
Sign up to Programming Digest and stay up to date!