Service workers with Hugo

Published:
Talks about: , and

In order to use a serviceworker to cache a Hugo site, configure a media type in your config.toml:

[mediaTypes."application/javascript"]
  suffixes = ["js"]
[outputFormats.ServiceWorker]
  name = "ServiceWorker"
  mediaType = "application/javascript"
  baseName = "serviceworker"
  isPlainText = false
  rel = "alternate"
  isHTML = false
  noUgly = true
  permalinkable = false

Create a new layout, e.g. in _default/home.serviceworker.js with the following content:

const CACHE = 'cache-and-update';

self.addEventListener('install', (event) => {
  event.waitUntil(precache());
});

self.addEventListener('fetch', (event) => {
  event.respondWith(fromCache(event.request));
  event.waitUntil(update(event.request));
});

const precache = async () => {
    const cache = await caches.open(CACHE);
    return await cache.addAll([
        {{ range $i, $e := .Site.RegularPages }}
        '{{ $.RelPermalink }}'{{ if $i }}, {{ end }}
        {{ end }}
    ]);
}

const fromCache = async (request) => {
    const cache = await caches.open(CACHE);
    const match = await cache.match(request);
    return match || Promise.reject('no-match');
}

const update = async (request) => {
    const cache = await caches.open(CACHE);
    const response = await fetch(request);
    return await cache.put(request, response);
}