Service Workers Nightly

Editor’s Draft,

More details about this document
This version:
https://w3c.github.io/ServiceWorker/
Latest published version:
https://www.w3.org/TR/service-workers/
Implementation Report:
https://wpt.fyi/results/service-workers
Test Suite:
https://github.com/web-platform-tests/wpt/tree/master/service-workers
Feedback:
GitHub
Inline In Spec
Editors:
(Microsoft)
(Google)
Former Editors:
(Google)
(Google)
(Microsoft‚ represented Samsung until April 2018)
(Google)

Abstract

The core of this specification is a worker that wakes to receive events. This provides an event destination that can be used when other destinations would be inappropriate, or no other destination exists.

For example, to allow the developer to decide how a page should be fetched, an event needs to dispatch potentially before any other execution contexts exist for that origin. To react to a push message, or completion of a persistent download, the context that originally registered interest may no longer exist. In these cases, the service worker is the ideal event destination.

This specification also provides a fetch event, and a request and response store similar in design to the HTTP cache, which makes it easier to build offline-enabled web applications.

Status of this document

This document was published by the Web Applications Working Group as an Editor’s Draft.

Publication as an Editor’s Draft does not imply endorsement by W3C and its Members.

This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than a work in progress.

This is a living document. Readers need to be aware that this specification may include unimplemented features, and details that may change. Service Workers 1 is a version that is advancing toward a W3C Recommendation.

This document was produced by a group operating under the W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent that the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 18 August 2025 W3C Process Document.

1. Motivations

This section is non-normative.

Web Applications traditionally assume that the network is reachable. This assumption pervades the platform. HTML documents are loaded over HTTP and traditionally fetch all of their sub-resources via subsequent HTTP requests. This places web content at a disadvantage versus other technology stacks.

The service worker is designed first to redress this balance by providing a Web Worker context, which can be started by a runtime when navigations are about to occur. This event-driven worker is registered against an origin and a path (or pattern), meaning it can be consulted when navigations occur to that location. Events that correspond to network requests are dispatched to the worker and the responses generated by the worker may override default network stack behavior. This puts the service worker, conceptually, between the network and a document renderer, allowing the service worker to provide content for documents, even while offline.

Web developers familiar with previous attempts to solve the offline problem have reported a deficit of flexibility in those solutions. As a result, the service worker is highly procedural, providing a maximum of flexibility at the price of additional complexity for developers. Part of this complexity arises from the need to keep service workers responsive in the face of a single-threaded execution model. As a result, APIs exposed by service workers are almost entirely asynchronous, a pattern familiar in other JavaScript contexts but accentuated here by the need to avoid blocking document and resource loading.

Developers using the HTML5 Application Cache have also reported that several attributes of the design contribute to unrecoverable errors. A key design principle of the service worker is that errors should always be recoverable. Many details of the update process of service workers are designed to avoid these hazards.

Service workers are started and kept alive by their relationship to events, not documents. This design borrows heavily from developer and vendor experience with shared workers and Chrome Background Pages. A key lesson from these systems is the necessity to time-limit the execution of background processing contexts, both to conserve resources and to ensure that background context loss and restart is top-of-mind for developers. As a result, service workers bear more than a passing resemblance to Chrome Event Pages, the successor to Background Pages. Service workers may be started by user agents without an attached document and may be killed by the user agent at nearly any time. Conceptually, service workers can be thought of as Shared Workers that can start, process events, and die without ever handling messages from documents. Developers are advised to keep in mind that service workers may be started and killed many times a second.

Service workers are generic, event-driven, time-limited script contexts that run at an origin. These properties make them natural endpoints for a range of runtime services that may outlive the context of a particular document, e.g. handling push notifications, background data synchronization, responding to resource requests from other origins, or receiving centralized updates to expensive-to-calculate data (e.g., geolocation or gyroscope).

2. Model

2.1. Service Worker

A service worker is a type of web worker. A service worker executes in the registering service worker client’s origin.

A service worker has an associated state, which is one of "parsed", "installing", "installed", "activating", "activated", and "redundant". It is initially "parsed".

A service worker has an associated script url (a URL).

A service worker has an associated type which is either "classic" or "module". Unless stated otherwise, it is "classic".

A service worker has an associated containing service worker registration (a service worker registration), which contains itself.

A service worker has an associated global object (a ServiceWorkerGlobalScope object or null).

A service worker has an associated script resource (a script), which represents its own script resource. It is initially set to null.

A script resource has an associated has ever been evaluated flag. It is initially unset.

A script resource has an associated policy container (a policy container). It is initially a new policy container.

A service worker has an associated script resource map which is an ordered map where the keys are URLs and the values are responses.

A service worker has an associated set of used scripts (a set) whose item is a URL. It is initially a new set.

Note: The set of used scripts is only used to prune unused resources from a new worker’s map after installation, that were populated based on the old worker’s map during the update check.

A service worker has an associated skip waiting flag. Unless stated otherwise it is unset.

A service worker has an associated classic scripts imported flag. It is initially unset.

A service worker has an associated set of event types to handle (a set) whose item is an event listener’s event type. It is initially a new set.

A service worker has an associated set of extended events (a set) whose item is an ExtendableEvent. It is initially a new set.

A service worker has an associated start status which can be null or a Completion. It is initially null.

A service worker has an associated all fetch listeners are empty flag. It is initially unset.

A service worker has an associated list of router rules (a list of RouterRules). It is initially an empty list.

A service worker is said to be running if its event loop is running.

A service worker has an associated [[service worker queue]] (a parallel queue).

2.1.1. Lifetime

The lifetime of a service worker is tied to the execution lifetime of events and not references held by service worker clients to the ServiceWorker object.

A user agent may terminate service workers at any time it:

  • Has no event to handle.

  • Detects abnormal operation: such as infinite loops and tasks exceeding imposed time limits (if any) while handling the events.

2.1.2. Events

The Service Workers specification defines service worker events (each of which is an event) that include (see the list):

2.2. Service Worker Timing

Service workers mark certain points in time that are later exposed by the navigation timing API and resource timing API.

A service worker timing info is a struct. It has the following items:

start time

A DOMHighResTimeStamp, initially 0.

fetch event dispatch time

A DOMHighResTimeStamp, initially 0.

worker router evaluation start

A DOMHighResTimeStamp, initially 0.

worker cache lookup start

A DOMHighResTimeStamp, initially 0.

worker matched router source

A DOMString, initially an empty string.

worker final router source

A DOMString, initially an empty string.

2.3. Service Worker Registration

A service worker registration is a tuple of a scope url, a storage key, and a set of service workers, an installing worker, a waiting worker, and an active worker. A user agent may enable many service worker registrations at a single origin so long as the scope url of the service worker registration differs. A service worker registration of an identical scope url when one already exists in the user agent causes the existing service worker registration to be replaced.

A service worker registration has an associated storage key (a storage key).

A service worker registration has an associated scope url (a URL).

A service worker registration has an associated installing worker (a service worker or null) whose state is "installing". It is initially set to null.

A service worker registration has an associated waiting worker (a service worker or null) whose state is "installed". It is initially set to null.

A service worker registration has an associated active worker (a service worker or null) whose state is either "activating" or "activated". It is initially set to null.

A service worker registration has an associated last update check time. It is initially set to null.

A service worker registration is said to be stale if the registration’s last update check time is non-null and the time difference in seconds calculated by the current time minus the registration’s last update check time is greater than 86400.

A service worker registration has an associated update via cache mode, which is "imports", "all", or "none". It is initially set to "imports".

A service worker registration has one or more task queues that back up the tasks from its active worker’s event loop’s corresponding task queues. (The target task sources for this back up operation are the handle fetch task source and the handle functional event task source.) The user agent dumps the active worker’s tasks to the service worker registration’s task queues when the active worker is terminated and re-queues those tasks to the active worker’s event loop’s corresponding task queues when the active worker spins off. Unlike the task queues owned by event loops, the service worker registration’s task queues are not processed by any event loops in and of itself.

A service worker registration has an associated NavigationPreloadManager object.

A service worker registration has an associated navigation preload enabled flag. It is initially unset.

A service worker registration has an associated navigation preload header value, which is a byte sequence. It is initially set to `true`.

A service worker registration is said to be unregistered if registration map[this service worker registration’s (storage key, serialized scope url)] is not this service worker registration.

2.3.1. Lifetime

A user agent must persistently keep a list of registered service worker registrations unless otherwise they are explicitly unregistered. A user agent has a registration map that stores the entries of the tuple of service worker registration’s (storage key, serialized scope url) and the corresponding service worker registration. The lifetime of service worker registrations is beyond that of the ServiceWorkerRegistration objects which represent them within the lifetime of their corresponding service worker clients.

2.4. Service Worker Client

A service worker client is an environment.

A service worker client has an associated discarded flag. It is initially unset.

Each service worker client has the following environment discarding steps:

  1. Set client’s discarded flag.

Note: Implementations can discard clients whose discarded flag is set.

A service worker client has an algorithm defined as the origin that returns the service worker client’s origin if the service worker client is an environment settings object, and the service worker client’s creation URL’s origin otherwise.

A window client is a service worker client whose global object is a Window object.

A dedicated worker client is a service worker client whose global object is a DedicatedWorkerGlobalScope object.

A shared worker client is a service worker client whose global object is a SharedWorkerGlobalScope object.

A worker client is either a dedicated worker client or a shared worker client.

2.5. Control and Use

A service worker client has an active service worker that serves its own loading and its subresources. When a service worker client has a non-null active service worker, it is said to be controlled by that active service worker. When a service worker client is controlled by a service worker, it is said that the service worker client is using the service worker’s containing service worker registration. A service worker client’s active service worker is determined as explained in the following subsections.

The rest of the section is non-normative.

The behavior in this section is not fully specified yet and will be specified in HTML Standard. The work is tracked by the issue and the pull request.

2.5.1. The window client case

A window client is created when a browsing context is created and when it navigates.

When a window client is created in the process of a browsing context creation:

If the browsing context’s initial active document’s origin is an opaque origin, the window client’s active service worker is set to null. Otherwise, it is set to the creator document’s service worker client’s active service worker.

When a window client is created in the process of the browsing context’s navigation:

If the fetch is routed through HTTP fetch, the window client’s active service worker is set to the result of the service worker registration matching. Otherwise, if the created document’s origin is an opaque origin or not the same as its creator document’s origin, the window client’s active service worker is set to null. Otherwise, it is set to the creator document’s service worker client’s active service worker.

Note: For an initial replacement navigation, the initial window client that was created when the browsing context was created is reused, but the active service worker is determined by the same behavior as above.

Note: Sandboxed iframes without the sandboxing directives, allow-same-origin and allow-scripts, result in having the active service worker value of null as their origin is an opaque origin.

2.5.2. The worker client case

A worker client is created when the user agent runs a worker.

When the worker client is created:

When the fetch is routed through HTTP fetch, the worker client’s active service worker is set to the result of the service worker registration matching. Otherwise, if the worker client’s origin is an opaque origin, or the request’s URL is a blob URL and the worker client’s origin is not the same as the origin of the last item in the worker client’s global object’s owner set, the worker client’s active service worker is set to null. Otherwise, it is set to the active service worker of the environment settings object of the last item in the worker client’s global object’s owner set.

Note: Window clients and worker clients with a data: URL result in having the active service worker value of null as their origin is an opaque origin. Window clients and worker clients with a blob URL can inherit the active service worker of their creator document or owner, but if the request’s origin is not the same as the origin of their creator document or owner, the active service worker is set to null.

2.6. Task Sources

The following additional task sources are used by service workers.

The handle fetch task source

This task source is used for dispatching fetch events to service workers.

The handle functional event task source

This task source is used for features that dispatch other functional events, e.g. push events, to service workers.

Note: A user agent may use a separate task source for each functional event type in order to avoid a head-of-line blocking phenomenon for certain functional events.

2.7. User Agent Shutdown

A user agent must maintain the state of its stored service worker registrations across restarts with the following rules:

To attain this, the user agent must invoke Handle User Agent Shutdown when it terminates.

3. Client Context

Bootstrapping with a service worker:
// scope defaults to the path the script sits in
// "/" in this example
navigator.serviceWorker.register("/serviceworker.js").then(registration => {
  console.log("success!");
  if (registration.installing) {
    registration.installing.postMessage("Howdy from your installing page.");
  }
}, err => {
  console.error("Installing the worker failed!", err);
});

3.1. ServiceWorker

[SecureContext, Exposed=(Window,Worker)]
interface ServiceWorker : EventTarget {
  readonly attribute USVString scriptURL;
  readonly attribute ServiceWorkerState state;
  undefined postMessage(any message, sequence<object> transfer);
  undefined postMessage(any message, optional StructuredSerializeOptions options = {});

  // event
  attribute EventHandler onstatechange;
};
ServiceWorker includes AbstractWorker;

enum ServiceWorkerState {
  "parsed",
  "installing",
  "installed",
  "activating",
  "activated",
  "redundant"
};

A ServiceWorker object represents a service worker. Each ServiceWorker object is associated with a service worker. Multiple separate objects implementing the ServiceWorker interface across documents and workers can all be associated with the same service worker simultaneously.

A ServiceWorker object has an associated ServiceWorkerState object which is itself associated with service worker’s state.

3.1.1. Getting ServiceWorker instances

An environment settings object has a service worker object map, a map where the keys are service workers and the values are ServiceWorker objects.

To get the service worker object representing serviceWorker (a service worker) in environment (an environment settings object), run these steps:
  1. Let objectMap be environment’s service worker object map.

  2. If objectMap[serviceWorker] does not exist, then:

    1. Let serviceWorkerObj be a new ServiceWorker in environment’s Realm, and associate it with serviceWorker.

    2. Set serviceWorkerObj’s state to serviceWorker’s state.

    3. Set objectMap[serviceWorker] to serviceWorkerObj.

  3. Return objectMap[serviceWorker].

3.1.2. scriptURL

The scriptURL getter steps are to return the service worker’s serialized script url.

For example, consider a document created by a navigation to https://example.com/app.html which matches via the following registration call which has been previously executed:
// Script on the page https://example.com/app.html
navigator.serviceWorker.register("/service_worker.js");

The value of navigator.serviceWorker.controller.scriptURL will be "https://example.com/service_worker.js".

3.1.3. state

The state attribute must return the value (in ServiceWorkerState enumeration) to which it was last set.

3.1.4. postMessage(message, transfer)

The postMessage(message, transfer) method steps are:

  1. Let options be «[ "transfer" → transfer ]».

  2. Invoke postMessage(message, options) with message and options as the arguments.

3.1.5. postMessage(message, options)

The postMessage(message, options) method steps are:

  1. Let serviceWorker be the service worker represented by this.

  2. Let incumbentSettings be the incumbent settings object.

  3. Let incumbentGlobal be incumbentSettings’s global object.

  4. Let serializeWithTransferResult be StructuredSerializeWithTransfer(message, options["transfer"]). Rethrow any exceptions.

  5. If the result of running the Should Skip Event algorithm with "message" and serviceWorker is true, then return.

  6. Run these substeps in parallel:

    1. If the result of running the Run Service Worker algorithm with serviceWorker is failure, then return.

    2. Queue a task on the DOM manipulation task source to run the following steps:

      1. Let source be determined by switching on the type of incumbentGlobal:

        ServiceWorkerGlobalScope
        The result of getting the service worker object that represents incumbentGlobal’s service worker in the relevant settings object of serviceWorker’s global object.
        Window
        a new WindowClient object that represents incumbentGlobal’s relevant settings object.
        Otherwise
        a new Client object that represents incumbentGlobal’s associated worker
      2. Let origin be the serialization of incumbentSettings’s origin.

      3. Let destination be the ServiceWorkerGlobalScope object associated with serviceWorker.

      4. Let deserializeRecord be StructuredDeserializeWithTransfer(serializeWithTransferResult, destination’s Realm).

        If this throws an exception, let e be the result of creating an event named messageerror, using ExtendableMessageEvent, with the origin attribute initialized to origin and the source attribute initialized to source.

      5. Else:

        1. Let messageClone be deserializeRecord.[[Deserialized]].

        2. Let newPorts be a new frozen array consisting of all MessagePort objects in deserializeRecord.[[TransferredValues]], if any, maintaining their relative order.

        3. Let e be the result of creating an event named message, using ExtendableMessageEvent, with the origin attribute initialized to origin, the source attribute initialized to source, the data attribute initialized to messageClone, and the ports attribute initialized to newPorts.

      6. Dispatch e at destination.

      7. Invoke Update Service Worker Extended Events Set with serviceWorker and e.

3.1.6. Event handler

The following is the event handler (and its corresponding event handler event type) that must be supported, as event handler IDL attributes, by all objects implementing ServiceWorker interface:

event handler event handler event type
onstatechange statechange

3.2. ServiceWorkerRegistration

[SecureContext, Exposed=(Window,Worker)]
interface ServiceWorkerRegistration : EventTarget {
  readonly attribute ServiceWorker? installing;
  readonly attribute ServiceWorker? waiting;
  readonly attribute ServiceWorker? active;
  [SameObject] readonly attribute NavigationPreloadManager navigationPreload;

  readonly attribute USVString scope;
  readonly attribute ServiceWorkerUpdateViaCache updateViaCache;

  [NewObject] Promise<ServiceWorkerRegistration> update();
  [NewObject] Promise<boolean> unregister();

  // event
  attribute EventHandler onupdatefound;
};

enum ServiceWorkerUpdateViaCache {
  "imports",
  "all",
  "none"
};

A ServiceWorkerRegistration has a service worker registration (a service worker registration).

3.2.1. Getting ServiceWorkerRegistration instances

An environment settings object has a service worker registration object map, a map where the keys are service worker registrations and the values are ServiceWorkerRegistration objects.

To get the service worker registration object representing registration (a service worker registration) in environment (an environment settings object), run these steps:
  1. Let objectMap be environment’s service worker registration object map.

  2. If objectMap[registration] does not exist, then:

    1. Let registrationObject be a new ServiceWorkerRegistration in environment’s Realm.

    2. Set registrationObject’s service worker registration to registration.

    3. Set registrationObject’s installing attribute to null.

    4. Set registrationObject’s waiting attribute to null.

    5. Set registrationObject’s active attribute to null.

    6. If registration’s installing worker is not null, then set registrationObject’s installing attribute to the result of getting the service worker object that represents registration’s installing worker in environment.

    7. If registration’s waiting worker is not null, then set registrationObject’s waiting attribute to the result of getting the service worker object that represents registration’s waiting worker in environment.

    8. If registration’s active worker is not null, then set registrationObject’s active attribute to the result of getting the service worker object that represents registration’s active worker in environment.

    9. Set objectMap[registration] to registrationObject.

  3. Return objectMap[registration].

installing attribute must return the value to which it was last set.

Note: Within a Realm, there is only one ServiceWorker object per associated service worker.

waiting attribute must return the value to which it was last set.

Note: Within a Realm, there is only one ServiceWorker object per associated service worker.

active attribute must return the value to which it was last set.

Note: Within a Realm, there is only one ServiceWorker object per associated service worker.

3.2.5. navigationPreload

The navigationPreload getter steps are to return the service worker registration’s NavigationPreloadManager object.

3.2.6. scope

The scope getter steps are to return the service worker registration’s serialized scope url.

In the example in § 3.1.2 scriptURL, the value of registration.scope, obtained from navigator.serviceWorker.ready.then(registration => console.log(registration.scope)) for example, will be "https://example.com/".

3.2.7. updateViaCache

The updateViaCache getter steps are to return the service worker registration’s update via cache mode.

3.2.8. update()

The update() method steps are:

  1. Let registration be the service worker registration.

  2. Let newestWorker be the result of running Get Newest Worker algorithm passing registration as its argument.

  3. If newestWorker is null, return a promise rejected with an "InvalidStateError" DOMException and abort these steps.

  4. If this’s relevant global object globalObject is a ServiceWorkerGlobalScope object, and globalObject’s associated service worker’s state is "installing", return a promise rejected with an "InvalidStateError" DOMException and abort these steps.

  5. Let promise be a promise.

  6. Let job be the result of running Create Job with update, registration’s storage key, registration’s scope url, newestWorker’s script url, promise, and this’s relevant settings object.

  7. Set job’s worker type to newestWorker’s type.

  8. Invoke Schedule Job with job.

  9. Return promise.

Note: The unregister() method unregisters the service worker registration. It is important to note that the currently controlled service worker client’s active service worker’s containing service worker registration is effective until all the service worker clients (including itself) using this service worker registration unload. That is, the unregister() method only affects subsequent navigations.

The unregister() method steps are:

  1. Let registration be the service worker registration.

  2. Let promise be a new promise.

  3. Let job be the result of running Create Job with unregister, registration’s storage key, registration’s scope url, null, promise, and this’s relevant settings object.

  4. Invoke Schedule Job with job.

  5. Return promise.

3.2.10. Event handler

The following is the event handler (and its corresponding event handler event type) that must be supported, as event handler IDL attributes, by all objects implementing ServiceWorkerRegistration interface:

event handler event handler event type
onupdatefound updatefound
partial interface Navigator {
  [SecureContext, SameObject] readonly attribute ServiceWorkerContainer serviceWorker;
};

partial interface WorkerNavigator {
  [SecureContext, SameObject] readonly attribute ServiceWorkerContainer serviceWorker;
};

The serviceWorker getter steps are to return the ServiceWorkerContainer object that is associated with this.

3.4. ServiceWorkerContainer

[SecureContext, Exposed=(Window,Worker)]
interface ServiceWorkerContainer : EventTarget {
  readonly attribute ServiceWorker? controller;
  readonly attribute Promise<ServiceWorkerRegistration> ready;

  [NewObject] Promise<ServiceWorkerRegistration> register((TrustedScriptURL or USVString) scriptURL, optional RegistrationOptions options = {});

  [NewObject] Promise<(ServiceWorkerRegistration or undefined)> getRegistration(optional USVString clientURL = "");
  [NewObject] Promise<FrozenArray<ServiceWorkerRegistration>> getRegistrations();

  undefined startMessages();


  // events
  attribute EventHandler oncontrollerchange;
  attribute EventHandler onmessage; // event.source of message events is ServiceWorker object
  attribute EventHandler onmessageerror;
};
dictionary RegistrationOptions {
  USVString scope;
  WorkerType type = "classic";
  ServiceWorkerUpdateViaCache updateViaCache = "imports";
};

The user agent must create a ServiceWorkerContainer object when a Navigator object or a WorkerNavigator object is created and associate it with that object.

A ServiceWorkerContainer provides capabilities to register, unregister, and update the service worker registrations, and provides access to the state of the service worker registrations and their associated service workers.

A ServiceWorkerContainer has an associated service worker client, which is a service worker client whose global object is associated with the Navigator object or the WorkerNavigator object that the ServiceWorkerContainer is retrieved from.

A ServiceWorkerContainer object has an associated ready promise (a promise or null). It is initially null.

A ServiceWorkerContainer object has a task source called the client message queue, initially empty. A client message queue can be enabled or disabled, and is initially disabled. When a ServiceWorkerContainer object’s client message queue is enabled, the event loop must use it as one of its task sources. When the ServiceWorkerContainer object’s relevant global object is a Window object, all tasks queued on its client message queue must be associated with its relevant settings object’s associated document.

controller attribute must run these steps:

  1. Let client be this’s service worker client.

  2. If client’s active service worker is null, then return null.

  3. Return the result of getting the service worker object that represents client’s active service worker in this’s relevant settings object.

Note: navigator.serviceWorker.controller returns null if the request is a force refresh (shift+refresh).

ready attribute must run these steps:

  1. If this’s ready promise is null, then set this’s ready promise to a new promise.

  2. Let readyPromise be this’s ready promise.

  3. If readyPromise is pending, run the following substeps in parallel:

    1. Let client by this’s service worker client.

    2. Let storage key be the result of running obtain a storage key given client.

    3. Let registration be the result of running Match Service Worker Registration given storage key and client’s creation URL.

    4. If registration is not null, and registration’s active worker is not null, queue a task on readyPromise’s relevant settings object’s responsible event loop, using the DOM manipulation task source, to resolve readyPromise with the result of getting the service worker registration object that represents registration in readyPromise’s relevant settings object.

  4. Return readyPromise.

Note: The returned ready promise will never reject. If it does not resolve in this algorithm, it will eventually resolve when a matching service worker registration is registered and its active worker is set. (See the relevant Activate algorithm step.)

Note: The register(scriptURL, options) method creates or updates a service worker registration for the given scope url. If successful, a service worker registration ties the provided scriptURL to a scope url, which is subsequently used for navigation matching.

The register(scriptURL, options) method steps are:

  1. Let p be a promise.

  2. Set scriptURL to the result of invoking Get Trusted Type compliant string with TrustedScriptURL, this’s relevant global object, scriptURL, "ServiceWorkerContainer register", and "script".

  3. Let client be this’s service worker client.

  4. Let scriptURL be the result of parsing scriptURL with this’s relevant settings object’s API base URL.

  5. Let scopeURL be null.

  6. If options["scope"] exists, set scopeURL to the result of parsing options["scope"] with this’s relevant settings object’s API base URL.

  7. Invoke Start Register with scopeURL, scriptURL, p, client, client’s creation URL, options["type"], and options["updateViaCache"].

  8. Return p.

getRegistration(clientURL) method steps are:

  1. Let client be this’s service worker client.

  2. Let storage key be the result of running obtain a storage key given client.

  3. Let clientURL be the result of parsing clientURL with this’s relevant settings object’s API base URL.

  4. If clientURL is failure, return a promise rejected with a TypeError.

  5. Set clientURL’s fragment to null.

  6. If the origin of clientURL is not client’s origin, return a promise rejected with a "SecurityError" DOMException.

  7. Let promise be a new promise.

  8. Run the following substeps in parallel:

    1. Let registration be the result of running Match Service Worker Registration given storage key and clientURL.

    2. If registration is null, resolve promise with undefined and abort these steps.

    3. Resolve promise with the result of getting the service worker registration object that represents registration in promise’s relevant settings object.

  9. Return promise.

getRegistrations() method steps are:

  1. Let client be this’s service worker client.

  2. Let client storage key be the result of running obtain a storage key given client.

  3. Let promise be a new promise.

  4. Run the following steps in parallel:

    1. Let registrations be a new list.

    2. For each (storage key, scope) → registration of registration map:

      1. If storage key equals client storage key, then append registration to registrations.

    3. Queue a task on promise’s relevant settings object’s responsible event loop, using the DOM manipulation task source, to run the following steps:

      1. Let registrationObjects be a new list.

      2. For each registration of registrations:

        1. Let registrationObj be the result of getting the service worker registration object that represents registration in promise’s relevant settings object.

        2. Append registrationObj to registrationObjects.

      3. Resolve promise with a new frozen array of registrationObjects in promise’s relevant Realm.

  5. Return promise.

The startMessages() method steps are to enable this’s client message queue if it is not enabled.

3.4.7. Event handlers

The following are the event handlers (and their corresponding event handler event types) that must be supported, as event handler IDL attributes, by all objects implementing the ServiceWorkerContainer interface:

event handler event handler event type
oncontrollerchange controllerchange
onmessage message
onmessageerror messageerror

The first time the onmessage setter steps are performed, enable this’s client message queue.

3.5. Events

The following event is dispatched on ServiceWorker object:

Event name Interface Dispatched when…
statechange Event The state attribute of the ServiceWorker object is changed.

The following event is dispatched on ServiceWorkerRegistration object:

Event name Interface Dispatched when…
updatefound Event The service worker registration’s installing worker changes. (See step 8 of the Install algorithm.)

The following events are dispatched on ServiceWorkerContainer object:

Event name Interface Dispatched when…
controllerchange Event The service worker client’s active service worker changes. (See step 9.2 of the Activate algorithm. The skip waiting flag of a service worker causes activation of the service worker registration to occur while service worker clients are using the service worker registration, navigator.serviceWorker.controller immediately reflects the active worker as the service worker that controls the service worker client.)
message Event The service worker client receives a message from a service worker. See postMessage(message, options).
messageerror Event The service worker client is sent a message that cannot be deserialized from a service worker. See postMessage(message, options).
[SecureContext, Exposed=(Window,Worker)]
interface NavigationPreloadManager {
  Promise<undefined> enable();
  Promise<undefined> disable();
  Promise<undefined> setHeaderValue(ByteString value);
  Promise<NavigationPreloadState> getState();
};

dictionary NavigationPreloadState {
  boolean enabled = false;
  ByteString headerValue;
};

The enable() method steps are:

  1. Let promise be a new promise.

  2. Run the following steps in parallel:

    1. Let registration be this’s associated service worker registration.

    2. If registration’s active worker is null, reject promise with an "InvalidStateError" DOMException, and abort these steps.

    3. Set registration’s navigation preload enabled flag.

    4. Resolve promise with undefined.

  3. Return promise.

The disable() method steps are:

  1. Let promise be a new promise.

  2. Run the following steps in parallel:

    1. Let registration be this’s associated service worker registration.

    2. If registration’s active worker is null, reject promise with an "InvalidStateError" DOMException, and abort these steps.

    3. Unset registration’s navigation preload enabled flag.

    4. Resolve promise with undefined.

  3. Return promise.

The setHeaderValue(value) method steps are:

  1. Let promise be a new promise.

  2. Run the following steps in parallel:

    1. Let registration be this’s associated service worker registration.

    2. If registration’s active worker is null, reject promise with an "InvalidStateError" DOMException, and abort these steps.

    3. Set registration’s navigation preload header value to value.

    4. Resolve promise with undefined.

  3. Return promise.

The getState() method steps are:

  1. Let promise be a new promise.

  2. Run the following steps in parallel:

    1. Let registration be this’s associated service worker registration.

    2. Let state be a new NavigationPreloadState dictionary.

    3. If registration’s navigation preload enabled flag is set, set state["enabled"] to true.

    4. Set state["headerValue"] to registration’s navigation preload header value.

    5. Resolve promise with state.

  3. Return promise.

4. Execution Context

Serving Cached Resources:
// caching.js
self.addEventListener("install", event => {
  event.waitUntil(
    // Open a cache of resources.
    caches.open("shell-v1").then(cache => {
      // Begins the process of fetching them. Succeeds only once all
      // resources have been stored. Even just one failing resource
      // causes the entire operation to fail.
      return cache.addAll([
        "/app.html",
        "/assets/v1/base.css",
        "/assets/v1/app.js",
        "/assets/v1/logo.png",
        "/assets/v1/intro_video.webm"
      ]);
    })
  );
});

self.addEventListener("fetch", event => {
  // No "fetch" events are dispatched to the service worker until it
  // successfully installs and activates.

  // All operations on caches are async, including matching URLs, so we use
  // promises heavily. e.respondWith() even takes promises to enable this:
  event.respondWith(
    caches.match(e.request).then(response => {
      return response || fetch(e.request);
    }).catch(() => {
      return caches.match("/fallback.html");
    })
  );
});

4.1. ServiceWorkerGlobalScope

[Global=(Worker,ServiceWorker), Exposed=ServiceWorker, SecureContext]
interface ServiceWorkerGlobalScope : WorkerGlobalScope {
  [SameObject] readonly attribute Clients clients;
  [SameObject] readonly attribute ServiceWorkerRegistration registration;
  [SameObject] readonly attribute ServiceWorker serviceWorker;

  [NewObject] Promise<undefined> skipWaiting();

  attribute EventHandler oninstall;
  attribute EventHandler onactivate;
  attribute EventHandler onfetch;

  attribute EventHandler onmessage;
  attribute EventHandler onmessageerror;
};

A ServiceWorkerGlobalScope object represents the global execution context of a service worker.

A ServiceWorkerGlobalScope object has an associated service worker (a service worker).

A ServiceWorkerGlobalScope object has an associated force bypass cache for import scripts flag. It is initially unset.

A ServiceWorkerGlobalScope object has an associated race response map which is an ordered map where the keys are requests and the values are race response.

A race response is a struct used to contain the network response when "race-network-and-fetch-handler" performs. It has a value, which is a response, "pending", or null.

Note: ServiceWorkerGlobalScope object provides generic, event-driven, time-limited script execution contexts that run at an origin. Once successfully registered, a service worker is started, kept alive and killed by their relationship to events, not service worker clients. Any type of synchronous requests must not be initiated inside of a service worker.

4.1.1. clients

The clients getter steps are to return the Clients object that is associated with this.

4.1.2. registration

The registration getter steps are to return the result of getting the service worker registration object representing this’s service worker’s containing service worker registration in this’s relevant settings object.

4.1.3. serviceWorker

The serviceWorker getter steps are to return the result of getting the service worker object that represents this’s service worker in this’s relevant settings object.

4.1.4. skipWaiting()

Note: The skipWaiting() method allows this service worker to progress from the registration’s waiting position to active even while service worker clients are using the registration.

The skipWaiting() method steps are:

  1. Let promise be a new promise.

  2. Run the following substeps in parallel:

    1. Set service worker’s skip waiting flag.

    2. Invoke Try Activate with service worker’s containing service worker registration.

    3. Resolve promise with undefined.

  3. Return promise.

4.1.5. Event handlers

The following are the event handlers (and their corresponding event handler event types) that must be supported, as event handler IDL attributes, by all objects implementing the ServiceWorkerGlobalScope interface:

event handler event handler event type
oninstall install
onactivate activate
onfetch fetch
onmessage message
onmessageerror messageerror

4.2. Client

[Exposed=ServiceWorker]
interface Client {
  readonly attribute USVString url;
  readonly attribute FrameType frameType;
  readonly attribute DOMString id;
  readonly attribute ClientType type;
  undefined postMessage(any message, sequence<object> transfer);
  undefined postMessage(any message, optional StructuredSerializeOptions options = {});
};

[Exposed=ServiceWorker]
interface WindowClient : Client {
  readonly attribute VisibilityState visibilityState;
  readonly attribute boolean focused;
  [SameObject] readonly attribute FrozenArray<USVString> ancestorOrigins;
  [NewObject] Promise<WindowClient> focus();
  [NewObject] Promise<WindowClient?> navigate(USVString url);
};

enum FrameType {
  "auxiliary",
  "top-level",
  "nested",
  "none"
};

A Client object has an associated service worker client (a service worker client).

A Client object has an associated frame type, which is one of "auxiliary", "top-level", "nested", and "none". Unless stated otherwise it is "none".

A WindowClient object has an associated browsing context, which is its service worker client’s global object’s browsing context.

A WindowClient object has an associated visibility state, which is one of visibilityState attribute value.

A WindowClient object has an associated focus state, which is either true or false (initially false).

A WindowClient object has an associated ancestor origins array.

4.2.1. url

The url getter steps are to return this’s associated service worker client’s serialized creation URL.

4.2.2. frameType

The frameType getter steps are to return this’s frame type.

4.2.3. id

The id getter steps are to return this’s associated service worker client’s id.

4.2.4. type

The type getter steps are:

  1. Let client be this’s service worker client.

  2. If client is an environment settings object, then:

    1. If client is a window client, return "window".

    2. Else if client is a dedicated worker client, return "worker".

    3. Else if client is a shared worker client, return "sharedworker".

  3. Else:

    1. Return "window".

4.2.5. postMessage(message, transfer)

The postMessage(message, transfer) method steps are:

  1. Let options be «[ "transfer" → transfer ]».

  2. Invoke postMessage(message, options) with message and options as the arguments.

4.2.6. postMessage(message, options)

The postMessage(message, options) method steps are:

  1. Let contextObject be this.

  2. Let sourceSettings be the contextObject’s relevant settings object.

  3. Let serializeWithTransferResult be StructuredSerializeWithTransfer(message, options["transfer"]). Rethrow any exceptions.

  4. Run the following steps in parallel:

    1. Let targetClient be null.

    2. For each service worker client client:

      1. If client is the contextObject’s service worker client, set targetClient to client, and break.

    3. If targetClient is null, return.

    4. Let destination be the ServiceWorkerContainer object whose associated service worker client is targetClient.

    5. Add a task that runs the following steps to destination’s client message queue:

      1. Let origin be the serialization of sourceSettings’s origin.

      2. Let source be the result of getting the service worker object that represents contextObject’s relevant global object’s service worker in targetClient.

      3. Let deserializeRecord be StructuredDeserializeWithTransfer(serializeWithTransferResult, destination’s relevant Realm).

        If this throws an exception, catch it, fire an event named messageerror at destination, using MessageEvent, with the origin attribute initialized to origin and the source attribute initialized to source, and then abort these steps.

      4. Let messageClone be deserializeRecord.[[Deserialized]].

      5. Let newPorts be a new frozen array consisting of all MessagePort objects in deserializeRecord.[[TransferredValues]], if any.

      6. Dispatch an event named message at destination, using MessageEvent, with the origin attribute initialized to origin, the source attribute initialized to source, the data attribute initialized to messageClone, and the ports attribute initialized to newPorts.

4.2.7. visibilityState

The visibilityState getter steps are to return this’s visibility state.

4.2.8. focused

The focused getter steps are to return this’s focus state.

4.2.9. ancestorOrigins

The ancestorOrigins getter steps are to return this’s associated ancestor origins array.

4.2.10. focus()

The focus() method steps are:

  1. If no Window in this origin has transient activation, return a promise rejected with an "InvalidAccessError" DOMException.

  2. Let serviceWorkerEventLoop be the surrounding agent’s event loop.

  3. Let promise be a new promise.

  4. Queue a task to run the following steps on this’s associated service worker client’s responsible event loop using the user interaction task source:

    1. Run the focusing steps with this’s browsing context.

    2. Let frameType be the result of running Get Frame Type with this’s browsing context.

    3. Let visibilityState be this’s browsing context’s active document’s visibilityState attribute value.

    4. Let focusState be the result of running the has focus steps with this’s browsing context’s active document.

    5. Let ancestorOriginsList be this’s browsing context’s active document’s relevant global object’s Location object’s ancestor origins list’s associated list.

    6. Queue a task to run the following steps on serviceWorkerEventLoop using the DOM manipulation task source:

      1. Let windowClient be the result of running Create Window Client with this’s associated service worker client, frameType, visibilityState, focusState, and ancestorOriginsList.

      2. If windowClient’s focus state is true, resolve promise with windowClient.

      3. Else, reject promise with a TypeError.

  5. Return promise.

4.2.11. navigate(url)

The navigate(url) method steps are:

  1. Let url be the result of parsing url with this’s relevant settings object’s API base URL.

  2. If url is failure, return a promise rejected with a TypeError.

  3. If url is about:blank, return a promise rejected with a TypeError.

  4. If this’s associated service worker client’s active service worker is not this’s relevant global object’s service worker, return a promise rejected with a TypeError.

  5. Let serviceWorkerEventLoop be the current global object’s event loop.

  6. Let promise be a new promise.

  7. Queue a task to run the following steps on this’s associated service worker client’s responsible event loop using the user interaction task source:

    1. Let browsingContext be this’s browsing context.

    2. If browsingContext’s associated document is not fully active, queue a task to reject promise with a TypeError, on serviceWorkerEventLoop using the DOM manipulation task source, and abort these steps.

    3. HandleNavigate: Navigate browsingContext to url, using browsingContext’s associated document, with exceptionsEnabled true.

    4. If the algorithm steps invoked in the step labeled HandleNavigate throws an exception, queue a task to reject promise with the exception, on serviceWorkerEventLoop using the DOM manipulation task source, and abort these steps.

    5. Let frameType be the result of running Get Frame Type with browsingContext.

    6. Let visibilityState be browsingContext’s active document’s visibilityState attribute value.

    7. Let focusState be the result of running the has focus steps with browsingContext’s active document.

    8. Let ancestorOriginsList be browsingContext’s active document’s relevant global object’s Location object’s ancestor origins list’s associated list.

    9. Queue a task to run the following steps on serviceWorkerEventLoop using the DOM manipulation task source:

      1. If browsingContext’s Window object’s environment settings object’s creation URL’s origin is not the same as the service worker’s origin, resolve promise with null and abort these steps.

      2. Let windowClient be the result of running Create Window Client with this’s service worker client, frameType, visibilityState, focusState, and ancestorOriginsList.

      3. Resolve promise with windowClient.

  8. Return promise.

4.3. Clients

[Exposed=ServiceWorker]
interface Clients {
  // The objects returned will be new instances every time
  [NewObject]