Making react-europe.org work offline with Service Workers and free SSL from Cloudflare

Now that Chrome for Android officially supports service workers, I thought it would be a good idea to make react-europe.org and conference sites using EventLama, that way we wouldn't need to build a conference app or at least we could offer an alternative.

First, in case you don’t know, Service Worker is a new technology based on web workers, so it doesn’t have direct access to the DOM and works in the background. It gives direct access to the fetch API and allows cool stuff such as push messages, background sync, and geofencing. In our case, we are just using it for offline support. It’s already being used by Facebook, ebay and others.

Here’s how we did it:

First thing you need to make Service Workers work is an SSL certificate.

If you’re using github.io, that’s a no brainer but it doesn’t work with custom domains. If you’re on your own server, you can use Let’s Encrypt for free certificates, the only problem is that it’s not quite ready yet. So you need to either find a cheap SSL or buy one for $50 or so. However, there’s a free trick pointed out to me by Thibaut Assus. You can get SSL for free with cloudflare. It’s very easy, just create an account, add your domain and point your dns to cloudfare’s (just keep clicking on Continue in their wizard). Once this is done, you need to click on the Crypto icon on the top menu:

Now scroll to the SSL section and select Full:

Save your settings. Congrats, you now have free SSL and caching for your domain!

Ok, back to Service Workers. So, as I mentioned, Service Workers run in some kind of web worker in the background, this means it needs to be in its own file. So, in your main javascript file, you need to call your service worker like this:

if (‘serviceWorker’ in navigator) { navigator.serviceWorker.register(‘sw.js’).then(function(registration) {

// Registration was successful

console.log(‘ServiceWorker registration successful with scope: ‘, registration.scope); }).catch(function(err) {

// registration failed ☹

console.log(‘ServiceWorker registration failed: ‘, err); });
}

Pretty simple so far. This will call https://yourdomain.com/sw.js and execute it in the background. The API for the service worker is pretty low level but very flexible, here’s hoping someone writes a nice wrapper around it. For the caching, I just reused this code from a chromium demo, not pasting the whole thing here but you can read it here, it’s well documented:

https://github.com/react-europe/www/blob/cfp/app/sw.js

Basically, it listens for various events, such as install, activate and fetch and it caches the whole thing for you with the cache.addAll() API. It then reads from the cache with the caches.open() function that allows easy versioning. Pretty cool stuff.

Ok, so now https://www.react-europ.org works offline, yay! Well at least it does on Chrome and Firefox nightly. Let’s go shopping for a polyfill now. Google returns this one as first result: https://github.com/coonsta/cache-polyfill, unfortunately after looking at the code, it only polyfills a few caching apis, it still expects your browser to support service worker in the first place. After a few minutes of googling, I give up and decide to harass el señor Service Worker on twitter, that is Jake Archibald:

To which he replied:

Silly me, here I was thinking polyfills were for new features. Ok so ServiceWorker only works on new browsers, bummer. Well, I can understand the push api part, but I thought the offline part was polyfillable (is that a word?). I guess I’m back to AppCache then for other browsers. Having heard of many horror stories, I didn’t want to waste more time on this so after a few googling, I just executed this peace of code in the chrome inspector on react-europe.org, this generated a fancy manifest file ready to use, yay.

However, I still wanted to use service workers for browsers that did support it. Luckily, I found this appCacheNanny that will load your appcache manifest dynamically. So I ended up loading it this way:

if (‘serviceWorker’ in navigator) { navigator.serviceWorker.register(‘sw.js’).then(function(registration) {

// Registration was successful

console.log(‘ServiceWorker registration successful with scope: ‘, registration.scope); }).catch(function(err) {

// registration failed ☹

console.log(‘ServiceWorker registration failed: ‘, err); });
} else {

appCacheNanny.start({checkInterval: 1800000});
}

Finally, react-europe.org should be available offline on most devices now, which is always handy as many non-French attendees coming to the conference will not have a data connection on their phone while in Paris. Another good thing is that all the other events created on eventlama.com will also benefit from offline support using service workers from now on.