Skip to content

Below are all the necessary files and their contents. Place them under your docs/ folder so that MkDocs will copy them into site/ on build.


  1. docs/sw.js

const CACHE_NAME = 'mkdocs-offline-v1'; const URLS_TO_CACHE = [ '/', '/index.html', '/offline.html', '/css/offline.css', '/manifest.json', '/js/register-sw.js', '/js/update-handler.js', ];

// Install – cache core assets self.addEventListener('install', event => { event.waitUntil( caches.open(CACHE_NAME) .then(cache => cache.addAll(URLS_TO_CACHE)) ); });

// Activate – clean up old caches self.addEventListener('activate', event => { event.waitUntil( caches.keys().then(keys => Promise.all( keys.filter(k => k !== CACHE_NAME) .map(k => caches.delete(k)) ) ) ); });

// Fetch – serve from cache, fall back to network, offline fallback self.addEventListener('fetch', event => { event.respondWith( caches.match(event.request).then(cached => { if (cached) return cached; return fetch(event.request).catch(() => { // If navigation request fails, show offline page if (event.request.mode === 'navigate') { return caches.match('/offline.html'); } }); }) ); });


  1. docs/js/register-sw.js

if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker .register('/sw.js') .catch(err => console.error('SW registration failed:', err)); }); }


  1. docs/js/update-handler.js

if ('serviceWorker' in navigator) { navigator.serviceWorker.ready.then(reg => { reg.addEventListener('updatefound', () => { const newWorker = reg.installing; newWorker.addEventListener('statechange', () => { if (newWorker.state === 'installed') { showUpdateNotification(); } }); }); }); }

function showUpdateNotification() { const notice = document.createElement('div'); notice.className = 'offline-notice'; notice.textContent = 'New content available – please refresh.'; document.body.appendChild(notice); notice.style.display = 'block'; }


  1. docs/css/offline.css

.offline-notice { position: fixed; bottom: 20px; right: 20px; background: #ff9800; color: #fff; padding: 12px; border-radius: 4px; box-shadow: 0 2px 6px rgba(0,0,0,0.2); z-index: 9999; display: none; font-family: sans-serif; }


  1. docs/offline.html
Offline

You’re Offline

Sorry, you need an internet connection to view this page.

Retry


  1. docs/manifest.json

{ "name": "My Docs", "short_name": "Docs", "start_url": "/", "display": "standalone", "background_color": "#ffffff", "theme_color": "#4CAF50", "icons": [ { "src": "assets/images/icon-192.png", "sizes": "192x192", "type": "image/png" } ] }


  1. mkdocs.yml snippets

Make sure you include these lines so MkDocs will copy your files into the built site:

site_name: My Docs

extra_javascript: - sw.js - js/register-sw.js - js/update-handler.js

extra_css: - css/offline.css

If you haven’t already, tell MkDocs to include offline.html at root:

nav: - Home: index.md - Offline: offline.html


✅ Build & Deploy

mkdocs build mkdocs gh-deploy --clean

Final verification:

Visit https://.github.io/sw.js → should load the JS, not 404.

In Chrome DevTools → Application → Service Workers → should show your SW as active.

In Network tab (“Offline” checked) → reload → pages in cache still load; others fall back to offline.html.