Building an Offline Page for Theguardian.com

You’re on a put together to work and likewise you originate up the Guardian app on your phone. A tunnel surrounds you, but the app quiet works in very noteworthy the identical manner as it generally would—despite your lack of web connection, you quiet obtain the fleshy abilities, only the advise material shown would possibly be frail. Must you tried the identical for a web salvage of abode, on the opposite hand, it wouldn’t load in any appreciate:

Chrome eases the difficulty of being offline with its hidden game (press situation bar on desktop, tap the dinosaur on cellular). However we can attain greater.

Carrier workers enable web salvage of abode authors to intercept all network requests to their websites, meaning we can present rich offline experiences, factual cherish native apps. At the Guardian, we lately released a custom offline abilities of our salvage. When users are offline they’ll search a Guardian branded page with a straightforward offline message and, for stress-free, a crossword to play while they look forward to a connection. This blog put up is ready how we built it, but first, here’s the contrivance you would possibly presumably well even strive it out for yourself.

Strive it out

You would possibly presumably well salvage to be running a browser that helps the Carrier Employee and procure APIs. At the time of writing only Chrome (cellular and desktop) helps both of APIs, but improve is coming in Firefox very soon (at the second in the nightly make), and all browsers other than Safari salvage shown enthusiasm. Furthermore, provider workers can only be registered for websites served over HTTPS, which theguardian.com has started to cross towards. Thus, we can only offer the offline abilities for HTTPS sections of the procure salvage of abode. In the intervening time, we salvage chosen the developer blog as our testing ground. So, when you happen to’re reading this on our developer blog share of the procure salvage of abode, you’re in luck.

Whereas you’ve visited a page on our developer blog in a supported browser, you’re all salvage of abode. Disconnect your instrument from the procure and refresh. Must that you just would possibly presumably be unable to exhaust a salvage a study it out for yourself, exhaust a salvage a study this demo video.

The contrivance it in actuality works

We are in a position to reveal browsers to register our provider worker as soon as the user arrives on the page with some straightforward JavaScript. Toughen for provider workers is at the second sparse, so we want to make expend of purpose detection to retain away from any errors.

if (navigator.serviceWorker) {
    navigator.serviceWorker.register('/provider-worker.js');
}

As segment of the provider worker’s set up match, we can expend the fresh cache API to cache the many absorbing components of our web salvage of abode, akin to HTML, CSS, and JavaScript:

var staticCacheName = 'static';
var version = 1;

purpose updateCache() {
    return caches.originate(staticCacheName + version)
        .then(purpose (cache) {
            return cache.addAll([
                '/offline-page.html',
                '/assets/css/main.css',
                '/assets/js/main.js'
            ]);
        });
};

self.addEventListener('set up', purpose (match) {
    match.waitUntil(updateCache());
});

As soon as set up has finished, the provider worker can hear to and alter the procure match, giving us fleshy alter over all future network requests incurred by the procure salvage of abode.

self.addEventListener('procure', purpose (match) {
    match.respondWith(procure(match.build a question to));
});

To come up with some idea of the flexibleness we salvage here, we would possibly produce our salvage response programmatically:

self.addEventListener('procure', purpose (match) {
    var response = fresh Response('

Howdy, World!

',         { headers: { 'Mumble material-Kind': 'text/html' } });     match.respondWith(response); });

Or, we would possibly acknowledge with one thing from the cache if we can derive a match for the given build a question to, falling help to the network:

self.addEventListener('procure', purpose (match) {
    match.respondWith(
        caches.match(match.build a question to)
            .then(purpose (response) {
                return response || procure(match.build a question to);
            })
    );
});

So how attain we expend all of this to present an offline abilities?

Initially, the HTML and resources wanted for the offline page are cached by the provider worker upon set up. Incorporated in this cache is the React utility we salvage developed for our crossword pages. Thereafter we intercept all network requests to a online page material on theguardian.com, including requests for subresources on those pages. The good judgment for handling these requests goes one thing cherish:

  1. If we detect the incoming build a question to is a navigation to one of our HTML pages, we constantly need to attend basically the most modern advise material, so we strive to produce the build a question to over the network to the server.
    1. As soon as we obtain a response from the server, we can acknowledge with that without delay.
    2. If the network build a question to throws an error (i.e. failed since the user is offline), we pick this and as a substitute acknowledge with the cached HTML for the offline page.
  2. Else, if we detect the build a question to is the relaxation rather than HTML, we can lookup the build a question to in the cache.
    1. If a cached match is came across, we can acknowledge with that without delay.
    2. Else, we can strive to produce the build a question to over the network to the server.

The following code, which uses the fresh cache API (as segment of the Carrier Employee API) and procure (for making network requests), is as follows:

var doesRequestAcceptHtml = purpose (build a question to) {
    return build a question to.headers.obtain('Accept')
        .crash up(',')
        .some(purpose (form) { return form === 'text/html'; });
};

self.addEventListener('procure', purpose (match) {
    var build a question to = match.build a question to;
    if (doesRequestAcceptHtml(build a question to)) {
        // HTML pages fallback to offline page
        match.respondWith(
            procure(build a question to)
                .pick(purpose () {
                    return caches.match('/offline-page.html');
                })
        );
    } else {
        // Default procure behaviour
        // Cache first for all other requests
        match.respondWith(
            caches.match(build a question to)
                .then(purpose (response) {
                    return response || procure(build a question to);
                })
        );
    }
});

That’s it! The general code for theguardian.com is originate offer on GitHub, so you would possibly presumably well even scrutinize the fleshy version of our provider worker script there, or in manufacturing at https://www.theguardian.com/provider-worker.js.

We have got correct reasons to be focused on these fresh browser technologies, because they would possibly even be frail to present websites the identical rich offline experiences we salvage in native apps as of late. Sooner or later when theguardian.com has finished migration to HTTPS, the offline page will amplify in significance and we can produce extra improvements to the offline abilities. Imagine opening theguardian.com on your web-less commute to work to search out advise material personalized for you, downloaded and cached by the browser forward of your visit. There just isn’t any friction taking into consideration the set up step—not like native apps which require users to salvage app retailer accounts for set up, all that’s wanted on the procure is to head to the procure salvage of abode in question. Carrier workers would possibly presumably well even moreover help give a enhance to web salvage of abode load events, as the shell of a web salvage of abode would possibly even be cached reliably, factual cherish in native apps.

Must you’re attracted to finding out extra about provider workers and what’s that you just would possibly presumably well even agree with, Matt Gaunt, who is a Developer Recommend for Chrome, has written an introduction to Carrier Employee which works into extra detail.

Read Extra