Skip to content

Commit

Permalink
ServiceWorkerContainer.register() updates
Browse files Browse the repository at this point in the history
  • Loading branch information
hamishwillee committed Nov 12, 2024
1 parent d10583e commit c8da3d8
Showing 1 changed file with 88 additions and 32 deletions.
120 changes: 88 additions & 32 deletions files/en-us/web/api/serviceworkercontainer/register/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,21 @@ browser-compat: api.ServiceWorkerContainer.register

{{APIRef("Service Workers API")}}{{SecureContext_Header}}{{AvailableInWorkers}}

The **`register()`** method of the
{{domxref("ServiceWorkerContainer")}} interface creates or updates a
{{domxref("ServiceWorkerRegistration")}} for the given `scriptURL`.
The **`register()`** method of the {{domxref("ServiceWorkerContainer")}} interface creates or updates a {{domxref("ServiceWorkerRegistration")}} for the given scope.
If successful, the registration associates the provided script URL to a _scope_, which is subsequently used for matching documents to a specific service worker.

If successful, a service worker registration ties the provided script URL to a
_scope_, which is subsequently used for navigation matching. You can call this
method unconditionally from the controlled page. I.e., you don't need to first check
whether there's an active registration.
A single registration is created for each unique scope.
If `register()` is called for a scope that has an existing registration, the registration is updated with any changes to the scriptURL or options.
If there are no changes, then the existing registration is returned.
Note that the service worker is installed only on the first registration of a particular scriptURL.
You can therefore call this method unconditionally from a controlled page: you don't need to first check whether there's an active registration or service worker.

A document can potentially be within the scope of several registrations with different service workers and options.
The browser will associate the document with the matching registration that has the most specific scope.
This ensures that only one service worker runs for each document.

> [!NOTE]
> It is generally safer not to define registrations that have overlapping scopes.
## Syntax

Expand All @@ -27,36 +34,38 @@ register(scriptURL, options)
### Parameters

- `scriptURL`
- : The URL of the service worker script. The registered service worker file needs to
have a valid [JavaScript MIME type](/en-US/docs/Web/HTTP/MIME_types#textjavascript).
- : The URL of the service worker script.
The registered service worker file needs to have a valid [JavaScript MIME type](/en-US/docs/Web/HTTP/MIME_types#textjavascript).
- `options` {{optional_inline}}

- : An object containing registration options. Currently available options are:

- `scope`
- : A string representing a URL that defines a
service worker's registration scope; that is, what range of URLs a service worker
can control. This is usually a relative URL. It is relative to the base URL of the
application. By default, the `scope` value for a service worker
registration is set to the directory where the service worker script is located (by resolving `./` against `scriptURL`).
See the [Examples](#examples) section for more information on how it
works.

- : A string representing a URL that defines a service worker's registration scope; that is, what range of URLs a service worker can control.

This is usually a relative URL, which is relative to the base URL of the application.
By default, the `scope` value for a service worker registration is set to the directory where the service worker script is located (by resolving `./` against `scriptURL`).
Note that by default this scope must specify documents that are in the same directory or more deeply nested than the service worker (if you need a broader scope, this can be permitted via the HTTP `Service-Worker-Allowed` header).

See the [Examples](#examples) section for more information on how it works.

- `type`

- : A string
specifying the type of worker to create. Valid values are:
- : A string specifying the type of worker to create.
Valid values are:

- `'classic'`
- : The loaded service worker is in a standard script. This is the default.
- : The loaded service worker is in a standard script.
This is the default.
- `'module'`
- : The loaded service worker is in an
[ES module](/en-US/docs/Web/JavaScript/Guide/Modules)
and the import statement is available on
worker contexts. For ES module compatibility info, see the [browser compatibility data table for the `ServiceWorker` interface](/en-US/docs/Web/API/ServiceWorker#browser_compatibility).
- : The loaded service worker is in an [ES module](/en-US/docs/Web/JavaScript/Guide/Modules) and the import statement is available on worker contexts.
For ES module compatibility info, see the [browser compatibility data table for the `ServiceWorker` interface](/en-US/docs/Web/API/ServiceWorker#browser_compatibility).

- `updateViaCache`

- : A string indicating how the HTTP cache is used for service worker scripts resources during updates. Note: This only refers to the service worker script and its imports, not other resources fetched by these scripts.
- : A string indicating how the HTTP cache is used for service worker scripts resources during updates.
Note: This only refers to the service worker script and its imports, not other resources fetched by these scripts.

- `'all'`
- : The HTTP cache will be queried for the main script, and all imported scripts. If no fresh entry is found in the HTTP cache, then the scripts are fetched from the network.
Expand All @@ -67,15 +76,31 @@ register(scriptURL, options)

### Return value

A {{jsxref("Promise")}} that resolves with a {{domxref("ServiceWorkerRegistration")}}
object.
A {{jsxref("Promise")}} that resolves with a {{domxref("ServiceWorkerRegistration")}} object.

### Exceptions

- `TypeError`

- : The `scriptURL` or `scope URL` is a failure.
This can happen if the URL can't be resolved to a valid URL or uses a scheme that is not `http:` or `https`.
For `scriptURL` it may also happen because the URL cannot be validated using the [Trusted Types API](/en-US/docs/Web/API/Trusted_Types_API).

The exception is also raised if the `scriptURL` or `scope URL` path contains the case-insensitive ASCII "%2f" (`*`) or "%5c" (`=`)

- `SecurityError` {{domxref("DOMException")}}
- : The `scriptURL` is not a potentially trustworthy origin, such as `localhost` or an `https` URL.
The `scriptURL` and scope are not same-origin with the registering page.

## Examples

The examples described here should be taken together to get a better understanding of
how service workers scope applies to a page.
The examples described here should be taken together to get a better understanding of how service workers scope applies to a page.

The following example uses the default value of `scope` (by omitting it). Suppose the service worker code is at `example.com/sw.js`, and the registration code at `example.com/index.html`. The service worker code will control `example.com/index.html`, as well as pages underneath it, like `example.com/product/description.html`.
### Register a service worker with default scope

The following example uses the default value of `scope` (by omitting it).
Suppose the service worker code is at `example.com/sw.js`, and the registration code at `example.com/index.html`.
The service worker code will control `example.com/index.html`, as well as pages underneath it, like `example.com/product/description.html`.

```js
if ("serviceWorker" in navigator) {
Expand All @@ -94,7 +119,10 @@ if ("serviceWorker" in navigator) {
}
```

The following code, with all code in the same place, would apply to exactly the same pages as the example above. Alternatively, if the service worker code is at `example.com/product/sw.js`, and the registration code at `example.com/product/description.html`. then the service worker would only apply to resources under `example.com/product`. Remember the scope, when included, uses the page's location as its base.
### Register a service worker with a scope

The code below is almost identical, except we have specified the scope explicitly using `{ scope: "./" }`.
This scope happens to be the same as the default scope, so the registration applies to exactly the same pages as the example above.

```js
if ("serviceWorker" in navigator) {
Expand All @@ -112,7 +140,34 @@ if ("serviceWorker" in navigator) {
}
```

There is frequent confusion surrounding the meaning and use of _scope_. A service worker can't have a scope broader than its own location, unless the server specifies a broader maximum scope in a [Service-Worker-Allowed](https://w3c.github.io/ServiceWorker/#service-worker-allowed) header on the service worker script. Therefore you should use the `scope` option when you need a _narrower_ scope than the default.
Note that if we were to run this code after the previous example, browsers should recognise that we're updating an existing registration at the same scope.

### Register a service worker from a different base URL

In this example the service worker code is at `example.com/product/sw.js`, and the registration code at `example.com/product/description.html`.
The service worker applies to resources under `example.com/product`. Remember the scope, when included, uses the page's location as its base.

```js
if ("serviceWorker" in navigator) {
// declaring scope manually
navigator.serviceWorker.register("./sw.js", { scope: "./" }).then(
(registration) => {
console.log("Service worker registration succeeded:", registration);
},
(error) => {
console.error(`Service worker registration failed: ${error}`);
},
);
} else {
console.error("Service workers are not supported.");
}
```

### Using Service-Worker-Allowed to increase service worker scope

There is frequent confusion surrounding the meaning and use of _scope_.
A service worker can't have a scope broader than its own location, unless the server specifies a broader maximum scope in a [Service-Worker-Allowed](https://w3c.github.io/ServiceWorker/#service-worker-allowed) header on the service worker script.
Therefore you should use the `scope` option when you need a _narrower_ scope than the default.

The following code, if included in `example.com/index.html`, at the root of a site, would only apply to resources under `example.com/product`.

Expand All @@ -132,7 +187,8 @@ if ("serviceWorker" in navigator) {
}
```

As noted above, servers can change the default maximum scope by setting the `Service-Worker-Allowed` header on the service worker script. In this case, the `scope` option should specify a scope narrower than the header value, but potentially larger than the service worker's location.
As noted above, servers can change the default maximum scope by setting the `Service-Worker-Allowed` header on the service worker script.
In this case, the `scope` option should specify a scope narrower than the header value, but potentially larger than the service worker's location.

The following code, if included in `example.com/product/index.html`, would apply to all resources under `example.com` if the server set the `Service-Worker-Allowed` header to `/` or `https://example.com/` when serving `sw.js`. If the server doesn't set the header, the service worker registration will fail, as the requested `scope` is too broad.

Expand Down

0 comments on commit c8da3d8

Please sign in to comment.