Skip to content
Advertisement

How should I configure workbox to support offline caching of third party requests?

I am currently using the workbox-build module, specifically the generateSW mode, to generate my service worker scripts to deploy my web application to Netlify. My site is a static site.

Here is my worker-config.js:

module.exports = {
    globDirectory: '_site/',
    globPatterns: [
        '**/*.{html,iml,css,xml,eot,svg,ttf,woff,woff2,jpg,webp,png,ico,xcf,js,json,txt}'
    ],
    swDest: 'sw.js',
    ignoreURLParametersMatching: [
        /^utm_/,
        /^fbclid$/
    ],
    offlineGoogleAnalytics: true,
    mode: 'production',
    navigateFallback: '/index.html'
};

This configuration works well for online use. However, third party requests to certain assets (i.e. images, Javascript, etc.) are not successfully precached for offline usage. Netlify deploys assets that go through their optimization and minification process into their CloudFront CDN. I have no other feasible option but to use the Netlify optimization and minification process for Javascript, HTML, and image assets. Unfortunately, these CDN assets are not precached. Consequently, a user who uses my web application without network access will not find these CDN assets precached and do not load into the cache like the other non-CDN assets.

What do I need to do to ensure third party CDN assets are correctly precached when using the workbox-build module? I definitely want to keep things simple and I hope the fix is to make simple changes to the work-config.js file.

Advertisement

Answer

Since you don’t know the URLs in advance, at build time, your only option is to employ runtime caching to match the requests for the URLs, and apply a specific caching strategy to generate responses.

There are some gotchas/best practices that you can read about in “Smarter runtime caching of hashed assets,” but the summary is that you’ll need to employ some sort of expiration policy to your runtime caching in order to avoid your caches filling up indefinitely when new URLs are added.

Here’s how you could configure generateSW to add in runtimeCaching, using the more basic ExpirationPlugin method of controlling cache sizes:

module.exports = {
  // ...other options...
  runtimeCaching: [{
    urlPattern: ({url}) => url.origin === 'https://d33wubrfki0l68.cloudfront.net',
    handler: 'CacheFirst',
    options: {
      cacheName: 'cdn-assets',
      expiration: {
        // Adjust the number of entries to keep as needed.
        maxEntries: 50,
      },
    }
  }],
  clientsClaim: true,
};

You should note that with runtime caching, the assets won’t start being added to the cache until the subsequent visit, after the initial time a service worker is registered, since most of them will have already been loaded by the time the service worker takes control. Using clientsClaim: true will cause a service worker that’s registered for the first time to take control of the page that registered it immediately, which increases the chances that some assets loaded at runtime might be cached, but generally speaking, it’s only the next navigation that will end up populating the cache.

Advertisement