JavaScript Navigator serviceWorker Property

Beginner
⏱️ 10 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Baseline
Secure context

What You’ll Learn

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

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.

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.

📝 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);
});

⚡ Quick Reference

GoalCode
Get containernavigator.serviceWorker
Feature detect"serviceWorker" in navigator
Registernavigator.serviceWorker.register("/sw.js")
Who controls page?navigator.serviceWorker.controller
Wait until activeawait navigator.serviceWorker.ready
List registrationsawait navigator.serviceWorker.getRegistrations()
Secure page?window.isSecureContext

🔍 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

📋 Service Worker vs Web Worker (concept)

Service WorkerWeb Worker
Entrynavigator.serviceWorkernew Worker(url)
Main jobNetwork / cache / offline (page lifecycle)Background CPU work for one page
Survives tab close?Can stay registered for the originEnds with the page
HTTPSRequired (secure context)Usually same-origin script rules
Best forPWAs, caching, pushHeavy calculations off the UI thread

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.");
}
Try It Yourself

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");
}
Try It Yourself

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.");
  });
}
Try It Yourself

How It Works

After the first successful registration, a reload is often needed before controller is set.

Example 4 — Register a Service Worker

Register a script at the site root (needs a real /sw.js file).

JavaScript
if ("serviceWorker" in navigator) {
  navigator.serviceWorker
    .register("/sw.js")
    .then((registration) => {
      console.log("Service worker registration succeeded:", registration.scope);
    })
    .catch((error) => {
      console.error("Service worker registration failed: " + error);
    });
} else {
  console.log("Service workers are not supported.");
}
Try It Yourself

How It Works

Without a same-origin worker script, registration fails — that is expected in many demos. Host a minimal sw.js to see success.

Example 5 — List Registrations

Inspect what is already registered for this origin.

JavaScript
async function listRegs() {
  if (!("serviceWorker" in navigator)) {
    return "Service workers are not supported.";
  }
  const regs = await navigator.serviceWorker.getRegistrations();
  return "registrations: " + regs.length;
}

listRegs().then(console.log);
Try It Yourself

How It Works

Useful for debugging “is anything installed?” before calling register() again.

🚀 Common Use Cases

  • Offline / cache — serve shell assets when the network is down.
  • Faster repeat visits — cache static CSS / JS / images.
  • Background sync & push — with additional APIs, notify or sync later.
  • PWA installability — service workers are part of modern installable web apps.
  • Progressive enhancement — register when supported; keep a normal site otherwise.

🧠 How navigator.serviceWorker Fits In

1

Detect support

Check "serviceWorker" in navigator on HTTPS.

Detect
2

Register a script

register("/sw.js") installs or updates the worker.

Register
3

Worker activates

Install / activate events run inside the worker script.

Lifecycle
4

Page is controlled

controller is set; fetch events can serve cached responses.

📝 Notes

  • Baseline Widely available (MDN, since April 2018).
  • Not Deprecated, Experimental, or Non-standard — no status banner required.
  • Secure context required (HTTPS / localhost).
  • May be unavailable in private browsing — feature-detect.
  • Related: storage, onLine, locks, Window.

Universal Browser Support

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.

Universal Widely available
Google Chrome Service workers · Desktop & Mobile
Full support
Mozilla Firefox Service workers · Desktop & Mobile
Full support
Apple Safari Service workers · macOS & iOS
Full support
Microsoft Edge Service workers · Chromium
Full support
Opera Service workers · Modern versions
Full support
Internet Explorer No service worker support
Unavailable
serviceWorker Excellent

Bottom line: Feature-detect, use HTTPS, register a same-origin sw.js, then check controller / ready for control status.

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.

Continue with storage, locks, or the JavaScript hub.

💡 Best Practices

✅ Do

  • Feature-detect with "serviceWorker" in navigator
  • Serve over HTTPS (or localhost)
  • Keep sw.js small and well-versioned
  • Handle registration failures with .catch()
  • Test private mode and first-visit vs reload

❌ Don’t

  • Assume service workers work on plain HTTP
  • Forget that private mode may disable them
  • Register without a real same-origin script URL
  • Block the whole app if registration fails
  • Assign to navigator.serviceWorker

Key Takeaways

Knowledge Unlocked

Five things to remember about serviceWorker

Baseline container — detect, register on HTTPS, check controller and ready.

5
Core concepts
🚀 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.

Learn storage Next

Estimate origin quota and request persistent storage for PWAs.

storage →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful