{"id":15376747,"url":"https://github.com/bennypowers/service-worker","last_synced_at":"2025-04-15T16:43:40.706Z","repository":{"id":28525736,"uuid":"117426114","full_name":"bennypowers/service-worker","owner":"bennypowers","description":"Custom Element for declaratively adding a service worker with \"Click To Update\" prompt and optional auto-install.","archived":false,"fork":false,"pushed_at":"2023-01-24T17:50:57.000Z","size":791,"stargazers_count":23,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-28T22:35:26.963Z","etag":null,"topics":["customelements","hacktoberfest","service-worker","sw-precache","webcomponents","workbox"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bennypowers.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["bennypowers"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"custom":null}},"created_at":"2018-01-14T11:57:28.000Z","updated_at":"2023-01-01T10:21:15.000Z","dependencies_parsed_at":"2023-02-13T23:55:15.953Z","dependency_job_id":null,"html_url":"https://github.com/bennypowers/service-worker","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bennypowers%2Fservice-worker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bennypowers%2Fservice-worker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bennypowers%2Fservice-worker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bennypowers%2Fservice-worker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bennypowers","download_url":"https://codeload.github.com/bennypowers/service-worker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249110724,"owners_count":21214385,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["customelements","hacktoberfest","service-worker","sw-precache","webcomponents","workbox"],"created_at":"2024-10-01T14:08:50.219Z","updated_at":"2025-04-15T16:43:40.688Z","avatar_url":"https://github.com/bennypowers.png","language":"TypeScript","funding_links":["https://github.com/sponsors/bennypowers"],"categories":[],"sub_categories":[],"readme":"[![Published on npm](https://img.shields.io/npm/v/@power-elements/service-worker)](https://npm.im/@power-elements/service-worker)\n[![Published on webcomponents.org](https://img.shields.io/badge/webcomponents.org-published-blue.svg)](https://www.webcomponents.org/element/bennypowers/service-worker)\n[![Test Status](https://github.com/bennypowers/service-worker/workflows/test/badge.svg)](https://github.com/bennypowers/service-worker/actions?query=workflow%3Atest)\n[![Test Coverage](https://api.codeclimate.com/v1/badges/512ba168f108821c0be1/test_coverage)](https://codeclimate.com/github/bennypowers/service-worker/test_coverage)\n[![Maintainability](https://api.codeclimate.com/v1/badges/512ba168f108821c0be1/maintainability)](https://codeclimate.com/github/bennypowers/service-worker/maintainability)\n[![Contact me on Codementor](https://cdn.codementor.io/badges/contact_me_github.svg)](https://www.codementor.io/bennyp?utm_source=github\u0026utm_medium=button\u0026utm_term=bennyp\u0026utm_campaign=github)\n\n💕 Proudly built using [open-wc](https://open-wc.org) and [Modern Web](https://github.com/modernweb-dev/web) Tools.\n# service-worker\n\nCustom Element for declaratively adding a service worker with optional auto-update.\n\n## Example\n\n```html\n\u003cservice-worker id=\"serviceWorker\"\n    path=\"./service-worker.js\"\n    scope=\"/muh-data/\"\n    auto-reload\n\u003e\u003c/service-worker\u003e\n```\n\n## Properties\n\n| Property        | Attribute       | Type                    | Default              | Description                                      |\n|-----------------|-----------------|-------------------------|----------------------|--------------------------------------------------|\n| `autoReload`    | `auto-reload`   | `boolean`               | false                | If true, when updates are found, the page will automatically\u003cbr /\u003ereload, so long as the user has not yet interacted with it. |\n| `channelName`   | `channel-name`  | `string \\| null`        | \"service-worker\"     | Channel name for communicating with the service worker. |\n| `error`         | `error`         | `Error`                 |                      | Error state of the service-worker registration   |\n| `installed`     | `installed`     | `boolean`               | false                | True when the service worker is installed.       |\n| `path`          | `path`          | `string`                | \"/service-worker.js\" | Path to the service worker script.               |\n| `scope`         | `scope`         | `string`                | \"/\"                  | Scope for the service worker.                    |\n| `serviceWorker` |                 | `ServiceWorker \\| null` | null                 | A reference to the service worker instance.      |\n| `updateAction`  | `update-action` | `string \\| null`        | \"skipWaiting\"        | String passed to serviceWorker which triggers self.skipWaiting().\u003cbr /\u003eString will be passed in message.action. |\n\n## Methods\n\n| Method                  | Type                                             | Description                                      |\n|-------------------------|--------------------------------------------------|--------------------------------------------------|\n| `#onError`              | `(error: Error): Error`                          | Sets the error property                          |\n| `#onRegistration`       | `(reg: ServiceWorkerRegistration): ServiceWorkerRegistration` |                                                  |\n| `#refresh`              | `(): void`                                       |                                                  |\n| `#track`                | `(serviceWorker: ServiceWorker): ServiceWorker`  | Listen for changes on a new worker, notify when installed. 🍞 |\n| `#update`               | `(serviceWorker: ServiceWorker): ServiceWorker`  | When an update is found, if user has not yet interacted with the page,\u003cbr /\u003ereload it for them, otherwise, prompt them to reload 🍩. |\n| `#updateChannelName`    | `(): void`                                       |                                                  |\n| `#updateConfig`         | `(): void`                                       |                                                  |\n| `registerServiceWorker` | `(options?: Partial\u003cPick\u003cServiceWorkerElement, \"path\" \\| \"scope\" \\| \"updateAction\"\u003e\u003e \\| undefined): Promise\u003cvoid \\| ServiceWorkerRegistration\u003e` | Registers a service worker, and prompts to update as needed |\n\n## Events\n\n| Event     | Type                        | Description                                      |\n|-----------|-----------------------------|--------------------------------------------------|\n| `change`  | `ServiceWorkerChangeEvent`  | When the service worker changes                  |\n| `error`   | `ServiceWorkerErrorEvent`   | When an error occurs                             |\n| `message` | `ServiceWorkerMessageEvent` | When a message is received on the broadcast channel |\n\n## Updating the Service Worker.\n\nWhen an updated service worker is detected, `\u003cservice-worker\u003e` 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()`:\n\n```js\nself.addEventListener('message', event =\u003e {\n  switch (event.data.action) {\n    case 'skipWaiting': return self.skipWaiting();\n  }\n});\n```\n\nIf `auto-reload` is set, `\u003cservice-worker\u003e` 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.\n\n```js\nconst dialogTemplate = document.createElement('template');\ndialogTemplate.innerHTML = `\n  \u003cdialog\u003e\n    \u003cform method=\"dialog\"\u003e\n      \u003ch1\u003eNew Version Available!\u003c/h1\u003e\n      \u003cp\u003eReload the Page?\u003c/p\u003e\n      \u003cmenu\u003e\n        \u003cbutton value=\"confirm\"\u003eOK\u003c/button\u003e\n        \u003cbutton value=\"cancel\"\u003eCancel\u003c/button\u003e\n      \u003c/menu\u003e\n    \u003c/form\u003e\n  \u003c/dialog\u003e\n`;\ndocument.querySelector('service-worker')\n  .addEventListener('service-worker-changed', event =\u003e {\n    const dialog = dialogTemplate.content.cloneNode(true);\n    dialog.addEventListener('close', function({ returnValue }) {\n      if (returnValue === 'confirm') location.reload();\n    });\n    document.body.append(dialog);\n    dialog.showModal();\n  })\n```\n\n### sw-precache\nIf you are using [sw-precache](https://github.com/GoogleChromeLabs/sw-precache#skipwaiting-boolean) to generate your SW, it will automatically skip waiting on reload, unless you specify otherwise in `sw-precache-config.js`\n\n### Workbox\n[Workbox](https://developers.google.com/web/tools/workbox/reference-docs/latest/module-workbox-sw.WorkboxSW) offers a similar feature, although you must opt in when constructing the workbox instance.\n\n#### Directly in service-worker.js\n\n```js\n// service-worker.js\nconst workboxSW = new WorkboxSW({\n  skipWaiting: true,\n});\n```\n\n#### Workbox CLI\n```js\n// workbox-config.js\nmodule.exports = {\n  // ...\n  skipWaiting: true,\n};\n```\n\n#### Rollup\n```js\n// rollup.config.js\nimport { generateSW } from 'rollup-plugin-workbox';\nexport default {\n  // ...\n  // use workbox-config.js as above\n  plugins: [generateSW(require('./workbox-config.js'))]\n}\n```\n\n#### Webpack\n```js\n// webpack.config.js\nconst workboxPlugin = require('workbox-webpack-plugin');\n\nplugins: [\n  new workboxPlugin({\n    skipWaiting: true,\n  }),\n];\n```\n\n#### Gulp\n```js\n// gulpfile.js\nconst workbox = require('workbox-build');\n\ngulp.task('generate-service-worker', () =\u003e {\n  workbox.generateSW({\n    skipWaiting: true,\n  });\n});\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbennypowers%2Fservice-worker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbennypowers%2Fservice-worker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbennypowers%2Fservice-worker/lists"}