Search code examples
reactjscreate-react-appservice-worker

Role of navigator.serviceWorker.controller in serviceWorker.js of Create React App


Below is an excerpt of serviceWorker.js generated by CRA.

What is the point of having if (navigator.serviceWorker.controller) inside if (installingWorker.state === 'installed')?

The new service worker has been successfully installed at this stage. Does the 'else' part handle the scenario in which no previous service worker has been installed yet?

navigator.serviceWorker
    .register(swUrl)
    .then(registration => {
      registration.onupdatefound = () => {
        const installingWorker = registration.installing;
        if (installingWorker == null) {
          return;
        }
        installingWorker.onstatechange = () => {
          if (installingWorker.state === 'installed') {
            if (navigator.serviceWorker.controller) {
              // At this point, the updated precached content has been fetched,
              // but the previous service worker will still serve the older
              // content until all client tabs are closed.
              console.log(
                'New content is available and will be used when all ' +
                  'tabs for this page are closed.'
              );

              // Execute callback
              if (config && config.onUpdate) {
                config.onUpdate(registration);
              }
            } else {
              // At this point, everything has been precached.
              // It's the perfect time to display a
              // "Content is cached for offline use." message.
              console.log('Content is cached for offline use.');

              // Execute callback
              if (config && config.onSuccess) {
                config.onSuccess(registration);
              }
            }
          }
        };
      };
    })
    .catch(error => {
      console.error('Error during service worker registration:', error);
    });

Solution

  • navigator.serviceWorker.controller will be set to a truthy value (a ServiceWorker object) if the current page is under the control of a service worker.

    If this is the first time a service worker's been registered whose scope encompasses the current page's URL, then navigator.serviceWorker.controller will not be set (unless the service worker itself calls clients.claim()).

    If this is a subsequent visit to a page that is under the registered service worker's scope, then navigator.serviceWorker.controller will be set, and the page will be under the service worker's control.