Periodic Service Worker Updates
INFO
If you're not importing any of the virtual modules provided by vite-plugin-pwa
you'll need to figure out how to configure it, it is out of the scope of this guide.
As explained in Manual Updates entry in The Service Worker Lifecycle article, you can use this code to configure periodic service worker updates on your application on your main.ts
or main.js
:
main.ts / main.js
ts
import { registerSW } from 'virtual:pwa-register'
const intervalMS = 60 * 60 * 1000
const updateSW = registerSW({
onRegistered(r) {
r && setInterval(() => {
r.update()
}, intervalMS)
}
})
import { registerSW } from 'virtual:pwa-register'
const intervalMS = 60 * 60 * 1000
const updateSW = registerSW({
onRegistered(r) {
r && setInterval(() => {
r.update()
}, intervalMS)
}
})
The interval must be in milliseconds, in the example above it is configured to check the service worker every hour.
Handling Edge Cases
INFO
From version 0.12.8+
we have a new option, onRegisteredSW
, and onRegistered
has been deprecated. If onRegisteredSW
is present, onRegistered
will never be called.
Previous script will allow you to check if there is a new version of your application available, but you will need also to deal with some edge cases like:
- server is down when calling the update method
- the user can go offline at any time
To mitigate previous problems, use this more complex snippet:
main.ts / main.js
ts
import { registerSW } from 'virtual:pwa-register'
const intervalMS = 60 * 60 * 1000
const updateSW = registerSW({
onRegisteredSW(swUrl, r) {
r && setInterval(async () => {
if (!(!r.installing && navigator))
return
if (('connection' in navigator) && !navigator.onLine)
return
const resp = await fetch(swUrl, {
cache: 'no-store',
headers: {
'cache': 'no-store',
'cache-control': 'no-cache',
},
})
if (resp?.status === 200)
await r.update()
}, intervalMS)
}
})
import { registerSW } from 'virtual:pwa-register'
const intervalMS = 60 * 60 * 1000
const updateSW = registerSW({
onRegisteredSW(swUrl, r) {
r && setInterval(async () => {
if (!(!r.installing && navigator))
return
if (('connection' in navigator) && !navigator.onLine)
return
const resp = await fetch(swUrl, {
cache: 'no-store',
headers: {
'cache': 'no-store',
'cache-control': 'no-cache',
},
})
if (resp?.status === 200)
await r.update()
}, intervalMS)
}
})
WARNING
This only applies when importing any of the virtual modules or using workbox-window
module.
Since workbox-window
uses a time-based heuristic
algorithm to handle service worker updates, if you build your service worker and register it again, if the time between last registration and the new one is less than 1 minute, then, workbox-window
will handle the service worker update found
event as an external event, and so the behavior could be strange (for example, if using prompt
, instead showing the dialog for new content available, the ready to work offline dialog will be shown; if using autoUpdate
, the ready to work offline dialog will be shown and shouldn't be shown).