If you’re familiar with Express, sw-toolbox supports URL patterns using a similar syntax to its routing syntax.

toolbox.router.get('img/**/*.{png,jpg}', global.toolbox.cacheFirst);

This will intercept GET requests for any PNG/JPG file under the img folder. It handles requests according to the cacheFirst strategy, first checking the cache for a response. If that fails, the request gets sent to the network. If that succeeds, the response gets added to the cache.

Full domains can also be used here, e.g this will cache your Google Fonts:

toolbox.router.get('https://fonts.googleapis.com/', toolbox.cacheFirst);

We can also intercept GET requests to another domain using Express-style routing. We just define an ‘origin’ property in our options (a string or RegExp) which gets matched against the full origin of the URL.

toolbox.router.get('/(.*)', global.toolbox.cacheFirst, {

origin: /\.googleapis\.com$/

});

A RegExp object can also be used. Here we’re defining a route for POST requests that start with “https://www.googleapis.com”:

toolbox.router.post(/^https://www.googleapis.com\//, global.toolbox.networkFirst);

Tip: When inspecting Cache Storage, you can differentiate what sw-toolbox is caching as it manages the $$$toolbox-cache$$ namespace.

More granular control

sw-toolbox also gives us the ability to granularly control caching characteristics. In addition to specifying an origin, we can also customize the cache as follows:

We give it a name (“products”)

We give it a maximum size of 12 items (using the maxEntries parameter)

We set the content to expire in a day (24 hours = 86400 seconds)

toolbox.router.get('/(.*)', global.toolbox.cacheFirst, {

cache: {

name: 'products',

maxEntries: 12,

maxAgeSeconds: 86400

},

origin: /\.products\.com$/

});

You can find tutorials on sw-precache & sw-toolbox in our Progressive Web Apps Instructor Led training material.

Offline Google Analytics

As mentioned earlier, offline Google Analytics can relay analytics requests a user performed offline when a network connection is available again. To add this to your Service Worker involves just two lines of code:

// Import offline analytics into the SW global scope:

importScripts('path/to/offline-google-analytics-import.js'); // initialize it

goog.offlineGoogleAnalytics.initialize();

Boom. That’s it!

It’s also possible to supply an object with custom parameters that will be included with each request that is replayed:

goog.offlineGoogleAnalytics.initialize({

parameterOverrides: {

cd1: 'Guacamole',

cd2: 'So much cheese'

}

});

Note: the main use case for passing in an object of parameter overrides is detecting when hits are sent normally (vs replayed by Service Worker).

Autotrack.js

Setting up Autotrack is relatively straight-forward. In addition to including analytics.js in your page, also async load in the Autotrack library. Next, update your default tracking code to require any Autotrack plugins needed:

<script>

window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;

ga('create', '<!-- your google_analytics_tracking_id -->', 'auto'); // Autotrack plugins available

ga('require', 'cleanUrlTracker');

ga('require', 'eventTracker');

ga('require', 'maxScrollTracker');

ga('require', 'outboundLinkTracker');

ga('require', 'pageVisibilityTracker');



ga('send', 'pageview');

</script>

<script async src='

<script async src='/public/js/autotrack.js'></script> ga('require', 'urlChangeTracker');ga('require', 'cleanUrlTracker');ga('require', 'eventTracker');ga('require', 'maxScrollTracker');ga('require', 'outboundLinkTracker');ga('require', 'pageVisibilityTracker');ga('send', 'pageview'); https://www.google-analytics.com/analytics.js'</a> >

Note: Some of the Autotrack.js plugins work without specifying configuration options (e.g outboundLinkTracker) while others don’t (e.g clearUrlTracker). Be sure to check the docs to see what options the various plugins take :)

Selenium Assistant

As mentioned, Selenium Assistant helps us get a list of browsers available on our machines, get a web driver instance for them and then run some tests.

You install the Web Driver modules for browsers you want to test (npm install chromedriver etc) and can then iterate through the list of these browsers and control them as needed. The assistant also works great with Sauce Labs, should you need to test browsers that aren’t installed on your local system.

Firebase Cloud Messaging

After adding Firebase to an existing project, there are a few extra steps involved in adding support for Web Push notifications:

1. Add the FCM gcm_sender_id to your Web Application Manifest (manifest.json) file:

"gcm_sender_id": "103953800507"

2. Create a new firebase-messaging-service-worker.js file. We’re going to give

it access to FCM by importing the Firebase Messaging libraries into this file:

Then initialize the Firebase app in Service Worker. Pass your

messagingSenderId (from Firebase Project Settings) to do so:

firebase.initializeApp({

'messagingSenderId': '<-- your sender ID goes here -->'

});

Next, retrieve an instance of Firebase Messaging to handle background

messages:

const messaging = firebase.messaging();

and request permission to show notifications. You may want to wait until

an appropriate time to do rather than doing this when the page boots up:

messaging.requestPermission()

.then(function() {

console.log('Notification permissions granted.');

// ...

})

.catch(function(err) {

console.log('Permission denied', err);

});

Now when the user receives a message from FCM, a notification is displayed

if they granted permission to enable this.

What’s next?

We’re currently working on the next big version of our Service Worker libraries, expanding our explorations to also cover Background Sync, Service-Worker based HiDPI image-switching and smarter analytics for PWAs. We look forward to sharing more as beta releases for these libraries become available.

We’re also planning on a new post over on our Sustainable Loading channel talking about Service Workers in production on Google.com.

Until then, we hope our libraries prove useful, regardless of whether you’re building a PWA or just trying to improve performance on your site :)

With thanks to the awesome members of our team — Jeff Posnick, Matt Gaunt, Taylor Savage, Joe Medley, Prateek Bhatnagar, Lucas Mullens, Phil Walton, Alex Russell and former member Mat Scales for their contributions to our small family of open-source libraries.

Resources