# workbox

Workbox is a collection of JavaScript libraries for Progressive Web Apps. ([Learn more](https://developers.google.com/web/tools/workbox)). This module adds full offline support using workbox.

You can pass options to `pwa.workbox` in `nuxt.config.js` to override the [defaults](https://github.com/nuxt-community/pwa-module/blob/dev/lib/workbox/defaults.js).

```
pwa: {
  workbox: {
    /* workbox options */
  }
}
```

## Options

### `workboxVersion`

(String) Version of workbox. Default value is latest tested version which will be updated by updating this package.

### `workboxURL`

(String) URL for workbox CDN. Default is JSDelivr - See [Workbox CDN](https://github.com/nuxt-community/workbox-cdn). You can also use `config.modulePathPrefix` if you need to rewrite module paths.

### `importScripts`

(Array) Additional scripts to be imported in service worker script. (Relative to `/`. Can be placed in `assets/` directory)

### `autoRegister`

(Boolean) Automatically register `/sw.js` on page load. Enabled by default.

### `dev`

(Boolean) Enable workbox in dev mode of nuxt. (Disabled by default - Not recommended)

**IMPORTANT NOTE:** Remember to clean application data and unregister service workers in your browser or you will experience infinity loop!

It is recommended to test workbox using `nuxt build`/`nuxt start`. You can enable debug mode using `workbox.config.debug`.

### `cacheNames`

(Object) Configure the workbox cache names. See [workbox docs](https://developers.google.com/web/tools/workbox/guides/configure-workbox#configure_cache_names) for more information on this.

### `config`

(Object) Options to be passed to workbox before using it's modules. By default `debug` field will be set to `false` for production builds.

### `clientsClaim`

(Boolean) Start controlling any existing clients as soon as it activates. Enabled by default.

### `skipWaiting`

(Boolean) Skip over the SW waiting lifecycle stage. Enabled by default.

### `offlineAnalytics`

(Boolean) Enable offline Google Analytics tracking [through workbox](https://developers.google.com/web/tools/workbox/guides/enable-offline-analytics) (Disabled by default)

### `workboxExtensions`

(String|String\[]) Loads and inserts the contents of the specified file path into the service worker script before any call to `precacheAndRoute`. You may add as many extra calls as you want to these files.

### `preCaching`

(Array) Cache a set of files when registering service worker. Default is `[]`

Workbox takes a lot of the heavy lifting out of precaching by simplifying the API and ensuring assets are downloaded efficiently.

### `cacheOptions`

(Object) Default:

```javascript
{
  cacheId: '<npm package name> || nuxt',
  directoryIndex: '/',
  revision: undefined
}
```

### `cachingExtensions`

(String|String\[]) Loads and inserts the contents of the specified file path into the service worker script, below autogenerated calls to `workbox.precaching.*`. You may add as many extra calls as you want to these files.

### `cleanupOutdatedCaches`

(Boolean) Find and remove any of the older precaches that might have been used by previous versions of Workbox.

### `offline`

(Boolean) Cache all routes. Enabled by default.

### `offlineStrategy`

(String) Strategy for caching routes. Default is `NetworkFirst`.

### `offlinePage`

(String) Enables routing all offline requests to the specified path. (Example: `/offline.html`)

**Please note** that enabling `offlinePage` will disable `/.*` caching (`offline` option) and will route all offline requests to the specified path.

### `offlineAssets`

(Array) List of assets to precache, in case you need extra files precached other than on the fly caching (`_nuxt/*` etc) or you want to ensure assets used by your `offlinePage`. (Example: `['/offline.png']`)

### `runtimeCaching`

(Array) Custom routes to cache with specific strategy. Useful for caching requests to other origins.

### `cacheAssets`

(Boolean) Cache requests to the `/_nuxt/*` with **cacheFirst** strategy on the fly. Enabled by default.

**NOTE:** This is considered safe because all assets should be correctly hashed there.

**NOTE:** Nuxt smart links trigger chunk downloads for next pages when user sees a link to a non-cached page.

### `routingExtensions`

(String|String\[]) Loads and inserts the contents of the specified file path into the service worker script, below autogenerated calls to `workbox.routing.*`. You may add as many extra calls as you want to these files.

### `assetsURLPattern`

(String/Regex) Pattern to match assets for runtime caching.

Default is auto generated based on `publicPath`. Supports CDN too.

Default: `/_nuxt/`

### `pagesURLPattern`

(String/Regex) Pattern to match pages to be offlined.

Default is auto generated based on `router.base`.

Default: `/`

### `swTemplate`

(String) You can use this to customize generated `sw.js`. Not recommended to be directly used.

### `swURL`

(String) If you need to register another service worker (OneSignal, etc) you can use this option.

### `swDest`

(String) If you want to change the name of service worker, you must use this option with swURL.

### `swScope`

(String) Defaults to `routerBase`.

### `routerBase`

(String) Defaults to router base.

### `publicPath`

(String) Defaults to `/_nuxt`.

## Workbox Window

This module uses [workbox-window](https://developers.google.com/web/tools/workbox/modules/workbox-window) to register and communicate with workbox service worker. See docs for more information about use cases.

As service worker is registered in background, to access instance you have to await on a promise:

```javascript
const workbox = await window.$workbox

if (workbox) {
  // Service worker is available
}
```

## Examples

### Adding custom runtimeCaching items (For CDN)

By default resources in dist (`/_nuxt/`) will be cached with `cacheFirst` and other requests to same domain will be cached with `networkFirst` strategy.

If you have a custom CDN and need to cache requests for it, simply use `runtimeCaching`:

**IMPORTANT:** Please note that workbox will **not** cache opaque responses. So please only use either `networkFirst` or `staleWhileRevalidate` strategies. Please see [Handle Third Party Requests](https://developers.google.com/web/tools/workbox/guides/handle-third-party-requests).

```
workbox: {
      runtimeCaching: [
      {
        // Should be a regex string. Compiles into new RegExp('https://my-cdn.com/.*')
        urlPattern: 'https://my-cdn.com/.*',
        // Defaults to `networkFirst` if omitted
        // handler: 'networkFirst',
        // Defaults to `GET` if omitted
        // method: 'GET'
      }
    ]
}
```

### Adding custom cache

[StrategyOption](https://developers.google.com/web/tools/workbox/modules/workbox-strategies)

```
workbox: {
   runtimeCaching: [
     {
       urlPattern: 'https://my-cdn.com/posts/.*',
       strategyOptions: {
         cacheName: 'our-cache',
         cacheExpiration: {
           maxEntries: 10,
           maxAgeSeconds: 300
         }
       }
     }
   ]
}
```

### Adding custom service worker

Create `static/custom-sw.js` file:

```
console.log('Custom service worker!')
```

Add it with `importScripts` option in `nuxt.config.js`:

```
workbox: {
  importScripts: [
      'custom-sw.js'
  ],
}
```

### Hooking on service worker registration life cycle

Create `plugins/sw.js`:

```
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.getRegistrations().then((registrations) => {
    for (const worker of registrations) {
      console.log('Service worker:', worker)
    }
  });
}
```

Add it to the `plugins` section of `nuxt.config.js`:

```
{
  plugins: [
    {
      src: '~/plugins/sw.js',
      ssr: false
    }
  ]
}
```

### Basic Auth

As a workaround for making basic auth working as described [here](https://thatemil.com/blog/2018/02/21/pwa-basic-auth) you have to enable `manifest.crossorigin` in `nuxt.config.js`:

```
{
  manifest: {
    crossorigin: 'use-credentials'
  }
}
```

Thanks to [@henrixapp](https://github.com/henrixapp) for the tip.

### Enable rangeRequests

Safari requires rangeRequests.

`plugins/workbox-range-request.js`:

```
workbox.routing.registerRoute(
  /\.(mp4|webm)/,
  new workbox.strategies.CacheFirst({
    plugins: [
      new workbox.rangeRequests.Plugin(),
    ],
  }),
  'GET'
);
```

`nuxt.config.js`:

```
{
  workbox: {
    cachingExtensions: '@/plugins/workbox-range-request.js'
  }
}
```

Thanks to [@CarterLi](https://github.com/CarterLi) for the tip.

### Disable Add to Home Screen button (the mini-infobar)

A PWA can be installed by the user if it meets a set of **criteria** and as installable it can trigger an "Add to Home Screen" button (the mini-infobar) as described [here](https://developers.google.com/web/fundamentals/app-install-banners/).

One **criteria** is that `display` must be either `fullscreen`, `standalone`, or `minimal-ui`. If you want to *prevent* the mini-infobar from appearing in your App, you can set the `pwa.manifest.display` to `browser` in `nuxt.config.js`:

```
{
  pwa {
   manifest: {
      display: 'browser'
    }
  }
}
```

### Refresh to Update Notification

In `layouts/default.vue` (or wherever you want, maybe in a plugin):

```
const workbox = await window.$workbox;
if (workbox) {
  workbox.addEventListener('installed', (event) => {
    // If we don't do this we'll be displaying the notification after the initial installation, which isn't perferred.
    if (event.isUpdate) {
      // whatever logic you want to use to notify the user that they need to refresh the page.
    }
  });
}
```
