Tutorial: Auto-update your Create React App PWA

Andrew Kirchofer Feb 27, 2023

You’re probably here because you’ve been developing a Progressive Web App (PWA) using Create React App? I’ve been working on developing a PWA, and had a hard time finding information on how to implement an auto-update notification.


Preliminary Steps

This tutorial assumes you’ve already created a new app using React Create React App. If you need help starting your project, visit the Create React App – Getting Started documentation.

We're also going to make use of the React-Toastify project. React-Toastify allows you to add notification popups anywhere in your app easily.

You can install this in your project via NPM:

npm install --save react-toastify

or via Yarn:

yarn add react-toastify


1. Let’s Get Started

Create React App includes a built-in service worker, disabled by default. When you enable the built-in service worker, the browser loads the pre-cached version of your app. On one hand, this is great — after the first load, your users will experience very fast load times. On the other hand, this causes new issues — how do you roll out updates to your users? Since their browser will default to loading from cache.

That’s where this tutorial comes in to help.


2. Enable Service Worker

If you haven’t already, go ahead and “register” the service worker in your project's src/index.js file.

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want your app to work offline and load faster, you can change// unregister() to register() below. Note this comes with some pitfalls.// Learn more about service workers: https://cra.link/PWAserviceWorker.register();

3. Move Service Worker File

In order for your service worker file to display a toast notification, you'll need to call the serviceWorker.register() method from within a render() method. This will enable React-Toastify to render notifications from within your src/serviceWorker.js file.


4. Modify Service Worker File

Inside your project's src/serviceWorker.js file, at the top of the document, import the following:

import React from 'react'
import { toast } from 'react-toastify'

Then under the registerValidSW function – add lines 4 through 10, and 29 through 33.

Line number 5 checks for updates during app launch (i.e. whenever the website is opened, works with either the browser or installed version).

Lines 7 through 10, checks for app updates every 5 minutes. You can modify the interval to whatever suits your use case.

Lines 28 through 33, displays React-Toastify notification in app. Letting the end-user know that a new version has been discovered on the server. All they need to do is close and reopen the app to update.

function registerValidSW(swUrl, config) {
  navigator.serviceWorker.register(swUrl)
    .then(registration => {
      // Check for updates at start.      registration.update();      // Check for updates every 5 min.      setInterval(() => {        registration.update();        console.debug("Checked for update...");      }, (1000 * 60) * 5);
      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. See https://bit.ly/CRA-PWA.'
              );

              toast.info(`Update available! To update, close all windows and reopen.`, {                toastId: "appUpdateAvailable", // Prevent duplicate toasts                onClick: () => window.close(), // Closes windows on click                autoClose: false // Prevents toast from auto closing              });
              // 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);
    });
}

5. Test Notification

To test your newly configured auto-update notification, run npm run build on your Create React App project. Load the freshly built web app in your browser – this should cache this build in your browser.

After loading in your browser, make a small change to your web app and run npm run build again. Open your browser to the web app again, and voilà — this should trigger the auto-update notification! ✨

Tired of managing GitHub issues manually? Genius is the ultimate AI-powered GitHub project management tool.