Blog Add a service worker for offline-first pages
Add a service worker for offline-first pages
TL;DR A service worker sits between your page and the network, serving cached responses so the site loads instantly and works offline. Register it, cache the core assets on install, serve from cache with a network fallback, and handle updates carefully so users are not stuck on an old version.
A service worker is what turns a normal website into one that loads instantly and works offline. It is a script the browser runs in the background that can intercept requests and answer them from a cache. Powerful, and easy to misuse. Here is the safe version.
The lifecycle
A service worker has a lifecycle you have to respect: it registers, installs, activates, and then controls the page. You cache your core assets during install, clean up old caches on activate, and intercept requests once it is in control.
Register it from your page:
if ("serviceWorker" in navigator) {
navigator.serviceWorker.register("/sw.js");
}
Cache the core on install
When the worker installs, pre-cache the assets your site needs to render, its shell:
self.addEventListener("install", (e) => {
e.waitUntil(
caches.open("v1").then((cache) =>
cache.addAll(["/", "/styles.css", "/app.js"])
)
);
});
Now those assets are available instantly and offline.
Serve from cache, fall back to network
Intercept requests and answer from the cache, falling back to the network on a miss:
self.addEventListener("fetch", (e) => {
e.respondWith(
caches.match(e.request).then((hit) => hit || fetch(e.request))
);
});
For content that changes often, flip it, try the network first and fall back to cache, so users get fresh content but still have something offline. Match the strategy to how fresh each resource needs to be.
The update pitfall
Here is where service workers bite people: they can trap users on an old version. If you cache aggressively without a clear update path, a deploy does not reach anyone, because they keep being served the cached old files.
The fix is to manage updates deliberately: version your caches, clean up old ones when a new worker activates, and take control of open pages so a new version actually takes effect. Cache with a plan for how the next version gets in.
The payoff, and the caution
Done well, a service worker makes your site load instantly on repeat visits and keep working with no connection, which is a genuinely great experience. Done carelessly, it serves stale content that users cannot escape. The whole difference is having a caching strategy and an update strategy, not just a cache. Add both, and offline-first is a real upgrade rather than a support headache.
FAQ
What is a service worker?
It is a script the browser runs in the background, separate from your page, that can intercept network requests. That lets it serve responses from a cache, so your site can load instantly and keep working when the user is offline.
What is a safe caching strategy to start with?
Cache the core assets, the shell of your site, when the service worker installs, then serve requests from the cache with a fallback to the network. For content that changes, prefer the network and fall back to cache. Match the strategy to how fresh each thing needs to be.
What is the common service worker pitfall?
Getting users stuck on a cached old version. If you cache aggressively without a clear update path, people keep seeing stale content after you deploy. You need a strategy to update the cache and activate the new service worker so changes actually reach users.