We’ve written a bit in the past about the negative impact of sharing buttons on performance. What if there was a better way? Let’s talk about the Web Share API.
What is the Web Share API?
The Web Share API offers something of an alternative. It’s an API developed by Google to expose the native sharing capabilities of the underlying platform to the web. That means a share button on your web page can trigger the native sharing widget of your device, just like a native app can. On Android—it’s only supported on Android right now—it will look something like this, depending on the apps installed on the device:
Why is this a good thing?
First, it offers a simple way to tie into the platform’s native share widget, so that you can share to any installed apps, social networks, and even websites (yes, even websites, more on this later).
Additionally, it offers a uniform and familiar way to share, whether from a native app, or via this API, from the web.
Since this functionality is built into the browser, it removes the need to use any third-party scripts. That means less code to run on your site, and most likely fewer HTTP requests. So that’s a win for performance.
Fewer third-party scripts on your site means fewer scripts to potentially hoover up user data, so it’s safer for your users. And again, since you’re not relying on a third-party script, it means one less script that’s out of your control, so it’s safer for you and your site.
Sounds good so far; let’s see how it works.
How to use it
Before jumping into the code, there are two things to note:
- The page must be served over HTTPS
- It can only be triggered by user interaction (this means it couldn’t be triggered on page load, for example)
Now to the API. There’s just one method: navigator.share()
. You definitely need to test for support before using it, you can do this with:
1 |
if(navigator.share) {...} |
Now we can call the share()
method. We need to pass in an object that can include title
, text
, and url
fields, and must include one of text
and url
:
1 2 3 4 5 6 7 |
if(navigator.share) { navigator.share({ title: 'mobiForge: Web Share API' text: 'Check out this great article about the Web Share API' url: 'https://mobiforge.com/design-development/web-share-api' }) } |
You can put whatever you want for title
, text
and url
. Users will generally expect that the shared URL would be the URL of the current page, although it could feasibly link to other pages too, for instance if you included a share button beside each item in a list, or it could link to some position in a page with a page anchor.
The code above will achieve our goal, but since it returns a Promise, we can also use this to catch success and exception situations, and act accordingly:
1 2 3 4 5 6 7 8 9 |
if(navigator.share) { navigator.share({ title: 'mobiForge: Web Share API' text: 'Check out this great article about the Web Share API' url: 'https://mobiforge.com/design-development/web-share-api' }) .then(() => console.log('Share complete')) .error((error) => console.error('Could not share at this time', error)) } |
When the Promise resolves, you could indicate to the user whether it was successful or not, perhaps through a UI tweak or message.
Adding the share button
We’ll need a way to trigger the share widget. We’ll use a button for this. When this button is clicked, we’ll trigger the navigator.share()
functionality:
1 |
<button class="share-button">Share with the Web Share API</button> |
Then we’ll attach a JavaScript event handler to the button, using the click event, to execute the code we saw earlier:
1 2 3 4 5 6 7 8 9 10 11 |
document.querySelector('.share-button').addEventListener('click', function() { if(navigator.share) { navigator.share({ title: 'mobiForge: Web Share API' text: 'Check out this great article about the Web Share API' url: 'https://mobiforge.com/design-development/web-share-api' }) .then(() => console.log('Share complete')) .error((error) => console.error('Could not share at this time', error)) } }); |
If you visit this page on a supported browser (e.g. Chrome-based browsers on Android), you should be able to pop up the native share widget by clicking the button below:
You can also see the demo and source code on github here.
So, can I get rid of my share buttons?
Right now this API is not widely supported. Although it’s described in a W3C Draft Community Report, it’s not actually a standard, and it only works on Android devices. This means you’re going to need a workaround for when it’s not supported.
You have a couple of options here:
- Integrate a third-party service, and use that when
navigator.share()
isn’t supported - Implement simple sharing buttons without a third-party service, there are plenty of examples out there
- Use a polyfill to bring the
navigator.share()
API to a browser where it’s not supported. There are plenty of polyfills available
Even with a polyfill, can I get rid of my share buttons?
There’s something else to consider first. Sharing buttons on the web typically allow the user to share to any number of web sites, while the native share widget shares only to targets offered by installed apps. So, it would seem that the Web Share API doesn’t offer this.
Or does it…? Earlier, we teased that even a website could be used as a target for the share. Let’s see how this might happen. Time to take a look at the Web Share Target API.
Adding websites to the native share widget with the Web Share Target API
To be able to share to an arbitrary website, we’d need the site to
- be registered in the list of share targets, and
- be able to receive and process the data to be shared
This brings us to the Web Share Target API, a deceptively simple API that works in a complementary way to the Web Share API. It comes at the problem from the other end, allowing a web site to opt-in or register itself as a web sharing target in the native sharing widget.
It’s set up via web app manifest file, thus overlapping somewhat with Progressive Web App (PWA) territory, and further chipping away at the native-web divide.
Registering a web share target
First, we need to get the web share target registered with the native share widget. To do this we need a page that the user can visit, and which will prompt the user to “Add to homescreen”. This is important: the site must be Added to the homescreen of the device before the share target will be registered on the device. This means we’ll need the page to link to a web app manifest file and a service worker. We’ll add this stuff to our index page (source) at mobiforge.github.io.
To specify a share target, we have to add a share_target
object to the web app manifest. The share_target
object should include a url_template
property, like this:
1 2 3 |
"share_target": { "url_template": "web-share-target.html?title={title}&text={text}&url={url}" } |
In the url_template
above, we’re specifying a page, and three parameters, title
, text
, and url
. When the page is added to the homescreen of the device, the manifest will be read, and the share target registered on the device.
Your manifest will need a couple of other properties that specify the name of your site, an icon, and theme colours. These things essentially configure how your web page will be display by the device after it’s been added to the home screen.
This is the full manifest for our example on https://mobiforge.github.io/manifest.json:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
{ "lang": "en", "name": "mobiForge Web examples", "short_name": "mobiForge", "start_url": "/", "display": "standalone", "theme_color": "#ffffff", "background_color":"#ffffff", "icons": [ { "src": "mf-logo-144.png", "sizes": "144x144", "type": "image/png" } ], "share_target": { "url_template": "web-share-target.html?title={title}&text={text}&url={url}" }, "scope":"/" } |
If you visit https://mobiforge.github.io/ on Chrome Canary on Android, you should see an Add to homescreen prompt. Chrome Canary will parse the manifest, and register the share target URL. You can check this immediately by tapping Menu -> Share in the browser. You should now see a new icon in the native share widget, mobiForge Web examples in our case:
We can also go back to the original Web Share API example page we set up earlier (or even the button above in this article), to trigger the native widget via the Web Share API. You should see the same result whether triggering natively, or via the Web Share API.
Creating the share target page
So now we need to create the page to handle the shared data. We’ve specified that web-share-target.html
will be the share target, and it will take title
, text
, and url
parameters, so let’s set this up. When the user selects a web share target from the native share widget, they will be brought to the share target URL in a webview.
We’ll write a minimal page with a small bit of JavaScript to grab the shared parameters and output them to the browser. First, let’s add a container for each parameter:
1 2 3 4 5 |
<h2>mobiForge web share target example page</h2> <p>You shared:</p> <div id="share_title"></div> <div id="share_text"></div> <div id="share_url"></div> |
Then, we’ll run the JavaScript below on the page load event. It parses the shared parameters from the URL, and then writes each parameter to the appropriate HTML element:
1 2 3 4 5 6 7 8 |
<script> window.addEventListener('load', function() { var url = new URL(window.location.toString()); document.querySelector('#share_title').innerHTML = 'Title: ' + url.searchParams.get('title'); document.querySelector('#share_text').innerHTML = 'Text: ' + url.searchParams.get('text'); document.querySelector('#share_url').innerHTML = 'URL: ' + url.searchParams.get('url'); }); </script> |
That’s it!
Testing the Web Share Target API and Web Share API together
To test the Web Share API and Web Share Target API end-to-end, you can do the following:
- Visit the original page (mobiforge.github.io) in Chrome Canary (or Chrome Dev) browser to get the ‘Add to home screen’ prompt. This should add the new web share target to the native widget.
- Visit the Web Share API example page: (mobiforge.github.io/web-share-api.html)
- Tap the share button
- Choose the web share target we created
- Profit!
Note: at the time of writing there’s an issue with the API, so that when text
and url
parameters are included in the share, they are combined into the text
field.
So, can the Web Share API replace my sharing buttons?
Initially, it’s tempting to say no, it’s not a replacement, it does something a bit different. The native share widget, and therefore the Web Share API, can’t share to arbitrary websites, like web sharing buttons can. However, you can share to any app or web app you’ve installed or added to your homescreen. You can share to Twitter if you have Twitter installed. So, in the sense that you need to have installed an app (or web app), it’s not an outright replacement for website sharing widgets.
But maybe this isn’t such a big deal. After all, you will only share with Twitter if you have a Twitter account. Ditto, Facebook, Reddit, or any social network or community site. You might have the app already installed on your device, if so, then you’re in business.
What if you’re not a fan of apps, and prefer the web? Then you won’t have the native app of your favorite social network installed. Well, this is where the Web Share Target API comes in. You can share to any web app where
- you’ve added the web app to the device homescreen (PWA-speak for installing)
- the web app has to have implemented the Web Share Target API in its manifest
This second item might seem like a big ask, but we’ve already seen how to do it in this article. It’s likely that the major social sites will implement it. In fact, Twitter already has! You can see this live right now on the web, in the Twitter Lite PWA. It has the following in its manifest:
1 2 3 |
"share_target": { "url_template": "compose/tweet?title={title}&text={text}&url={url}" } |
Which means you can share to the Twitter Lite PWA web app just as you would a native app:
Let’s face it, how many of the sometimes tens of share icons does any one user habitually use? One or two, maybe three? So why should users have to see the same icons they don’t use on every site? With the Web Share API, you’ll only see the sharing targets that you use. So while it might seem more restrictive at first, it actually makes a lot of sense: sharing options tailored for you, by you, based on the apps and web apps you actually use, and built into the browser.
Leave a Reply