Custom Offline Pages With Service Workers

2019-07-08PWAs3 min read

Here comes the dreaded dinosaur
Here comes the dreaded dinosaur
Today, I learned about eliminating the dinosaur. Everyone's tired of him. I think he's even tired of himself.

So.

Instead of showing a dinosaur to our precious users, we'll show them a beautiful page telling them to turn on their internet.

This is possible with Service Workers and the cacheStorage API. I assume you have basic knowledge of the service worker life cycle. If you don't, reading this first will help you get the most of this post.

We'll have a serviceWorker.js file, an index.js file that registers the service worker and an index.html file that includes the index.js.

Here's the code that'll respond to the fetch events (Add to serviceWorker.js).

self.addEventListener('fetch', event=> {
    event.respondWith(
        fetch(event.request).catch(()=>{
            return new Response(
                `<h1>Sorry you are offline</h1>`
                `<p>Try restarting your wifi or something</p>`
                {headers:{"Content-Type":"text/html"}}
            )
        })
    );
});

Here's what we're doing

  1. We first listen for fetch event. When a service worker has been activated (has scope over a page) every request goes through the service worker's fetch event.

  2. We call the respondWith method of the event object which accepts a promise resolving with the response. We use the fetch API which also returns a promise.

  3. The fetch() function tries to retrieve the original request sent by the browser. The event.request has all the details (headers etc) of the request by the browser. The fetch function resolves a promise if the request was able to go through (the user was connected to the internet).

  4. If the user is not connected to the internet, the promise is rejected, the request fails and the catch block is executed. It returns a new Response object on the fly. The Response function takes the content of the response as the first argument and the configuration as the second object.

Image of our site offline. Ewww, so undesirable
Image of our site offline. Ewww, so undesirable

But let's imagine we're not that primitive and want to serve beautiful pages when our users are offline.

If you aren't familiar with the service worker lifecycle, this is a nice time to be, read about them here and I'll wait for you. If you have done so, onwards

If you read that article, you should know how to add stuff to the cacheStorage. In the next example, we'll check if a user is offline and give them an offline.html we've stored in the cache. This time, it'll be beautiful because we made it just for them.

Replace the fetch event handler with this code

self.addEventListener('fetch', event=>{
    event.respondWith(
        fetch(event.request).catch(()=>{
            return caches.match('offline.html')
        })
    );
});

So there we have it. caches.match searches the cache to return a promise that resolves with our response containing offline.html which was stored in the cache. If everything works well, then hurray, we have a beautiful page when our users are offline.

Thanks for readingšŸ˜Š.