5.2 KiB
5.2 KiB
GOHUGO PWA SETUP
layouts/partials/custom_head.html
<!-- A partial to be overwritten by the user.
Simply place a custom_head.html into
your local /layouts/partials-directory -->
<div id="sw-update" hidden>
<span>A new version is available.</span>
<button id="sw-update-button" type="button">
Reload
</button>
</div>
<style>
#sw-update {
position: fixed;
right: 1rem;
bottom: 1rem;
z-index: 1000;
padding: 0.75rem 1rem;
color: white;
background: #222;
border-radius: 0.4rem;
box-shadow: 0 0.25rem 1rem rgb(0 0 0 / 25%);
}
#sw-update button {
margin-left: 0.75rem;
}
</style>
<script>
if ("serviceWorker" in navigator) {
let refreshing = false;
navigator.serviceWorker.addEventListener("controllerchange", () => {
if (refreshing) {
return;
}
refreshing = true;
window.location.reload();
});
navigator.serviceWorker.register("/sw.js").then((registration) => {
function showUpdatePrompt(worker) {
const prompt = document.querySelector("#sw-update");
const button = document.querySelector("#sw-update-button");
prompt.hidden = false;
button.addEventListener("click", () => {
worker.postMessage({
type: "SKIP_WAITING"
});
}, { once: true });
}
// Handle an update that was already waiting.
if (registration.waiting) {
showUpdatePrompt(registration.waiting);
}
registration.addEventListener("updatefound", () => {
const worker = registration.installing;
if (!worker) {
return;
}
worker.addEventListener("statechange", () => {
if (
worker.state === "installed" &&
navigator.serviceWorker.controller
) {
showUpdatePrompt(worker);
}
});
});
// Ask the browser to check for a newer sw.js.
registration.update();
});
}
</script>
layouts/partials/custom_body.html
<script src="/main.js"></script>
static/main.js
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js')
.then(req => {
console.log('Registered!', reg);
}).catch(err => {
console.log('Registration failed: ', err);
});
});
}
static/manifest.webmanifest
{
"name": "Pat K",
"short_name": "PK",
"start_url": "/",
"scope": "/",
"background_color": "#000000",
"theme_color": "#2e1e3c",
"display": "standalone",
"id": "5801e2e4fab6956ac349d7c724329b869cbffb19e87e545cd5bf6ffb2cc4a3e7",
"icons": [
{
"src": "icons/192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "icons/512.png",
"type": "image/png",
"sizes": "512x512"
}
]
}
static/icons
ffmpeg -i example.png -vf "scale=192:192" icon-192.png
ffmpeg -i example.png -vf "scale=512:512" icon-512.png
hugo.toml
[outputs]
home = ["HTML", "SW"]
[outputFormats.SW]
mediaType = "text/javascript"
baseName = "sw"
isPlainText = true
notAlternative = true
themes/hugo-bearblog/layouts/index.sw.js
const CACHE_NAME = "patk-{{ now.Unix }}";
const PRECACHE = [
"/index.html",
"/manifest.webmanifest",
"/main.js",
"/robots.txt",
"/icons/192.png",
"/icons/512.png",
"/404.html",
"/sitemap.xml",
{{- range hugo.Sites }}
{{- range .Pages }}
{{ printf "%q" .RelPermalink }},
{{- end }}
{{- end }}
];
self.addEventListener("install", (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => {
return cache.addAll(PRECACHE);
})
);
// self.skipWaiting(); // remove if want to changes to occur without pressing reload button
});
self.addEventListener("activate", (event) => {
event.waitUntil(
caches.keys().then((keys) => {
return Promise.all(
keys
.filter((key) => key !== CACHE_NAME)
.map((key) => caches.delete(key))
);
})
);
self.clients.claim();
});
self.addEventListener("fetch", (event) => {
event.respondWith(
caches.match(event.request).then((cachedResponse) => {
return cachedResponse || fetch(event.request);
// return fetch(event.request) || cachedResponse; // switch if you want to fetch resources first and serve cached if offline; current serve cache then request online fetch if error or not available
})
);
});
self.addEventListener("message", (event) => {
if (event.data?.type === "SKIP_WAITING") {
self.skipWaiting();
}
});
Makefile
- Make file requires tabs not space indentation
.PHONY: help cl gen serve pub dev
help:
@echo "Usage: make <option>"
@echo "gen ..... generate site"
@echo "serve ... generate site and http serve 8080"
@echo "dev ..... hugo serve"
@echo "pub ..... generate and publish to griffin nginx-blog/config/www"
cl:
@clear
gen:
hugo --cleanDestinationDir
serve: gen
cd /opt/websites/patk/public && \
python3 -m http.server -b 0.0.0.0 8080 && \
cd ..
dev: cl
hugo serve
pub: cl gen
rsync -azvP --delete public/ griffin-wsl:/opt/docker/volumes/nginx-blog/config/www