The 10 Minute Progressive Web App

There are many frameworks and services that promise to turn your site into a Progressive Web App (PWA) easily. In practice, it’s really quite simple to do yourself. This article will walk you through the process of setting up a PWA so you can see how easily it can be applied to any website.

Google’s rules are the de-facto standard for what qualifies as a PWA. At a MINIMUM the website must:

  • Be served over SSL (https)
  • Point to a valid web manifest file
  • Register a service worker

Let’s go through each of these requirements individually.

Set Up SSL

Virtually every hosting service offers some sort of SSL setup. Many are installed by default. If you’re in charge of your own server, you probably know how to do this. If not, Certbot is a great tool that completely automates the maintenance of your certificates. Whatever the case, setting up your web server to host over SSL is fairly straightforward and probably already done.

Add A Web Manifest

A web manifest file is a simple json file with some metadata about your site. If you’ve set up open graph metadata then you probably have all the information you need at hand. At a minimum, the manifest file requires the following:

  • name (title of your web site)
  • short_name (label that appears under the icon, when installed)
  • start_url (relative path to the front-page, e.g. ‘./index.html’)
  • display (display the app fullscreen or in a window)
  • background_color (used in the splash screen, along with the icon and name, when opening your app)
  • description (used in app store services like Appscope)
  • icons (an array of links to icon images at various sizes. Google recommends you include at minimum the 192px size.)
{
	"name": "GreenZeta 10 Minute PWA",
	"short_name": "GZ PWA",
	"theme_color": "#7bb951",
	"background_color": "#111313",
	"display": "fullscreen",
	"Scope": "/",
	"start_url": "/",
	"icons": [
	  {
		"src": "/assets/icons/icon-192x192.png",
		"sizes": "192x192",
		"type": "image/png"
	  }
	]
  }

There are a few more options that may or may not be used depending on the environment where your PWA is installed. At a minimum, the above values will give you all you need. To learn more about all web manifest values and their options, check out the MDN article on the specification.

To add the web manifest to your site, enter the json object into a file named manifest.json and upload it to the site root. Then, in the main page of your site, use a link tag in the header to point to the file:

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

Register A Service Worker

The service worker is at the core of every PWA. Service workers are javascript files which contain event handlers and run in the background, in a separate thread from your front-end javascript. They allow you to listen for events like network requests, push notifications, and going online/offline. The service worker intercepts these events even when the browser is not open.

But here’s the dirty little secret of service workers and PWAs: The service worker doesn’t have to do anything to qualify your site as a PWA, it simply needs to be registered. A blank file is all you need. Simply create a blank serviceworker.js file and upload to the site root! Now, the tricky part is registering your service worker. This requires a few lines of javascript on your main html page:

if ('serviceWorker' in navigator) {
	window.addEventListener('load', () => {
		navigator.serviceWorker.register('service-worker.js').then(registration => {
			console.log('SW registered: ', registration);
		}).catch(registrationError => {
			console.log('SW registration failed: ', registrationError);
		});
	});
}

I like to check first to see if the serviceWorker property of the navigator object is available. This step isn’t required and browsers that don’t have it will usually fail gracefully. Add a listener for the browser’s load event and call navigator.serviceWorker.register(), which accepts the relative path to your service worker file as a parameter and returns a promise. Handling the promise function is optional but I’ve added some log statements as an example.

Naturally, you’ll want to beef up your service worker with all kinds of features. But for the bare minimum, to get an install prompt, this is all you need. If you’re interested in adding offline support, I highly recommend the tool Workbox. Workbox offers a whole suite of caching strategies, as well as a wizard which will crawl through your site and set up your initial cache automatically.

Optional Step: Trigger The Install

Some browsers will prompt to install automatically, while others require some coaxing. Desktop Chrome, for example, requires a user interaction to trigger the install prompt while mobile Chrome is automatic. Fortunately, handling the install prompt is easy.

Whether installing automatically or manually, when the browser deems your site ready to install, it will fire a “beforeinstallprompt” event. In the case of browsers that require a user interaction, you need to capture this event for later use.

let deferredPrompt;

window.addEventListener('beforeinstallprompt', (e) => {
	// Store the install prompt event
	deferredPrompt = e;
});

In the above example, the install prompt event is stored in the global variable “deferredPrompt”. Once you have it, all you have to do is call its prompt() method. We’ll call it in a button click event, which satisfies Chrome’s user interaction requirement:

// Add a click handler to a button with id="install"
document.getElementById('install').addEventListener('click', (e)=>{
	// Show the prompt
	deferredPrompt.prompt();
});

Conclusion

The bare minimum requirements are quite easy to implement in any website. However, this article is meant to be a starting point for your PWA. There’s an entire philosophy around how to approach building Progressive Web Apps. I’ll post an article about exactly that next month. As you implement your PWA, consider offline access, background syncing, and push notification features and how they may apply to the future of your website.

Share on LinkedInTweet about this on TwitterShare on FacebookShare on Google+