18

So create-react-app includes service worker functionality by default, which is lovely - all my static assets get cached for offline use out of the box. Cool, but now I want to take things a bit further and use indexedDB to cache some dynamic content.

Problem is, there's no service-worker.js file to modify. It gets generated during the build process.

Is there a way to add additional logic without ejecting create-react-app or redoing all the nice static caching stuff?

Daniel Loiterton
  • 5,073
  • 5
  • 33
  • 46
  • AFIK you'll have to eject your app before you can edit it's `service-worker` – BlackBeard Dec 05 '17 at 12:59
  • Try [Using Sass with Create React App (Without Ejecting)](https://hackernoon.com/using-sass-with-create-react-app-without-ejecting-b5f4f827ed9e), you can also follow [this post by medium.com](https://medium.com/@kitze/configure-create-react-app-without-ejecting-d8450e96196a) for additional details about Sass. For details about Sass, [here is some site](http://sass-lang.com/documentation/file.SASS_REFERENCE.html) you can add on your research. – MαπμQμαπkγVπ.0 Dec 06 '17 at 12:32

2 Answers2

17

As you've observed, create-react-app's config is locked down, and the service worker logic is entirely defined in the config.

If you'd rather not eject but you want some customization, another option is to modify the create-react-app build process to explicitly call the sw-precache CLI after the normal build has completed, overwriting the service-worker.js that create-react-app generates by default. Because this involves modifying your local package.json, it doesn't require ejecting first.

There's some info on this approach here, and the general idea is modifying your npm scripts to look something like:

"build": "react-scripts build && sw-precache --config=sw-precache-config.js"

With sw-precache-config.js configured based on your needs, but including

swFilePath: './build/service-worker.js'

to ensure that the built-in service-worker.js is overwritten.

Jeff Posnick
  • 53,580
  • 14
  • 141
  • 167
  • Ahaa... Thanks, Jeff. This looks promising. So using this approach, how would I then get my own code into the service-worker.js file? Looking at the sw-precache docs, perhaps something like the importScripts option? sw-toolbox looks promising also... am I on the right track? – Daniel Loiterton Dec 07 '17 at 10:41
  • 2
    Actually @Jeff, I just watched your [talk from ChromeDevSummit](https://www.youtube.com/watch?time_continue=2&v=DtuJ55tmjps) about [Workbox](https://developers.google.com/web/tools/workbox/). Looks awesome. Wonder if I can use something like `"build": "react-scripts build && workbox-cli generate:sw --config-file=workbox-config.js"` to override the service-worker.js file? – Daniel Loiterton Dec 07 '17 at 13:39
  • 1
    Yup, definitely. You could do that as well. – Jeff Posnick Dec 07 '17 at 15:47
  • See also: https://github.com/facebook/create-react-app/issues/9141 – Jeff Posnick Jun 22 '20 at 14:06
  • Hey jef, do you know how to combine two service-workers? I wanted to add notification capabilities to the PWA, but there isn't much resources tell how to to it. – Art Dec 02 '22 at 15:46
9

I had the same problem and without doing eject, I could replace the default service-worker with workbox-generated one to add runtime caching webfonts, api calls, etc.

  1. install workbox-build
  2. prepare src/sw-template.js to add your registerRoute calls
  3. prepare /build-sw.js to copy workbox file to 'build' folder and injectManifest
  4. modify package.json scripts to run above build-sw.js
  5. modify src/registerServiceWorker.js to replace the default one

You can find detailed file changes here.

bob
  • 2,674
  • 1
  • 29
  • 46