Skip to content

Debugging service workers

In one line: The Application panel in Chrome DevTools (and equivalent panels in Firefox and Safari) lets you inspect the registration state, force updates, test offline, clear caches, and observe fetch event interception — all without deploying a change.

The primary debugging surface. Open DevTools → Application → Service Workers (left sidebar).

Control What it does
Update on reload Forces a byte-comparison check and installs a new worker every navigation
Bypass for network Disables the service worker for this tab — all fetch events pass through
Offline Simulates no network for requests going through the service worker
Update Triggers registration.update() manually
Unregister Removes the registration entirely

The panel also shows the current state: installing, waiting, or activated — plus the script URL and scope.

The “Update on reload” checkbox is the fastest way to test worker changes in development. Without it, Chrome serves the cached worker script for up to 24 hours even if the file changes, and the browser only installs a new worker when it detects a byte difference.

If a new worker is stuck in waiting, the panel shows a “skipWaiting” link that calls skipWaiting() immediately for the pending worker — useful for testing without modifying the worker code.

DevTools → Application → Cache Storage lists all named caches and their entries. You can inspect request/response headers, preview response bodies, and delete individual entries or entire caches.

Open the Network panel and enable the Service Worker column (right-click on column headers). Each request shows whether it was served from the service worker, from cache, or from the network. The (ServiceWorker) label in the “Size” column confirms the worker intercepted the request.

Switch the DevTools console’s JavaScript context (the dropdown next to the filter bar) from “top” to the service worker URL. console.log calls inside the worker appear in this context.

You can also evaluate expressions against the worker’s global scope, including inspecting self.registration, caches.keys(), and self.clients.matchAll().

Open about:debugging#/runtime/this-firefox → “This Firefox” → “Service Workers”. Firefox lists every registered worker with its scope, state, and a Inspect link that opens a dedicated console for that worker.

Firefox does not have a built-in “Update on reload” checkbox. To force a re-install during development, unregister the worker and reload, or call registration.update() in the page console.

In Safari (iOS or macOS), enable the Develop menu (Preferences → Advanced → Show Develop menu). Open Web Inspector → Storage → Service Workers. Safari lists registered workers, their scopes, and the script URL.

Safari Web Inspector has more limited debugging surfaces than Chrome or Firefox: there is no dedicated cache viewer or “force update” checkbox. Use the console in the worker context for caches.keys() inspection.

Symptom Likely cause Fix
Worker stuck in waiting Old tabs still open and no skipWaiting() Close all tabs, or use DevTools “skipWaiting” link
New code not running after deploy HTTP cache serving the old worker script Use updateViaCache: 'none' or set Cache-Control: no-cache on the worker URL
Requests not intercepted Worker not yet activated (still installing) or scope mismatch Check scope in DevTools; reload after activation
Cache not populated install failed or event.waitUntil() was not called Check the console in the worker context for errors
Stale content served CacheFirst strategy with no expiration Add ExpirationPlugin or version your cache name
Offline fallback not shown Fallback not pre-cached in install, or wrong fetch event guard Check Cache Storage for the fallback URL; add logging

Workbox emits verbose logs in development builds. When using Workbox, switch to the development build during debugging:

import { setCacheNameDetails } from 'workbox-core';
// Development builds log strategy decisions to the console

Workbox’s development build is automatically selected when process.env.NODE_ENV !== 'production'.

  • Enable “Update on reload” in DevTools during development to avoid cached-worker confusion.
  • Open the worker console context to see worker-side console.log output.
  • Use “Bypass for network” when you want to test behavior without the service worker temporarily.
  • After a deploy, verify Cache Storage contains only the new cache version and old caches are deleted.
  • Test the offline fallback by checking “Offline” in DevTools Network and navigating to an uncached URL.