Handling Dynamic and Static Content Offline
A fully functional offline PWA must cache both static assets and dynamic content.
1. Caching HTML Pages for Offline Use
To cache full pages dynamically, modify service_worker.js
:
self.addEventListener("fetch", (event) => {
if (event.request.mode === "navigate") {
event.respondWith(
fetch(event.request)
.then((response) => {
return caches.open("pages-cache").then((cache) => {
cache.put(event.request, response.clone());
return response;
});
})
.catch(() => caches.match("/offline.html"))
);
}
});
This ensures that:
- HTML pages are cached when first visited.
- If offline, an offline fallback page is displayed.
2. Preloading Key Static Assets
To make the app available offline instantly, pre-cache key assets during the service worker’s installation:
const STATIC_CACHE_NAME = "static-assets-v1";
const STATIC_ASSETS = [
"/",
"/offline.html",
"/assets/logo.png",
"/stylesheets/application.css",
];
self.addEventListener("install", (event) => {
event.waitUntil(
caches.open(STATIC_CACHE_NAME).then((cache) => {
return cache.addAll(STATIC_ASSETS);
})
);
});
- When the service worker installs, key assets are preloaded into the cache.
- Users get a faster experience even on first load.
3. Providing a Reliable Offline Experience
If a user navigates to a page that is not cached, a proper fallback should be provided.
1. Create an Offline Page (public/offline.html
):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Offline Mode</title>
</head>
<body>
<h1>You are offline</h1>
<p>Please check your connection and try again.</p>
</body>
</html>
2. Serve the Offline Page from the Service Worker
Modify service_worker.js
to return this page when a request fails:
self.addEventListener("fetch", (event) => {
event.respondWith(
fetch(event.request).catch(() => caches.match("/offline.html"))
);
});
This ensures that even if a user visits a page that hasn’t been cached, they see a friendly offline page instead of a browser error.