Glossary

Definition

Service worker registration

Short definition

Registration happens when a page calls navigator.serviceWorker.register("/sw.js", { scope: "/app/" }). The scope option (defaulting to the directory the script is served from) determines which pages the worker is allowed to control — a worker at /sw.js served with no scope option can normally only control /*, but serving it with the Service-Worker-Allowed HTTP header lets it claim a scope above its own script location.

Reviewed July 28, 2026

register() returns a promise that resolves to a ServiceWorkerRegistration object once the browser has at least accepted the script for install; it does not wait for the install or activate steps to finish.

A page can only be controlled by one active service worker at a time; registering a second worker at an overlapping scope replaces the first one for new navigations once the update cycle completes.

Scope is matched by URL prefix, so a worker registered with scope "/app/" controls "/app/settings" but not "/blog/post-1", even if both are served from the same origin.

You can inspect live registrations from the browser with navigator.serviceWorker.getRegistrations(), which is often the first debugging step when a PWA seems to be running stale code.

Related terms
Service worker
A service worker is a JavaScript file the browser runs in the background, separate from the page. It intercepts network requests, caches responses so the site works offline, and receives web-push events so the site can notify the user when it is closed.
Service worker update cycle
Browsers check a registered service worker's script for updates on every navigation to a page in scope, and at least every 24 hours in the background, by re-fetching the script URL and comparing it byte-for-byte against the currently installed version. Any difference — even a single changed character or comment — triggers a fresh install/waiting/activate cycle for a new worker instance.
scope (manifest field)
scope is a manifest field, for example "scope": "/app/", that defines the URL prefix the browser considers part of the installed app. Navigating within scope keeps the app in standalone mode; navigating outside it (such as to an external payment page) typically opens a normal browser tab or an in-app browser bar.
Cache Storage API
The Cache Storage API, exposed as the global caches object, lets a service worker (or page) store Request/Response pairs in named caches, e.g. caches.open("shell-v1").then((cache) => cache.put("/logo.png", response)). Unlike the HTTP cache, it is fully scriptable, has no automatic eviction schedule tied to headers, and persists until explicitly deleted or the storage quota is exceeded.
Cache-first strategy
Cache-first is a fetch-handling strategy: event.respondWith(caches.match(event.request).then((cached) => cached ?? fetch(event.request))). It serves cached content instantly and skips the network entirely when a match exists, making it ideal for versioned, immutable assets such as hashed JS/CSS bundles or app-shell icons that never change once deployed.
Network-first strategy
Network-first is a fetch-handling strategy: event.respondWith(fetch(event.request).then((res) => { cache.put(event.request, res.clone()); return res; }).catch(() => caches.match(event.request))). It prioritises up-to-date data and only serves a cached copy if the network request fails outright, making it the standard choice for API calls and frequently changing pages.