Offline Fallback Page
Serve a cached fallback page when the user is offline.
Offline Fallback Page is a free HTML Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the HTML Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Why an Offline Page?
When the network is unavailable, a service worker can serve a custom offline fallback instead of the browser's generic "no internet" error. The user sees the brand, useful information, and any cached content — much better than a Chromium dinosaur or Firefox sad-tab.
Caching the Fallback
In the service worker's install event, pre-cache the offline.html page so it is always available, even before the user navigates anywhere offline. The browser ensures the cache survives until the next sw.js change.
const CACHE = "v1";
self.addEventListener("install", (e) => {
e.waitUntil(
caches.open(CACHE).then((c) => c.addAll(["/offline.html", "/offline.css", "/logo.svg"]))
);
});Serving on Failure
In the fetch event, attempt the network first; on failure, return the cached offline.html. This pattern (network-first with offline fallback) is the simplest PWA recipe and works for most content sites.
self.addEventListener("fetch", (e) => {
if (e.request.mode !== "navigate") return;
e.respondWith(
fetch(e.request).catch(() => caches.match("/offline.html"))
);
});Mode Navigate Check
Only fall back to offline.html for navigation requests (top-level page loads). For images, scripts, and other subresource fetches, let them fail or fall back to per-resource cached copies — serving an HTML page in place of a missing image breaks the page worse.
Designing the Offline Page
Keep the offline page light: minimal CSS, no external assets unless they are also cached. Show the brand logo, a friendly message ("You're offline — content will load when you reconnect"), and a Retry button that calls location.reload().
<!doctype html>
<html lang="en">
<head><meta charset="utf-8"><title>Offline</title>
<style>body{font-family:sans-serif;text-align:center;padding:2rem}</style>
</head>
<body>
<h1>You're offline</h1>
<p>This page is unavailable without an internet connection.</p>
<button onclick="location.reload()">Try again</button>
</body>
</html>Caching Visited Pages
Beyond a single offline page, cache successfully loaded pages with a stale-while-revalidate or runtime cache strategy. Returning to a recently-viewed article without network still shows the content, only failing for unseen pages.
Cache Version Updates
When you update the offline.html, change the CACHE constant in sw.js (CACHE = "v2"). In the activate event, delete old caches: caches.keys().then(keys => keys.filter(k => k !== CACHE).forEach(k => caches.delete(k))). Stale offline pages are confusing.
Testing Offline
Chrome DevTools Network panel → "Offline" throttling simulates no network. Navigate around your app; verify the offline page appears for unseen routes and that previously visited pages still load from cache.
Failure of Subresources
If the offline page itself references an uncached CSS file, that file fails to load offline and the page renders without styles. Pre-cache every asset the offline page needs (CSS, logo, fonts) in the install handler.
Beyond Static Offline
Advanced PWAs queue user actions while offline using Background Sync, retry them when connectivity returns, and show optimistic UI in the meantime. The Workbox library provides recipes for these patterns; rolling your own is also feasible but more work.
Connection Restoration
Listen for the online event on the offline page to detect reconnection: window.addEventListener("online", () => location.reload()). The page reloads itself the moment connectivity returns — without the user needing to tap Retry.
Lie Carefully
"Try again" buttons should genuinely retry — call location.reload(), not a fake spinner that does nothing. Honest UI maintains user trust; deceptive offline pages damage credibility quickly when users notice.
Knowledge Check
Why should the offline.html fallback only be returned for navigation requests (e.request.mode === "navigate") and not for all failed requests?
Summary
Service workers can serve a custom offline fallback page instead of the browser's generic error. Pre-cache offline.html in install, serve it in fetch when the network fails and the request is a navigation. Keep the page self-contained, version the cache for updates, listen to the online event for auto-reload. Test with DevTools offline throttling.
Frequently asked questions
Is the “Offline Fallback Page” lesson free?
Yes — the full text of “Offline Fallback Page” is free to read here on the web, and the HTML Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the HTML Academy course, upgrade to CoddyKit PRO.
What will I learn in “Offline Fallback Page”?
Serve a cached fallback page when the user is offline. You practise HTML Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start HTML Academy?
No prior experience is required. HTML Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Offline Fallback Page” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this HTML Academy lesson?
Yes. Every HTML Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- The Web App Manifest
- Service Worker Registration from HTML
- Theme Color and App Icons
- Offline Fallback Page