Skip to content

Instantly share code, notes, and snippets.

@yann-yinn
Created June 23, 2020 10:45
Show Gist options
  • Save yann-yinn/0371da26b66bae0271236bfc970826b4 to your computer and use it in GitHub Desktop.
Save yann-yinn/0371da26b66bae0271236bfc970826b4 to your computer and use it in GitHub Desktop.
automatic sw cache key on build for eleventy
---
permalink: sw.js
---
'use strict';
const CACHE_VERSION = {{page.date.getTime()}};
const staticCacheName = "version-" + CACHE_VERSION;
const pagesCacheName = 'pages-' + CACHE_VERSION;
const imagesCacheName = 'images-' + CACHE_VERSION;
const cacheList = [
staticCacheName,
pagesCacheName,
imagesCacheName
];
const offlinePages = [
"/",
"/index.html"
];
function updateStaticCache() {
return caches.open(staticCacheName)
.then(cache => {
// These items won't block the installation of the Service Worker
cache.addAll([
//'/assets/js/instantclick.min.js',
].concat(offlinePages));
// These items must be cached for the Service Worker to complete installation
return cache.addAll([
'/assets/css/styles.css',
]);
});
}
function stashInCache(cacheName, request, response) {
caches.open(cacheName)
.then(cache => cache.put(request, response));
}
// Limit the number of items in a specified cache.
function trimCache(cacheName, maxItems) {
caches.open(cacheName)
.then(cache => {
cache.keys()
.then(keys => {
if (keys.length > maxItems) {
cache.delete(keys[0])
.then(trimCache(cacheName, maxItems));
}
});
});
}
// Remove caches whose name is no longer valid
function clearOldCaches() {
return caches.keys()
.then(keys => {
return Promise.all(keys
.filter(key => !cacheList.includes(key))
.map(key => caches.delete(key))
);
});
}
self.addEventListener('install', event => {
event.waitUntil(updateStaticCache()
.then(() => self.skipWaiting())
);
});
self.addEventListener('activate', event => {
console.log('Finally active. Ready to start serving content!');
event.waitUntil(clearOldCaches()
.then(() => self.clients.claim())
);
});
self.addEventListener('message', event => {
if (event.data.command == 'trimCaches') {
trimCache(pagesCacheName, 35);
trimCache(imagesCacheName, 20);
}
});
self.addEventListener('fetch', event => {
let request = event.request;
let url = new URL(request.url);
// Ignore non-GET requests
if (request.method !== 'GET') {
return;
}
// For HTML requests, try the network first, fall back to the cache, finally the offline page
if (request.headers.get('Accept').includes('text/html')) {
event.respondWith(
fetch(request)
.then(response => {
// NETWORK
// Stash a copy of this page in the pages cache
let copy = response.clone();
if (offlinePages.includes(url.pathname) || offlinePages.includes(url.pathname + '/')) {
stashInCache(staticCacheName, request, copy);
} else {
stashInCache(pagesCacheName, request, copy);
}
return response;
})
.catch(() => {
// CACHE or FALLBACK
return caches.match(request)
.then(response => response || caches.match('/offline/'));
})
);
return;
}
// For non-HTML requests, look in the cache first, fall back to the network
event.respondWith(
caches.match(request)
.then(response => {
// CACHE
return response || fetch(request)
.then(response => {
// NETWORK
// If the request is for an image, stash a copy of this image in the images cache
if (request.headers.get('Accept').includes('image')) {
let copy = response.clone();
stashInCache(imagesCacheName, request, copy);
}
return response;
})
.catch(() => {
// OFFLINE
// If the request is for an image, show an offline placeholder
if (request.headers.get('Accept').includes('image')) {
return new Response('<svg role="img" aria-labelledby="offline-title" viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg"><title id="offline-title">Offline</title><g fill="none" fill-rule="evenodd"><path fill="#D8D8D8" d="M0 0h400v300H0z"/><text fill="#9B9B9B" font-family="Helvetica Neue,Arial,Helvetica,sans-serif" font-size="72" font-weight="bold"><tspan x="93" y="172">offline</tspan></text></g></svg>', {
headers: {
'Content-Type': 'image/svg+xml',
'Cache-Control': 'no-store'
}
});
}
});
})
);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment