navigator.serviceWorker is the entry point for the Service Worker API. Learn the ServiceWorkerContainer, feature detection, register(), controller, ready, secure context rules, five examples, and try-it labs.
01
Kind
Read-only property
02
Returns
ServiceWorkerContainer
03
Baseline
Widely available
04
Context
Secure (HTTPS)
05
Register
register()
06
Control?
controller
Fundamentals
Introduction
A service worker is a background script that can intercept network requests, cache assets, and help your site work offline or load faster — a core piece of many Progressive Web Apps (PWAs).
navigator.serviceWorker returns a ServiceWorkerContainer. That object lets you register a worker script, check whether this page is already controlled, wait until a worker is ready, and listen for messages / controller changes.
💡
Beginner check (MDN)
Start with feature detection: if ("serviceWorker" in navigator) { /* Supported! */ }
⚠️
Private mode
MDN notes service workers may be unavailable in private / incognito browsing. Always feature-detect and keep a normal online-only path.
Concept
Understanding the serviceWorker Property
Think of navigator.serviceWorker as the desk that manages service workers for this document — not the worker script itself.
ServiceWorkerContainer — object returned by the property.
register(scriptURL) — install or update a service worker script.
controller — the active worker controlling this page, or null.
ready — Promise that resolves when an active registration exists.
getRegistration / getRegistrations — look up existing registrations.
Secure context — HTTPS / localhost required.
Foundation
📝 Syntax
General form of the property:
JavaScript
navigator.serviceWorker
Value
A ServiceWorkerContainer object when service workers are available.
Common patterns
JavaScript
// Feature-detect (MDN):
if ("serviceWorker" in navigator) {
// Supported!
}
// Register a worker at the site root (needs a real /sw.js file):
navigator.serviceWorker
.register("/sw.js")
.then((registration) => {
console.log("Service worker registration succeeded:", registration);
})
.catch((error) => {
console.error("Service worker registration failed: " + error);
});
// Is this page controlled right now?
if (navigator.serviceWorker.controller) {
console.log("Controlled by:", navigator.serviceWorker.controller);
}
// Wait until an active worker is ready:
navigator.serviceWorker.ready.then((reg) => {
console.log("Ready registration:", reg.scope);
});
Cheat Sheet
⚡ Quick Reference
Goal
Code
Get container
navigator.serviceWorker
Feature detect
"serviceWorker" in navigator
Register
navigator.serviceWorker.register("/sw.js")
Who controls page?
navigator.serviceWorker.controller
Wait until active
await navigator.serviceWorker.ready
List registrations
await navigator.serviceWorker.getRegistrations()
Secure page?
window.isSecureContext
Snapshot
🔍 At a Glance
Four facts to remember about navigator.serviceWorker.
Returns
ServiceWorkerContainer
API entry point
Status
Baseline
Widely available
HTTPS
required
Secure context
Key call
register()
Install / update
Compare
📋 Service Worker vs Web Worker (concept)
Service Worker
Web Worker
Entry
navigator.serviceWorker
new Worker(url)
Main job
Network / cache / offline (page lifecycle)
Background CPU work for one page
Survives tab close?
Can stay registered for the origin
Ends with the page
HTTPS
Required (secure context)
Usually same-origin script rules
Best for
PWAs, caching, push
Heavy calculations off the UI thread
Hands-On
Examples Gallery
Examples follow MDN navigator.serviceWorker / ServiceWorkerContainer patterns. Prefer Try It Yourself on HTTPS. Registration needs a real service worker file (for example /sw.js) on your origin.
📚 Getting Started
Detect support and confirm a secure context.
Example 1 — Feature Detection
MDN’s beginner check for service worker support.
JavaScript
if ("serviceWorker" in navigator) {
console.log("Supported!");
} else {
console.log("Service workers are not supported.");
}
Supported!
(or "Service workers are not supported.")
How It Works
This is the gate before any register() call. Private mode may print the unsupported path.
Example 2 — Secure Context Check
Service workers require HTTPS / localhost.
JavaScript
console.log("secure: " + window.isSecureContext);
console.log("serviceWorker in navigator: " + ("serviceWorker" in navigator));
if (!window.isSecureContext) {
console.log("Serve over HTTPS (or localhost) to use service workers");
} else if (!("serviceWorker" in navigator)) {
console.log("Secure, but service workers not exposed");
} else {
console.log("Ready to inspect controller / register");
}
secure: true
serviceWorker in navigator: true
Ready to inspect controller / register
How It Works
Localhost counts as a secure context for development.
📈 Practical Patterns
Controller checks, registration, and listing existing workers.
Example 3 — Is the Page Controlled?
Read controller and listen for controllerchange (MDN idea).
JavaScript
if (!("serviceWorker" in navigator)) {
console.log("Service workers are not supported.");
} else if (navigator.serviceWorker.controller) {
console.log("This page is currently controlled by a service worker.");
} else {
console.log("No controlling service worker yet.");
}
if ("serviceWorker" in navigator) {
navigator.serviceWorker.addEventListener("controllerchange", () => {
console.log("Controller changed — a new worker took control.");
});
}
navigator.serviceWorker is Baseline Widely available across modern browsers (MDN: since April 2018). It requires a secure context (HTTPS / localhost) and may be missing in private mode.
✓ Baseline · Widely available
Navigator.serviceWorker
ServiceWorkerContainer entry point for PWAs — register, control, and communicate with service workers.
UniversalWidely available
Google ChromeService workers · Desktop & Mobile
Full support
Mozilla FirefoxService workers · Desktop & Mobile
Full support
Apple SafariService workers · macOS & iOS
Full support
Microsoft EdgeService workers · Chromium
Full support
OperaService workers · Modern versions
Full support
Internet ExplorerNo service worker support
Unavailable
serviceWorkerExcellent
Bottom line: Feature-detect, use HTTPS, register a same-origin sw.js, then check controller / ready for control status.
Wrap Up
Conclusion
navigator.serviceWorker is the Baseline entry point to ServiceWorkerContainer. Feature-detect it, stay on HTTPS, register a same-origin worker script, and use controller / ready to know when your page is controlled.
Baseline container — detect, register on HTTPS, check controller and ready.
5
Core concepts
📄01
Returns
ServiceWorkerContainer
Value
🚀02
Register
register()
API
🔒03
HTTPS
required
Security
📈04
Control
controller
State
🎯05
Detect
in navigator
First step
❓ Frequently Asked Questions
It is a read-only Navigator property that returns a ServiceWorkerContainer for the document — the entry point to register, update, remove, and talk to service workers.
No. MDN marks it Baseline Widely available (since April 2018). It is not Deprecated, Experimental, or Non-standard.
Yes. It is available only in secure contexts (HTTPS or localhost) in supporting browsers.
Use MDN’s check: if ("serviceWorker" in navigator) { /* Supported! */ }
navigator.serviceWorker.controller is the ServiceWorker actively controlling this page, or null if none is controlling it yet.
MDN notes the feature may not be available in private/incognito browsing. Always feature-detect and keep a non-SW path.
Did you know?
After you register a service worker for the first time, the page often is not controlled until a reload. Checking navigator.serviceWorker.controller (and listening for controllerchange) helps you explain that to users.