How to Handle Upgrades with Service Workers with CRA3 and Typescript

in #typescript5 years ago (edited)

It is a huge pain to figure out how to handle upgrading when using Create React App with the service worker enabled and Typescript. It is unfortunate because the offline functionality works amazingly well and allowing users to install the app via Chrome onto their Desktop is very impressive.

The Problem

Users do not know that they need to close all the tabs with this app in order to install the update. The app could instruct them to do this, but it is a poor experience. In my case, I am not using lazy-loaded content so I simply want the app to update when an update is available.

The Second Problem

Most examples suggest calling skipWaiting() in order to apply the update immediately after refreshing. However this causes typescript to complain and the app will not compile.

The Solution

Update to react-scripts ^3.2.0. Verify that you have the new version of serviceWorker.ts or .js. The old one was called registerServiceWorker.js and the register function did not accept a configuration object.

then in index.tsx:

  serviceWorker.register({
    onUpdate: registration => {
    alert('New version available!  Ready to update?');
    window.location.reload();
      if (registration && registration.waiting) {
        registration.waiting.postMessage({ type: 'SKIP_WAITING' });
      }
    }
  });

The latest version of the ServiceWorker.ts register()function accepts a config object with a callback function where we can handle upgrading. If we post a message SKIP_WAITING this tells the service worker to stop waiting and to go ahead and load the new content after the next refresh. In this example I am using a javascript alert to inform the user. Please replace this with a custom toast or you can opt for a confirmation pattern:

        window.confirm(
              'New version available!  Ready to update?'
            )
          ) {
            window.location.reload();
          }

It is nice giving the user control here, but you will also need to add support for a) installing the update after ignoring it. b) add support for a "force update" feature for those times a critical bug needs to be resolved ASAP.

The reason this works is because under the hood CRA is using workbox-webpack-plugin which includes a SKIP_WAITING listener.

More About Service Workers

good guide: https://redfin.engineering/how-to-fix-the-refresh-button-when-using-service-workers-a8e27af6df68
CRA issue discussing service worker cache: https://github.com/facebook/create-react-app/issues/5316
If you are not using CRA, you can use workbox directly: https://developers.google.com/web/tools/workbox
issue tracking why typescript does not include service worker typings: https://github.com/Microsoft/TypeScript/issues/11781

Sort:  

Congratulations @jfbloom22! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 1 year!

You can view your badges on your Steem Board and compare to others on the Steem Ranking

Do not miss the last post from @steemitboard:

Valentine's day challenge - Give a badge to your beloved!
Vote for @Steemitboard as a witness to get one more award and increased upvotes!

Congratulations @jfbloom22! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 2 years!

You can view your badges on your Steem Board and compare to others on the Steem Ranking

Vote for @Steemitboard as a witness to get one more award and increased upvotes!

Coin Marketplace

STEEM 0.19
TRX 0.15
JST 0.029
BTC 63878.47
ETH 2625.83
USDT 1.00
SBD 2.79