PWAs (Progressive web apps) are web apps developed using a number of specific technologies and standard patterns to allow them to take advantage of both web and native app features. The PWA module includes preliminary support for Hugo sites, see thefeatures below.
Module | github.com/hugomods/pwa |
---|---|
Stats |
You may still be a bit confused about the features, the following video will show what the module can bring to your sites. You can also give it a shot on ourwebsite or thedemo site.
This section is for theme developers to integrate this module with their themes.
There is ademo site and it’ssource code to help you get started.
hugo.yaml
1module:2imports:3-path:github.com/hugomods/pwa
hugo.toml
1[module]2[[module.imports]]3path='github.com/hugomods/pwa'
hugo.json
1{2"module":{3"imports":[4{5"path":"github.com/hugomods/pwa"6}7]8}9}
The meta partial generate the manifest meta tag to tell browser the location ofweb app manifest.
1<head>2{{partialCached"pwa/assets/meta".}}3</head>
1{{$css:=resources.Get"main.css"}}2<linkhref="{{$css.RelPermalink}}"rel="stylesheet"/>3{{/* THIS OPERATION CANNOT BE BE CACHED BY partialCached. */}}4{{partial"pwa/functions/precache"(dict"URL"$css.RelPermalink"Page".)}}
1{{$js:=resources.Get"main.js"}}2<scriptsrc="{{$js.RelPermalink}}"></script>3{{/* THIS OPERATION CANNOT BE BE CACHED BY partialCached. */}}4{{partial"pwa/functions/precache"(dict"URL"$js.RelPermalink"Page".)}}
As the comments said,pwa/functions/precache
cannot be cached, since Hugo renders pages concurrently.
sequenceDiagram participant P1 as Page1 participant H as Hugo participant P2 as Page2 P1->>H: Precache CSS. H-->>P1: Done! P2->>H: Precache CSS. H-->>P2: Cache found, ignored! P2->>H: Precache JS. H-->>P2: Done! P1->>H: Precache JS. H-)P1: Cache found, ignored!
The example above shows the case of caching thepwa/functions/precache
operations.So far, thePage1
precaches the CSS, while thePage2
precaches the JS, in either case, the service worker not aware of all the resources that need to be precached.
Finally, import thepwa/assets/sw
partial to generate service worker script.
<body>
.1<body>2...3{{partialCached"pwa/assets/sw".}}4</body>
It’s recommended to usepartialCached
to cache the partial for getting better build performance.
This module provides a built-in offline page with inline style, you can change it by creating thelayouts/_default/index.offline.html
file.
This section is for theme users to set up the PWA.
Append theOffline
andWebAppManifest
format into theoutputs.home
, to generate the offline page andweb app manifest.
hugo.yaml
1outputs:2home:3-HTML4-RSS5-Offline6-WebAppManifest
hugo.toml
1[outputs]2home=['HTML','RSS','Offline','WebAppManifest']
hugo.json
1{ 2"outputs":{ 3"home":[ 4"HTML", 5"RSS", 6"Offline", 7"WebAppManifest" 8] 9}10}
Parameter | Type | Default | Required | Description |
---|---|---|---|---|
debug | boolean | false | - | Whether to enable the debug mode. |
icon_path | string | images/pwa/icon.png | - | The icon image relative to theassets folder, which used to generate icons in multiple sizes. |
icon_sizes | array | [48, 64, 128, 144, 256, 512] | - | The target sizes of icons. |
offline_image | string | images/pwa/offline.png | - | The offline image relative to theassets folder, which will be shown when request an image offline. |
precaches | array | [] | - | Custom precache files. |
precaches.url | string | - | - | The URL of precache file. |
caches | object | - | - | Cache settings. |
caches.font | object | - | - | Font cache settings. |
caches.font.origins | array | [] | - | Trusted origins2. |
caches.font.strategy | string | cache-first | - | Font cache strategy1. |
caches.font.max_age | string | 2592000 | - | Font cache max age in second. |
caches.image | object | - | - | Image cache settings. |
caches.image.origins | array | [] | - | Trusted origins2. |
caches.image.strategy | string | cache-first | - | Image cache strategy1. |
caches.image.max_age | string | 2592000 | - | Image cache max age in second. |
caches.script | object | - | - | Script cache settings. |
caches.script.origins | array | [] | - | Trusted origins2. |
caches.script.strategy | string | cache-first | - | Script cache strategy1. |
caches.script.max_age | string | 2592000 | - | Script cache max age in second. |
caches.style | object | - | - | Style cache settings. |
caches.style.origins | array | [] | - | Trusted origins2. |
caches.style.strategy | string | cache-first | - | Style cache strategy1. |
caches.style.max_age | string | 2592000 | - | Style cache max age in second. |
manifest | object | - | - | Manifest settings, such astheme_color ,background_color . |
This module doesn’t provide the built-in icon and offline images, you’ll need to save your icon and offline images to corresponding path.
hugo.yaml
1params: 2pwa: 3caches: 4font: 5max_age:2592000 6origins:[] 7strategy:cache-first 8image: 9max_age:259200010origins:[]11strategy:cache-first12script:13max_age:259200014origins:[]15strategy:cache-first16style:17max_age:259200018origins:[]19strategy:cache-first20debug:false21icon_path:images/pwa/icon.png22icon_sizes:23-4824-6425-12826-14427-25628-51229manifest:30background_color:'#ff4088'31theme_color:'#ff4088'32offline_image:images/pwa/offline.png33precaches:34-url:/35-url:foo.png
hugo.toml
1[params] 2[params.pwa] 3debug=false 4icon_path='images/pwa/icon.png' 5icon_sizes=[48,64,128,144,256,512] 6offline_image='images/pwa/offline.png' 7[params.pwa.caches] 8[params.pwa.caches.font] 9max_age=259200010origins=[]11strategy='cache-first'12[params.pwa.caches.image]13max_age=259200014origins=[]15strategy='cache-first'16[params.pwa.caches.script]17max_age=259200018origins=[]19strategy='cache-first'20[params.pwa.caches.style]21max_age=259200022origins=[]23strategy='cache-first'24[params.pwa.manifest]25background_color='#ff4088'26theme_color='#ff4088'27[[params.pwa.precaches]]28url='/'29[[params.pwa.precaches]]30url='foo.png'
hugo.json
1{ 2"params":{ 3"pwa":{ 4"caches":{ 5"font":{ 6"max_age":2592000, 7"origins":[], 8"strategy":"cache-first" 9},10"image":{11"max_age":2592000,12"origins":[],13"strategy":"cache-first"14},15"script":{16"max_age":2592000,17"origins":[],18"strategy":"cache-first"19},20"style":{21"max_age":2592000,22"origins":[],23"strategy":"cache-first"24}25},26"debug":false,27"icon_path":"images/pwa/icon.png",28"icon_sizes":[2948,3064,31128,32144,33256,3451235],36"manifest":{37"background_color":"#ff4088",38"theme_color":"#ff4088"39},40"offline_image":"images/pwa/offline.png",41"precaches":[42{43"url":"/"44},45{46"url":"foo.png"47}48]49}50}51}
The default parameters is best for production, but will be bad for development, because you may see a cached, out-of-date page and have to clear the cache or do a force refresh.
But don’t worry, we can fix it by changing the default cache strategies1 for development environment.
config/development/hugo.yaml
1params: 2pwa: 3caches: 4font: 5strategy:network-first 6image: 7strategy:network-first 8script: 9strategy:network-first10style:11strategy:network-first
config/development/hugo.toml
1[params] 2[params.pwa] 3[params.pwa.caches] 4[params.pwa.caches.font] 5strategy='network-first' 6[params.pwa.caches.image] 7strategy='network-first' 8[params.pwa.caches.script] 9strategy='network-first'10[params.pwa.caches.style]11strategy='network-first'
config/development/hugo.json
1{ 2"params":{ 3"pwa":{ 4"caches":{ 5"font":{ 6"strategy":"network-first" 7}, 8"image":{ 9"strategy":"network-first"10},11"script":{12"strategy":"network-first"13},14"style":{15"strategy":"network-first"16}17}18}19}20}
Available strategies:cache-first,network-first andstale-while-revalidate. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎
Only trusted third-party origin resources will be cached, such ashttps://example.com
,https://example.org/
. ↩︎ ↩︎ ↩︎ ↩︎