reactjsservice-workercreate-react-appfreshdesk

Add Service Worker to Create React App Project


I am installing a notification system called Subscribers with a project built with create react app. They ask the developer to download their service worker and include it in the root directory of the project. I have never had to install / use a service worker before, which is most likely the root of my misunderstanding.

How do you add a service worker into the root directory of a React project? The instructions say the service worker should appear in the root directory as https://yoursite.com/firebase-messaging-sw.js. In an attempt to register that URL, I included a service worker under src/index.js:

import Environment from './Environment'

export default function LocalServiceWorkerRegister() {
    const swPath = `${Environment.getSelfDomain()}/firebase-messaging-sw.js`;
    if ('serviceWorker' in navigator) {
      window.addEventListener('load', function() {
        navigator.serviceWorker.register(swPath).then(function(registration) {
          // Registration was successful
          console.log('ServiceWorker registration successful with scope: ', registration.scope);
        }, function(err) {
          // registration failed :(
          console.log('ServiceWorker registration failed: ', err);
        });
      });
    }
}

In production, I receive a 404 error. I have tried placing the firebase-messaging-sw.js file in the root directory, and under the src folder. Same error each time.

Here are the instructions from Subscribers: https://subscribers.freshdesk.com/support/solutions/articles/35000013054-diy-installation-instructions


Solution

  • The public folder is the provided 'escape hatch' for adding assets from outside of the module system. From the docs:

    If you put a file into the public folder, it will not be processed by Webpack. Instead it will be copied into the build folder untouched. To reference assets in the public folder, you need to use a special variable called PUBLIC_URL

    So, once copied to the public folder, you would reference the file like this:

    import Environment from './Environment'
    
    export default function LocalServiceWorkerRegister() {
        const swPath = `${process.env.PUBLIC_URL}/firebase-messaging-sw.js`;
        if ('serviceWorker' in navigator) {
          window.addEventListener('load', function() {
            navigator.serviceWorker.register(swPath).then(function(registration) {
              // Registration was successful
              console.log('ServiceWorker registration successful with scope: ', registration.scope);
            }, function(err) {
              // registration failed :(
              console.log('ServiceWorker registration failed: ', err);
            });
          });
        }
    }