← Recipes

阅读中文版本

Serve an Offline Page with a Service Worker

Precache a shell and a fallback page, use a network-first strategy for navigation, and clean up old caches so users see a clear offline experience.

~45 minpwaofflinefrontend

Task

Add a service worker that serves a cached fallback when navigation requests fail.

When to use this

When the network drops, the app shows the browser error page instead of a branded offline screen with cached navigation.

Prerequisites

  • An HTTPS origin (service workers require a secure context)
  • A build step that can emit the offline page

Steps

1. Precache the offline document and shell assets during install.

Expected output: The fallback is available before any runtime fetch.

2. Use a network-first strategy for navigations and fall back to the cached offline page.

Expected output: Online users get fresh HTML; offline users get the fallback.

3. Handle the fetch event only for same-origin GET requests.

Expected output: The worker does not interfere with API POSTs or cross-origin calls.

4. Delete caches whose names no longer match the current version on activate.

Expected output: Storage does not grow with every deploy.

Troubleshooting

Problem

Users stuck on old version

Solution

Use skipWaiting and clients.claim deliberately, or prompt the user to reload, so the new worker takes control.

Problem

Offline page not shown

Solution

Confirm the fallback URL is in the precache list and the navigation fallback is wired into the fetch handler.

Limitations

  • Service workers only run in secure contexts and are unsupported in some embedding scenarios.
  • Aggressive caching of HTML can serve stale pages if the strategy is cache-first by mistake.

Context

Add a service worker that serves a cached fallback when navigation requests fail. When the network drops, the app shows the browser error page instead of a branded offline screen with cached navigation.

Steps

  1. Precache the offline document and shell assets during install. Expected: The fallback is available before any runtime fetch.
  2. Use a network-first strategy for navigations and fall back to the cached offline page. Expected: Online users get fresh HTML; offline users get the fallback.
  3. Handle the fetch event only for same-origin GET requests. Expected: The worker does not interfere with API POSTs or cross-origin calls.
  4. Delete caches whose names no longer match the current version on activate. Expected: Storage does not grow with every deploy.
self.addEventListener('fetch', (event) => {
  if (event.request.mode === 'navigate') {
    event.respondWith(fetch(event.request).catch(() => caches.match('/offline.html')));
  }
});

Verify

  • The fallback is available before any runtime fetch.
  • Online users get fresh HTML; offline users get the fallback.
  • The worker does not interfere with API POSTs or cross-origin calls.
  • Storage does not grow with every deploy.

Limits

  • Service workers only run in secure contexts and are unsupported in some embedding scenarios.
  • Aggressive caching of HTML can serve stale pages if the strategy is cache-first by mistake.