To make the web experience closer to native applications, Google introduced the concept of Progressive Web App (PWA) at 2016.

We will cook it with Hugo1 to make Hugo more modernization.

Service Workers

Register

First we add sw.js from offline-first-sw make Hugo support Service Workers.

After download, put it to Hugo’s readable directory. Eg. /static

Add or modify footer based Partial Templates, then add code to register Service Workers.

if('serviceWorker' in navigator) {
    const PREFETCH = true;
    const PREFETCH_LINK_RELS = ['index','next', 'prev', 'prefetch'];
    function prefetchCache() {
        if(navigator.serviceWorker.controller) {
            let links = document.querySelectorAll(
                PREFETCH_LINK_RELS.map((rel) => {
                    return 'link[rel='+rel+']';
                }).join(',')
            );
            if(links.length > 0) {
                Array.from(links)
                    .map((link) => {
                        let href = link.getAttribute('href');
                        navigator.serviceWorker.controller.postMessage({
                            action : 'cache',
                            url : href,
                        });
                    });
            }
        }
    }

    navigator.serviceWorker
        .register('/sw.js', { scope: '/' })
        .then(() => {
            console.log('Service Worker Registered');
        });

    navigator.serviceWorker
        .ready
        .then(() => {
            if(PREFETCH) {
                prefetchCache();
            }
        });
}

Configuration

CACHE_VERSION { number }

The CACHE_VERSION is important when you update your service-worker. The cache-location will be updated and the old legacy cache is getting deleted.

const CACHE_VERSION = 1;

BASE_CACHE_FILES { array }

Define files that in this list which always needs to be cached from the beginning.

const BASE_CACHE_FILES = [
    // page cache
    '/',
    '/about/',
    '/zh/about/',
    '/showcase/',
    '/zh/showcase/',
    // assets cache
    '/assets/main.js',
    '/assets/prism.js',
    '/assets/style.css',
    '/manifest.json',
    // ico cache
    '/favicon.ico',
];

OFFLINE_CACHE_FILES { array }

Define files necessary for your offline page.

const OFFLINE_CACHE_FILES = [
    '/offline.html',
];

NOT_FOUND_CACHE_FILES { array }

Define files necessary for your 404 page.

const NOT_FOUND_CACHE_FILES = [
    '/404.html',
];

CACHE_BLACKLIST { array}

This is a list of functions a URL gets checked against if it should be cached or not. If one method returns true this resource will not be cached.

const CACHE_BLACKLIST = [
    (str) => {
        return !str.startsWith('https://conight.com');
        // return !str.startsWith('http://localhost') && !str.startsWith('https://conight.com');
    },
];

It will cache all you specified resource or path. You’ll find it in Chrome’s Developer's Tools -> Cache Storage tab.

Cache Storage Cache Storage

manifest.json

manifest is a decliner file to tell browser how is your PWA look like,. You can find all manifest properties at Official website

My blog’s manifest blow:

{
  "name": "Conight's Blog",
  "short_name": "Conight's Blog",
  "description": "Share the world.",
  "icons": [
    {
      "src": "/android-chrome-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "/android-chrome-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "start_url": "/",
  "display": "standalone",
  "orientation": "portrait",
  "background_color": "#222128",
  "theme_color": "#222128"
}
  • You must provide at least the short_name or name property.
  • icons is an array of image objects. Each object should include the src, a sizes property, and the type of image. You can use online tools if you like: favicomatic.com or realfavicongenerator.net.

Then put it in head template:

<link rel="manifest" href="/manifest.json">

Lighthouse

Lighthouse, an open-source, automated tool for improving the quality of your Progressive Web Apps, eliminates much of the manual testing that was previously required. You can even use Lighthouse in continuous integration systems to catch regressions.

Enter Chrome’s Developer's Tools -> Audits, and check Progressive Web Apps. After tests, it will show you website’s report.

Lighthouse Lighthouse PWA Audits

If configure right, browser which support PWA will show Install button or notice you add to desktop.

Install Notice Install Notice

If not, Enter Chrome’s Developer's Tools -> Manifest and Installability may show reason.

Installability Manifest Installability

Expand


  1. Golang Based static blog framework. Official website ↩︎