This is not a primer on what a create-react-app or service worker is. This post assumes prior knowledge of both.

So, I recently had the opportunity to work on a React project that involved publishing the resulting web application as a Progressive Web Application (PWA).

I realized how much of a struggle it is to get a PWA with custom routes configured inside a Create React App (CRA) build. Hope this helps someone stuck in a similar situation.

PWA in create-react-app
How can we actually run a PWA inside our CRA shell?

Now, the CRA shell bundles a service worker by default. You may have noticed that in a basic CRA shell, inside the index.

You can create a new CRA app and look inside the RegisterServiceWorker file.

This looks complicated enough, but it’s really just checking to see if the environment variables are set for a production build and whether ServiceWorker is supported in the current browser.

If you run a build with the yarn build command, you can open the build folder and check inside to see that a service-worker.js file has been generated. This is the default service worker file CRA generated for you.

The formatting of the file is inline ES5 JavaScript, which makes it a bit hard to read. But you can dump it into any pretifier, and you should see a more legible file.

Looking at the above file you will know that it is only creating a static cache with the following cache name: sw-precache-v3-sw-precache-webpack-plugin-+(selg.registration ? self.registration.scope). It then caches all your static files like index.html and your js and css files inside that cache.

You should also check out a fetch event listener in there that catches a fetch event and checks to see if the app is requesting one of the already cached static assets.

Now comes the million dollar question: what if you want to configure dynamic cache for a specific route? In short, a cache that will update itself with the data sent from the server when the user traverses a specified route. Note that this means that the data will not be available at build time, and therefore cannot be cached by the default service worker generated.

Limitations of Default PWA in CRA
Unfortunately, the above is not very easy to accomplish when using a CRA. Unless you’re willing to evict of course.

Take a look at these GitHub issues and see why the team at CRA won’t support customizing the default service worker.

So, given that we cannot customize the default service-worker, how do we work around it?

Understanding How a CRA Generates a Service Worker
The first step in finding a workaround for a build system is to really understand how the build system works.

So, let’s start with the library that the build system uses to generate the service worker file.

sw-precache is a library that allows you to generate a service worker file based on a template. The template file is written using Underscore’s templating engine.

Here’s a link to the template file in the SW-precache source code.

Again, the template file looks complicated, but once you manage to get your head around the templating language it’s fairly straightforward.

overriding default service worker
Now, how can we override the above process to allow our custom service worker file to be generated?

The answer is based on Jeff Pausnick’s (self-precached’s maintainer) Stackoverflow answer.

First, we need to run thesw-precache CLI after the normal build process.

Install the sw-precache library by running the following command: npm install –save-dev sw-precache

Now, the sw-precache library runs on a config file, which is provided via an option on the CLI. This command is: sw-precache –config=sw-precache-config.js , where sw-precache-config.js is the name of the config file.

Leave a Reply

Your email address will not be published. Required fields are marked *