Creating Custom Service Worker in React Apps
Learn to add custom service worker code in your
react projects created using Create React App.
The project code is available at GitHub
It's Harit from bonsaiilabs. Today I will show you how you can add custom service worker code in your react projects created using Create React App.
I have created a project using
create-react-app and call it
cra-custom-serviceworker. I have made changes to 2 files so let's view them first.
First, I have replaced the default implementation of
App.js with my own implementation. This implementation contains 2 parts, a form and a
userInfo in the table.
This form contains 1 text input and a button called
Submit. I will shortly show you how this looks. When the user types into the box,
handleChange method is called, which sets the value into the state. I have made use of React Hooks to keep the the state in the name variable whose default value is an empty string.
When a user clicks the
handleClick is called. It is logging a message on the console and I will soon call Github API to fetch the data and set the
userInfo is then used in the render to present the information in the table.
I have also updated
App.css to change the look and feel of the form. I have this app running locally, and we can see how it looks currently at
http://localhost:3000. When I fill the my github username and click the button, a message is logged on the console as expected.
I will now change the implementation of
handleClick. I will call
fetch with the Github API and pass on the
name provided by the user. I will call
.then() method to capture response and return the result by calling
json() method. I will use another
.then() method and here I will have access to data returned by Github API. I will call the
setUserInfo() method which will fill the
userInfo object. Let's go back and test!
Back in the browser, I will refresh the page and enter my github username followed by clicking the button. As we can see, now the data is populated for my github username. I change the username to bonsaiilabs and the data renders the information for this user.
Now, let's say you want to intercept all the
fetch() calls made to the network. Note that these fetch calls also include fetching resources such as icon files in your project. One way to do that is to use service worker and listen for the
fetch event in your app. Let's see how to do that in a react app created using create-react-app
Back in our project, we can see a file called
serviceWorker.js which comes with create-react-app. This file is NOT the service worker file, it is a template that will be used in the build process to create a service-worker file. I will show you a generated service worker file shortly. For now, this template file contains 2 methods called
unregister(). These methods are used to register and unregister a service worker in the project. If you navigate to
index.js, you'll see that currently service worker is not registered. Let's change this to
register(), and see if service worker shows up.
Back in the browser, I hit refresh and navigate to Application Panel of Chrome Dev Tools, but we do not see the service worker here. That's because when you are using the app created with create-react-app, you must create a production build to see a registered service worker.
Back in the terminal, I will create a production build using
npm run build. Once it completes, I will use
serve -s build to serve the production bundle. Hmm, I do not have serve installed, so first I will install serve using
npm install -g serve command. Once it completes, I will run
serve -s build command and this time our app is running on port
5000 instead of
Back in the browser, I will change the port and here you see service worker with number
0 activated and running. And, our app is still running as expected.
Back in the codebase, the generated service worker file is created in
build directory when I ran
npm run build and it is called
service-worker.js. If you look at the content of this file, you will see that is says it's an auto-generated file, and warns not to update it. Hmm, so where shall we write our service worker code to intercept
For that, I will create a new file under
src directory, called
custom-service-worker.js. In this file, I will add an eventlistener on
self will refer to the service worker once this code is placed in our generated service worker file. I will show you how, in the next step. Here, I will called
self.addEventListener() method and listen for
fetch event, I will provide a callback which receives a fetch event, and with that event I log the request method and URL of the request.
Now, to include this code in our generated
service-worker.js, I will change our
build command located in
package.json. I will append the contents of
build/service-worker.js file. Then, I will create another production build by executing
npm run build command, and run it using
serve -s build command. We are now ready to test.
Back in the browser, I will first empty the cache and do a hard reload, but this did not load our new service worker changes, it is still sitting at number
0. I will try to reload few more times, before I see a message as below
New content is available and will be used when all tabs for this page are closed.
For that, I will open up a new tab, close the existing tab, and open out app at port
5000. As you can see, it started intercepting all the
fetch requests. When I now enter github usernames and click submit, we can see the data, and that our custom service worker intercepts these fetch request as well.
Also, we can see our custom service worker code in the generated
service-worker.js file as you navigate the build folder and scroll all the way at the bottom of the file.
Fantastic! so you now know how you can write a custom service worker with react projects created with
Let us know if you have more topics that you would like us to cover and we will work on them to help you learn better.
See you next time!