loading...
Cover image for The easiest way to extend or customize Create React App service worker without ejecting

The easiest way to extend or customize Create React App service worker without ejecting

m3h0w profile image Michał Gacka Updated on ・2 min read

Create React App by default includes a Service Worker that will do some background magic for you in order for your app to be recognized as a Progressive Web Application. But if there's one pitfall of CRA, it's definitely how closed the configuration is and how difficult it is to modify / extend / customize it without ejecting (taking full control of the configuration) the application. Here, I discuss and present what I found to be the simplest way to extend the out-of-the-box service worker functionality. 

In my case, for the purpose of adding a background process to take care of firebase messaging for push notifications but this trick should work in any other case as well.

There's a multitude of articles trying to solve the problem but for some reason, most of them are overly complicated and are a pain to make them work in practice. That's because most of them overlook this wonderful utility: cra-append-sw. It lets you easily append the code you need to the existing service worker when building a production-ready app and also place a separate worker file in the public folder so you can register it yourself when running the development server.


It's as simple as installing the package, creating the service worker file in your main folder ('firebase-messaging-sw.js' in my case), and modifying your package.json file like this:

...
"start": "cra-append-sw --mode dev --env ./.env ./firebase-messaging-sw.js && react-scripts start",
"build": "cra-append-sw --env ./.env ./firebase-messaging-sw.js && react-scripts build",
...
Enter fullscreen mode Exit fullscreen mode

Also you need to remember to take care of registering the service worker when your application runs via a development server (CRA will only register its own service worker so in development, the separate file created in the public directory has to be registered separately). Here's a snippet out of my index.tsx file which is the entry point for my react application:

That should be all you need. Neat and simple in contrast to other hacky tools trying to accomplish the same.

One of the hardest issues to solve with these pipelines I've found was how to use environment variables within the service worker in order to configure the firebase access key and other secret variables I had in my .env file. This solution solves it because the code is ran through the webpack pipeline before it's outputted both in the normal mode and the dev mode. Meaning you can access the process.env object in your custom service worker code.

I hope this saves you some pain and you live happily ever after with your new service worker functionality included in your Create React App.

Discussion

pic
Editor guide
Collapse
avatar19710 profile image
Daniel Dopiriak

Wow, thanks a lot. I spent countless hours finding the right solution, and this one actually worked perfectly. :)

Collapse
ericyoung profile image
Eric Young

for those of us newer to service workers, it would be cool to show an example of your "firebase-messaging-sw.js" file.
Also, how you're handling requesting the user permissions would be nice to see.

Collapse
maged profile image
Abdelrahman Abdelhafez

Straightforward & incredibly helpful - thanks, Michał!