Service workers: what they are, and a minimal one
Published Updated
A service worker is a script the browser runs in its own worker thread, separate from any page, which can intercept network requests from the pages it controls and answer them itself. That is what makes offline support, instant repeat loads, and push possible: the worker keeps running after the tab is gone.
It has no DOM access, and it only runs in a secure context (HTTPS, or localhost
during development).
The smallest one that works
Section titled “The smallest one that works”Register it from the page:
if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js');} else { // No service worker: the site still works, it just has no offline layer.}And in /sw.js, answer requests from a cache, falling back to the network:
self.addEventListener('fetch', (event) => { event.respondWith( caches.match(event.request).then((hit) => hit || fetch(event.request)), );});That is a complete, working service worker. Everything else — precaching, update strategy, expiry — is refinement on top of these two pieces.
The lifecycle, in one pass
Section titled “The lifecycle, in one pass”A registered worker is installed, then activated, and only then does it start
controlling pages. A page loaded before the worker activated stays uncontrolled until
it is reloaded. When you ship a new sw.js, the browser installs it alongside the old
one and leaves it waiting until the old worker releases its clients — which is why
a deploy does not take effect on the very next reload unless you ask it to.
See Service worker lifecycle and The update flow and skipWaiting.
Where it commonly goes wrong
Section titled “Where it commonly goes wrong”- Scope — a worker at
/js/sw.jscontrols only/js/. Serve it from the root, or sendService-Worker-Allowed. See Registration and scope. - Stale users after a deploy — the new worker sits waiting behind the old one.
- Caching everything reflexively — a cache-first strategy on HTML strands users on an old page. Choose per request type: Caching strategies.
- Debugging it like page code — it has its own lifecycle and its own DevTools pane. See Debugging service workers.
Every topic in this section
Section titled “Every topic in this section”Where to go next
Section titled “Where to go next”- Web app manifest — the other half of an installable app.
- Install prompt — what browsers require before offering installation.
← Back to the Reference overview.