Why is my Workbox GenerateSW showing my offline page while connected?

1.3k Views Asked by At

I'm trying to setup my offline page using Workbox GenerateSW() and running into an issue where on the first load after I clear site data and hard refresh displays my homepage, but on subsequent loads I am getting the offline page I set up even though I'm online. I have a multi page PHP app that has the assets served up by a CDN. I run the GenerateSW() task in a JS file called by an npm node script.

Here is my GenerateSW() code...

// Pull in .env file values...
const dotEnv = require('dotenv').config({ path: '/var/www/my-project/sites/www/.env' });
if (dotEnv.error) {
  throw dotEnv.error
}

const {generateSW} = require('workbox-build');

// Used to break cache on generate of new SW where file is composed of multiple pieces that can't be watched.
const genRanHex = (size = 24) => [...Array(size)].map(() => Math.floor(Math.random() * 16).toString(16)).join('');

const mode = 'development';

generateSW({
    swDest: './sites/www/public/service-worker.js',
    skipWaiting: true,
    clientsClaim: true,
    cleanupOutdatedCaches: true,
    cacheId: genRanHex(),
    mode: mode,
    navigateFallback: '/offline',
    offlineGoogleAnalytics: mode === 'production',
    globDirectory: './sites/assets/public',
    globPatterns: [
        'img/shell/**/*.{svg,png}',
        'dist/**/*.{js,css}',
        'manifest.json'
    ],
    modifyURLPrefix: {
        'dist/': `${dotEnv.parsed.APPLICATION_ASSETS_CDN}/dist/`,
        'img/shell/': `${dotEnv.parsed.APPLICATION_ASSETS_CDN}/img/shell/`,
    },
    ignoreURLParametersMatching: [/v/],
    additionalManifestEntries: [
        {
            "url": "/offline",
            "revision": genRanHex()
        }
    ],
    runtimeCaching: []
}).then(({count, size}) => {
    console.log(`Generated service worker, which will precache ${count} files, totaling ${size} bytes.`);
}).catch(console.error);
2

There are 2 best solutions below

1
On BEST ANSWER

navigateFallback is not actually offline page. From workbox docs:

If specified, all navigation requests for URLs that aren't precached will be fulfilled with the HTML at the URL provided. You must pass in the URL of an HTML document that is listed in your precache manifest. This is meant to be used in a Single Page App scenario, in which you want all navigations to use common App Shell HTML.

For offline page, this question might help.

0
On

So the accepted answer was correct in my misuse of navigateFallback which I was trying to use as an offline fallback for non cached routes. After some digging and tinkering, I found the correct way to go about it. The important part that I missed or was not documented well enough on Workbox is that the offline fallback happens at the runtimeCache level...

// Pull in .env file values...
const dotEnv = require('dotenv').config({ path: '/var/www/my-project/sites/www/.env' });
if (dotEnv.error) {
  throw dotEnv.error
}

const {generateSW} = require('workbox-build');

// Used to break cache on generate of new SW where file is composed of multiple pieces that can't be watched.
const genRanHex = (size = 24) => [...Array(size)].map(() => Math.floor(Math.random() * 16).toString(16)).join('');

const mode = 'development';

generateSW({
    swDest: './sites/www/public/service-worker.js',
    skipWaiting: true,
    clientsClaim: true,
    cleanupOutdatedCaches: true,
    cacheId: genRanHex(),
    mode: mode,
    offlineGoogleAnalytics: mode === 'production',
    globDirectory: './sites/assets/public',
    globPatterns: [
        'img/shell/**/*.{svg,png}',
        'dist/**/*.{js,css}',
        'manifest.json'
    ],
    modifyURLPrefix: {
        'dist/': `${dotEnv.parsed.APPLICATION_ASSETS_CDN}/dist/`,
        'img/shell/': `${dotEnv.parsed.APPLICATION_ASSETS_CDN}/img/shell/`,
    },
    ignoreURLParametersMatching: [/v/],
    additionalManifestEntries: [
        {
            "url": "/offline",
            "revision": genRanHex()
        }
    ],
    runtimeCaching: [
        {
        urlPattern: /^https:\/\/([\w+\.\-]+www\.mysite\.tv)(|\/.*)$/,
        handler: 'StaleWhileRevalidate',
        options: {
            cacheName: 'core',
            precacheFallback: {
                fallbackURL: '/offline' // THIS IS THE KEY
            }
        }
    }
]
}).then(({count, size}) => {
    console.log(`Generated service worker, which will precache ${count} files, totaling ${size} bytes.`);
}).catch(console.error);