September 18, 2019
Progressive web apps (PWAs) are all the hype these days, and for good reason! PWAs provide significant user experience benefits over traditional web apps and web sites. If you’re unfamiliar with the idea of a progressive web app, I’d recommend taking a look at this article on Google Developers.
The primary goal of PWAs is to blur the line between the UI/UX of web apps and that of native apps (apps that are built with native technologies to target specific operating systems, such as iOS and Android). One of the ways a PWA can blur this line is by providing the same, native-feeling functionality as a native app. Luckily for those of us trying to build great PWAs, browser vendors have been working hard to unlock these capabilities for us, including the ability to add to home screen, re-engage with push notifications, and even connect to a bluetooth device!
Shout out to all the great browser vendors out there for continuing to push the web platform forward!
This post will focus on a small piece of functionality that, when implemented properly, will enhance the native feel of your app and contribute to an enhanced user experience: sharing.
In today’s world, enabling your users to share your content effortlessly is more important than ever. But it doesn’t only enhance their experience—when users are able to share your content easily across a wide range of platforms, the ultimate result is the increased visibility of your content. You benefit as well!
If you want to grow your audience and your reach, your content needs to be easy to share.
Traditionally, we web developers have been responsible for building custom share UIs into our web apps, either manually or by leveraging third-party libraries or services. For example, my website’s blog utilizes several react-share buttons and icons for its custom share UI, as seen in the following video:
In the absence of alternatives, the custom share UI approach is great! However, it has a few major drawbacks:
Is there a way we can solve all of these problems at once? There is! Please welcome to the stage the Web Share API!
In 2016, the Chrome team first launched the Web Share API in Chrome 61 for Android. Since then, it has been picked up by a few more browsers (more on that to come). The Web Share API unlocks the power of the device’s native sharing UI and makes it accessible to web apps.
Instead of web apps themselves being responsible for the share UI, the Web Share API enables a web app to instruct the browser to show the native share UI for a specific piece of shareable content.
This approach to showing share UIs solves all the problems mentioned above:
Here’s how it looks on my website’s blog:
At the time of this writing, the Web Share API is implemented in a few mobile browsers but hasn’t yet seen widespread adoption across both desktop and mobile. Check the Web Share API Can I Use page for up-to-date browser support information.
Because of poor browser support, it’s best practice to use the Web Share API when it’s available and fall back to a custom share UI when it isn’t. I take this approach on my website. In the video above, notice how the native UI is triggered by the same button that would trigger the custom UI if Web Share were not supported. This approach is also taken by The Dev Community.
Because the Web Share API is so easy to use, adding it to your web app can be an extremely quick win UX-wise for users with Web Share support in their browser. Let’s take a look at just how easy it is.
Because all the hard work of building and showing the share UI has already been taken care of by the browser and OS, we have to do very little to enable our users to share content with Web Share. There are only two steps involved:
When Web Share is supported, the browser exposes a share
function on the global window.navigator
object. The MDN docs do a great job of describing this function. Take a look!
All we need to do to check for Web Share is to check for the existence of this function:
if (navigator.share) {
// Web Share is supported
} else {
// Web Share is not supported
}
In order to mitigate abuse, browsers that support Web Share require navigator.share
to be called in response to a user gesture, such as clicking a share button:
myShareButton.addEventListener('click', () => {
if (navigator.share) {
// We can call navigator.share here!
}
})
// We can't call it here
The navigator.share
function expects you tell it what the user is trying to share. You specify this information as an object with a few optional keys: url
, text
, and title
. Although your requirements may be different depending on the nature of your app, most of the time you want to enable users to share the page they are currently looking at. To do this, you only need to define the url
and title
keys, which we have easy access to in a browser environment:
myShareButton.addEventListener('click', () => {
if (navigator.share) {
navigator.share({
url: location.href,
title: document.title
})
} else {
// Show custom share UI
}
})
If your app uses canonical URLs, you can query the document for a canonical URL and have that URL take priority over location.href
:
const canonicalLink = document.querySelector('link[rel=canonical]')
const url = canonicalLink ? canonicalLink.href : location.href
navigator.share({
url,
title: document.title
})
If your app needs to react to the share action, navigator.share
returns a promise for your convenience. The following example uses await
to handle the promise, but you can just as easily chain the usual .then()
and .catch()
calls.
try {
await navigator.share({ url, title })
console.log('Thanks for sharing!')
} catch (e) {
console.error('Could not share!', e)
}
That’s pretty much all there is to it!
The Web Share API is the future of sharing on the web. Regardless of whether you consider your web app to be a PWA, it should use the Web Share API when it is available. It only takes a few lines of code to check for browser support and conditionally make a call to the API!
It takes a lot of work to build a web app that is perceived by users as providing an equal or comparable experience to a native app. This checklist from Google enumerates an exhaustive list of PWA features, divided into baseline and exemplary feature categories.
Some of you may already be in the process of building new PWAs or migrating existing web apps to be PWAs. If that’s you, don’t let yourself be intimidated by the amount of work involved. Instead of focusing on the enormity of the entire task, prioritize features by anticipated impact, focus on one feature at a time, and identify and execute quick wins (such as Web Share!) in order to move your app in the right direction at an amplified rate. Don’t forget to re-evaluate your priorities as you go!
Thanks for reading and happy coding!
Written by Daniel Worsnup, a Software Engineer. All my links.