Home

Awesome

Gem Version MIT license

Jekyll PWA Workbox Plugin

note on future releases; we will be using the same version number as Workbox from here on.

A Jekyll plugin that makes your PWA / Website available offline and lets you install on desktop and mobile*.
It generates and injects a precache list into a Workbox service worker and handles the registration process in a secure way.
* does not fully work with iOS/Safari to date

The plugin was originally developed by Lavas Project. It is pretty much the same, except for:


This plugin supports Workbox version 5.1.4 *.

* in case you have been using a previous Workbox version (i.e. 3 or older), please see migration instructions here.

There are various tools available on the Workbox tools page, that let you easily generate a service worker with Webpack or Gulp as your build tool.

We do not use npm and therefore integrate this function in the Jekyll build process to precache and make posts/pages available offline, even if they have never been visited before.


Prerequisites

Web App Manifest

A manifest.json is required to experience the full features of your PWA.

In case you do not have one already, please read the following about creating and adding a manifest.json. Add it to the root directory of your project and Jekyll will deploy it to _site when your PWA / Website builds.

Use Chrome DevTools > Application for debugging/testing.

Installation

This plugin is available as a RubyGem.

Option #1

Add gem 'jekyll-pwa-workbox' to the jekyll_plugin group in your Gemfile:

source 'https://rubygems.org'

gem 'jekyll'

group :jekyll_plugins do
  gem "jekyll-pwa-workbox"
end

Then run bundle to install the gem.

Option #2

Alternatively, you can also install the gem manually, using the following command:

$ gem install jekyll-pwa-workbox

Once the gem has been installed successfully, add the following to your _config.yml in order to tell Jekyll to use the plugin:

plugins:
- jekyll-pwa-workbox

Getting Started

Configuration

Add the following configuration block to Jekyll's _config.yml:

pwa:
  sw_src_filepath: service-worker.js # Optional
  sw_dest_filename: service-worker.js # Optional
  dest_js_directory: assets/js # Required
  precache_recent_posts_num: 5 # Optional
  precache_glob_directory: / # Optional
  precache_glob_patterns: # Optional
    - "/**/*.{js,json,css}"
    - "/**/*.{ico,jpg,jpeg,png,svg}"
    - "/**/*.html"
  precache_glob_ignores: # Optional
    - "sw-register.js"
    - "fonts/**/*"
ParameterDescription
sw_src_filepathFilepath of the source service worker. Defaults to service-worker.js
sw_dest_filenameFilename of the destination service worker. Defaults to service-worker.js
dest_js_directoryDirectory of JS in _site. During the build process, some JS like workbox.js will be copied to this directory so that service worker can import them in runtime.
precache_glob_directoryDirectory of precache. Workbox Config
precache_glob_patternsPatterns of precache. Workbox Config
precache_glob_ignoresIgnores of precache. Workbox Config
precache_recent_posts_numNumber of recent posts to precache.

We handle precache and runtime cache with the help of Workbox in service worker.

Service Worker

Write your own

Create a service-worker.js in the root path of your Jekyll project. The source file's path can be adjusted with the sw_src_filepath option.

You can write your own service worker with Workbox APIs.

Basic example

Here is a basic example of service-worker.js:

// service-worker.js

// set names for both precache & runtime cache
workbox.core.setCacheNameDetails({
    prefix: 'my-blog',
    suffix: 'v1.0',
    precache: 'precache',
    runtime: 'runtime-cache'
});

// let Service Worker take control of pages ASAP
workbox.core.skipWaiting();
workbox.core.clientsClaim();

// let Workbox handle our precache list
workbox.precaching.precacheAndRoute(self.__precacheManifest);

// use `NetworkFirst` strategy for html
workbox.routing.registerRoute(
    /\.html$/,
    new workbox.strategies.NetworkFirst()
);

// use `NetworkFirst` strategy for css and js
workbox.routing.registerRoute(
    /\.(?:js|css)$/,
    new workbox.strategies.NetworkFirst()
);

// use `CacheFirst` strategy for images
workbox.routing.registerRoute(
    /assets\/(img|icons)/,
    new workbox.strategies.CacheFirst()
);

// use `StaleWhileRevalidate` third party files
workbox.routing.registerRoute(
    /^https?:\/\/cdn.staticfile.org/,
    new workbox.strategies.StaleWhileRevalidate()
);

Register the Service Worker

Add the following two blocks to an existing JS file (i.e. app.js):

this must be at the start of your JS file, before any other code, so that the script-src can be generated

---
layout: null
---

this snippet can live anywhere in your JS file (i.e. app.js)

window.onload = function () {
    var script = document.createElement('script');
    var firstScript = document.getElementsByTagName('script')[0];
    script.async = true;
    script.src = '{{'sw-register.js'|relative_url}}?v=' + Date.now();
    firstScript.parentNode.insertBefore(script, firstScript);
};

OR use any of these files to start the service worker registration:

DONE - use Chrome DevToolsfor debugging/testing.


Notes

Updates / Manual Refresh

When the PWA / Website updates, the service worker will go into the install stage and request the newest resources, but the user must refresh current page manually so that these updates can be applied. This can be done by notifying the user with a toast such as website updated - please refresh the page manually or whatever else fits your needs.

Workbox Plugins

Workbox also comes with a set of plugins, details of how to use these can be found in the Workbox Guide - Using Plugins

Contribute

Fork this repository, make your changes and then issue a pull request. If you find a bug or if you have new ideas, please file an issue in our bug tracker.

Copyright

Copyright © 2019 souldanger

Copyright © 2017 Pan Yuqi, Xing Peng

License: MIT