Recently, I was in a situation that required workbox integration for background sync in an application. After some trial, error and success, I decided to write this article to demonstrate the easiest way I’ve found to integrate workbox with create-react-app.
This article assumes basic knowledge of create-react-app, workbox and the react framework, as we will be using some terminology associated with these technologies. There’s no need to be a pro, beginner-level knowledge should suffice.
1. Update serviceWorker.js
The first step is updating the serviceWorker.js
file within the src folder. We will be updating the register function. At the moment, it looks like this:
export function register(config) {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
return;
}
window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC\_URL}/service-worker.js`;
if (isLocalhost) {
// This is running on localhost. Let's check if a service worker still exists or not.
checkValidServiceWorker(swUrl, config);
// Add some additional logging to localhost, pointing developers to the
// service worker/PWA documentation.
navigator.serviceWorker.ready.then(() => {
console.log(
'This web app is being served cache-first by a service ' +
'worker. To learn more, visit https://bit.ly/CRA-PWA'
);
});
} else {
// Is not localhost. Just register service worker
registerValidSW(swUrl, config);
}
});
}
}
We’re going to update the following line:
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
To:
const swUrl = `${process.env.PUBLIC_URL}/custom-service-worker.js`;
This will allow us to create and register our own custom service worker file named custom-service-worker.js
. You can name this whatever you like.
If you’d like to be able to test this in development, disable the production environment check in the following line:
if (process.env.NODE\_ENV === 'production' && 'serviceWorker' in navigator)
2. Create a custom service worker file
The next step is creating the custom service worker file in the public folder of our application. This should match the name we used in step 1. In our case, ‘custom-service-worker.js’
We can import and use workbox from here:
importScripts('https://storage.googleapis.com/workbox-cdn/releases/5.1.2/workbox-sw.js')
if (workbox) {
console.log(`Yay! Workbox is loaded ![🎉](https://cdn.hashnode.com/res/hashnode/image/upload/v1649114039486/kFdciRh2-.png)`);
} else {
console.log(`Boo! Workbox didn't load ![😬](https://cdn.hashnode.com/res/hashnode/image/upload/v1649114040812/CRViTXRw3.png)`);
}
Once Workbox is loaded from the CDN, a workbox object is created allowing us to make use of the workbox API.
We can self-host workbox by downloading the files into a folder in our public folder in one of 2 ways:
Note that workbox will cache all modules referenced when loaded through the CDN. These modules will then be available for offline use after the first time they are referenced.
Therefore, you do not need to host workbox yourself if this is your concern.
In order to load workbox if we’re self hosting, we will need to do the following:
importScripts('/third_party/workbox/workbox-sw.js');
workbox.setConfig({
modulePathPrefix: '/third_party/workbox/'
});
In this instance, the workbox folder is contained within the third_party folder inside our application’s public folder.
Now we can finally use workbox. We can use destructuring in order to access the different workbox modules:
const { backgroundSync, routing, strategies } = workbox
3. Register service worker
The final step is registering the service worker in our application. Navigate to the index.js file in the src folder and change the following line:
serviceWorker.unregister();
To:
serviceWorker.register();