Registering a Service Worker
Registering a service worker
Section titled “Registering a service worker”Before a service worker can intercept any requests, the page must register it. Registration tells the browser where to find the service worker file and which URLs it should control.
The registration call
Section titled “The registration call”if ('serviceWorker' in navigator) { navigator.serviceWorker .register('/sw.js') .then((registration) => { console.log('SW registered, scope:', registration.scope); }) .catch((error) => { console.error('SW registration failed:', error); });}navigator.serviceWorker.register() returns a Promise that resolves to a ServiceWorkerRegistration object. The most important property on that object is scope.
Feature detection
Section titled “Feature detection”Always guard the call with 'serviceWorker' in navigator. Browsers that do not support service workers (some very old browsers, or pages served over plain HTTP) will simply skip the block. Never let a missing API crash your page.
The scope determines which pages and sub-paths the service worker controls. By default it is the directory that contains the service worker file:
| SW file location | Default scope | Pages controlled |
|---|---|---|
/sw.js | / | The entire origin |
/app/sw.js | /app/ | Only /app/ and below |
/shop/sw.js | /shop/ | Only /shop/ and below |
You can narrow the scope (but never widen it beyond the SW file’s directory) by passing a scope option:
navigator.serviceWorker.register('/sw.js', { scope: '/shop/' });Secure context (HTTPS / localhost)
Section titled “Secure context (HTTPS / localhost)”Service workers only run on secure origins:
https://— any HTTPS page in production.http://localhostandhttp://127.0.0.1— explicitly exempted for local development.
Attempting to register on plain http:// (other than localhost) will silently fail or throw a SecurityError. Always deploy your PWA over HTTPS.
Try it live
Section titled “Try it live”The demo below registers a minimal service worker. Open the StackBlitz project and check the browser console — you will see the registration log and the SW’s scope.
Trade-offs
Section titled “Trade-offs”| Option | Benefit | Cost |
|---|---|---|
| Register the service worker at page load | Cache and offline support are ready as fast as possible | Adds work on the main thread during the very first load, while the user is waiting for critical content |
Register after the load event (deferred) | Does not compete with the critical rendering path on first load | A user who closes the tab too quickly may never get registered at all |
Common mistakes
Section titled “Common mistakes”- Registering the service worker at the wrong path for the desired scope, so it ends up controlling only part of the site instead of the whole thing.
- Not checking
if ('serviceWorker' in navigator)before registering, so older unsupported browsers throw an error mid-page. - Registering repeatedly without guarding against it, producing multiple service worker versions racing to handle fetch events.
web.dev’s own PWA checklist recommends registering the service worker after the load event so it does not compete for bandwidth with critical resources on first paint. Twitter’s PWA case study describes a similar incremental, deferred rollout strategy for its service worker (web.dev/twitter).