What’s a PWA?
A Progressive Web Application is a web application that leverages more of your host Operating System. It can work both online and offline, can synchronize data in the background, and use notifications.
In the browser it can act as a website, on mobile as a native app and on laptops and desktops as a desktop app.
PWA’s are locally installed websites, that can work fully detached from the internet. Therefor, their update flow to get the latest code and stat is also different.
Today I want to share a flow I use to inform users about the “what’s new” changes, even before they update their application.
The generic update cycle
When an application is an offline-capable PWA, the general update flow is as follows:
Step 1: Keeping a changelog
It is a good practice to keep a changelog of your application. Oftentimes this is done using a CHANGELOG.md
file in the code repository, in the format of “Keep a changelog“.
To make it easier to use this changelog for the application itself as well, I keep my changes using a YAML
file in the repo and have a script that converts this YAML file to a CHANGELOG.md
and a more technical changelog.json
file. In the JSON variant, I convert the time notation of the YAML file to UNIX timestamps, which I can use to see which changes the user has not seen yet.
Step 2: Ability to show the changelog in the application.
To show the changelog in the application, I will not bundle the changelog.json
with my application code. Because then the changelog will only change when the application changes.
This will be too late, because then the application is already updated, and the user would not be able to see “What’s new” before they update.
Instead, I bundle the changelog.json
into my service worker.
In the service worker, I place the contents as JSON into an app cache, using a fake URL.
I also register a fake URL as handler, to serve this JSON data from the cache.
So when a new service worker is installing
, I update the app cache.
The application can now fetch the new changelog contents with the ‘current’ service worker, and show the new changes.
Step 3: Keep track of ‘viewed’ changes
Using the same mechanic to store the changelog in the service worker, you can also use the service worker to manage when the user has seen the latest change. You should store the time of the last change though, not the time the user has seen it. Since the user could see the changes before your next release hits.
When you keep track of this inside the service worker, you can also use the Badging API to show a nice badge on your application, using navigator.setAppBadge(amountOfNewUpdates)
.
Be aware that the service worker only updates when you open the app already, so a badge will probably be to late. For desktop apps though, you can probably use the 🧪 Web Periodic Background sync API to place a badge and increase engagement from your users.
Step 4: Let the user install the update
There are a lot of good resources online how to achieve this (the technical details are too much for this post). In essential it boils down to:
- detecting the installation of a new service worker after registration
- capture the ‘waiting’ service worker
- tell your app that there is an update
- show an install button
- on click of this install button, send a message to the waiting service worker to ‘skip waiting’
- reload the page
For a good article on this, also with diagrams, checkout Handling Service Worker updates – how to keep the app updated and stay sane.
Happy updating!