💕 Proudly built using open-wc and Modern Web Tools.
Custom Element for declaratively adding a service worker with optional auto-update.
<service-worker id="serviceWorker"
path="./service-worker.js"
scope="/muh-data/"
auto-reload
></service-worker>
Property | Attribute | Type | Default | Description |
---|---|---|---|---|
autoReload |
auto-reload |
boolean |
false | If true, when updates are found, the page will automatically reload, so long as the user has not yet interacted with it. |
channelName |
channel-name |
string | null |
"service-worker" | Channel name for communicating with the service worker. |
error |
error |
Error |
Error state of the service-worker registration | |
installed |
installed |
boolean |
false | True when the service worker is installed. |
path |
path |
string |
"/service-worker.js" | Path to the service worker script. |
scope |
scope |
string |
"/" | Scope for the service worker. |
serviceWorker |
ServiceWorker | null |
null | A reference to the service worker instance. | |
updateAction |
update-action |
string | null |
"skipWaiting" | String passed to serviceWorker which triggers self.skipWaiting(). String will be passed in message.action. |
Method | Type | Description |
---|---|---|
#onError |
(error: Error): Error |
Sets the error property |
#onRegistration |
(reg: ServiceWorkerRegistration): ServiceWorkerRegistration |
|
#refresh |
(): void |
|
#track |
(serviceWorker: ServiceWorker): ServiceWorker |
Listen for changes on a new worker, notify when installed. 🍞 |
#update |
(serviceWorker: ServiceWorker): ServiceWorker |
When an update is found, if user has not yet interacted with the page, reload it for them, otherwise, prompt them to reload 🍩. |
#updateChannelName |
(): void |
|
#updateConfig |
(): void |
|
registerServiceWorker |
(options?: Partial<Pick<ServiceWorkerElement, "path" | "scope" | "updateAction">> | undefined): Promise<void | ServiceWorkerRegistration> |
Registers a service worker, and prompts to update as needed |
Event | Type | Description |
---|---|---|
change |
ServiceWorkerChangeEvent |
When the service worker changes |
error |
ServiceWorkerErrorEvent |
When an error occurs |
message |
ServiceWorkerMessageEvent |
When a message is received on the broadcast channel |
When an updated service worker is detected, <service-worker>
will post a message to the service worker with the contents { action: this.updateAction }
. You can customize the name of the passed action by setting the updateAction
property or the update-action
attribute (they will sync with each other). updateAction
is by 'skipWaiting'
by default. You can then handle that message in your service worker by running self.skipWaiting()
:
self.addEventListener('message', event => {
switch (event.data.action) {
case 'skipWaiting': return self.skipWaiting();
}
});
If auto-reload
is set, <service-worker>
will check if the user has not yet interacted with the app, and if she hasn't, refresh the page by calling location.reload()
when the new service-worker is installed. Listen for the service-worker-changed
event to display a message to the user when the service worker updates.
const dialogTemplate = document.createElement('template');
dialogTemplate.innerHTML = `
<dialog>
<form method="dialog">
<h1>New Version Available!</h1>
<p>Reload the Page?</p>
<menu>
<button value="confirm">OK</button>
<button value="cancel">Cancel</button>
</menu>
</form>
</dialog>
`;
document.querySelector('service-worker')
.addEventListener('service-worker-changed', event => {
const dialog = dialogTemplate.content.cloneNode(true);
dialog.addEventListener('close', function({ returnValue }) {
if (returnValue === 'confirm') location.reload();
});
document.body.append(dialog);
dialog.showModal();
})
If you are using sw-precache to generate your SW, it will automatically skip waiting on reload, unless you specify otherwise in sw-precache-config.js
Workbox offers a similar feature, although you must opt in when constructing the workbox instance.
// service-worker.js
const workboxSW = new WorkboxSW({
skipWaiting: true,
});
// workbox-config.js
module.exports = {
// ...
skipWaiting: true,
};
// rollup.config.js
import { generateSW } from 'rollup-plugin-workbox';
export default {
// ...
// use workbox-config.js as above
plugins: [generateSW(require('./workbox-config.js'))]
}
// webpack.config.js
const workboxPlugin = require('workbox-webpack-plugin');
plugins: [
new workboxPlugin({
skipWaiting: true,
}),
];
// gulpfile.js
const workbox = require('workbox-build');
gulp.task('generate-service-worker', () => {
workbox.generateSW({
skipWaiting: true,
});
});