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
Congratulations @jfbloom22! You received a personal award!
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:
Vote for @Steemitboard as a witness to get one more award and increased upvotes!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Congratulations @jfbloom22! You received a personal award!
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!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit