So you've build your website. Whether that is a React app, a Vue app or a good old HTML site, well done. You should be proud of it. Think back to when you wrote your first line of code, now you have a website. It's online and other people can see it.
However the website only works when you are connected to the Internet. If your users lose connection then they will see that chrome dinosaur instead of your lovely site.
So what's your solution? Do you accept the status quo? Is an offline website even possible?
Indeed it is! Progressive Web Apps(PWAs) are your solution.
What are Progressive Web Apps?
Progressive Web apps are Web applications that can act like native apps. Using 2 files, your website can have push notifications, offline mode and become downloadable like an app. These 2 files are called a service worker and a manifest JSON file.
Service worker
The first file you need is a service worker which is a Javascript file that is the brains of the PWA. You'll need to register it by adding a script tag in your base HTML and adding this code.
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js')
.then(function(registration) {
console.log('Service worker started');
})
.catch(function(error) {
console.log('Service worker failed, error:', error);
});
}
In your seperate service-worker.js
file, you'll need 2 blocks of code.
self.addEventListener('install', (event) => {
// run caching when installing service worker.
});
self.addEventListener('activate', (event) => {
 // After install and all active pages have been closed, this will run.
});
Now you have a starter code for your PWA. Look up some of the remaining code to add the functionality.
Manjest.json
The manifest.json file is similar to a package.json file in a node project. It contains some information about the website like name, background color and icon. For the full list see here on MDN. This file defines some of the Web apps meta data such as what the website icon will be when you download it.
Add <link rel="manifest" href="/manifest.json">
into the head element of the root HTML file to link the website to it and add your icon to an images folder.
{
"short_name": "My Example PWA",
"name": "Example PWA",
"start_url": "/index.html",
"background_color": "#1c5680",
"display": "standalone",
"theme_color": "#1c5680",
"icons": [
{
"src": "/images/icon.png",
"type": "image/png",
"sizes": "128x128"
}
]
}
Making an offline page
const custom_offline_page = "offline.html"
self.addEventListener('install', event => {
event.waitUntil(
caches.open('CacheName').then((cache) => {
return cache.addAll([
custom_offline_page
])
})
)
})
self.addEventListener("fetch", (event) => {
event.respondWith(
(async () => {
try {
// Fetch request from network
const networkResponse = await fetch(event.request)
return networkResponse
} catch (error) {
// Error thrown when a user has no internet connection
const cache = await caches.open('CacheName')
const cachedResponse = await cache.match(custom_offline_page)
return cachedResponse
}
})()
)
})
And you now have an offline page.
Testing it works
In chrome, open up the dev tools and go to the lighthouse tab. You can run an audit. One of the tick boxes is PWA. Run the audit and this will reveal any problems if you have any.
You can also check the application
tab in dev tools to see the manifest json and to see if a service worker has successfully been registered.
To say thank you, you could buy me a coffee?
If you have any questions or issues, drop them in the comments below. I'd be more than happy to help
Resources: