Skip to content

Commit

Permalink
BREAKING: Update to next.js recommended plugin signature
Browse files Browse the repository at this point in the history
  • Loading branch information
shadowwalker committed Aug 23, 2022
1 parent 7bcc597 commit 1e6af5f
Show file tree
Hide file tree
Showing 18 changed files with 452 additions and 489 deletions.
152 changes: 76 additions & 76 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ This plugin is powered by [workbox](https://developer.chrome.com/docs/workbox/)
>
> **NOTE 2** - If you encounter error `TypeError: Cannot read property **'javascript' of undefined**` during build, [please consider upgrade to webpack5 in `next.config.js`](https://github.com/shadowwalker/next-pwa/issues/198#issuecomment-817205700).
----
---

[![Open in Gitpod](https://img.shields.io/badge/Open%20In-Gitpod.io-%231966D2?style=for-the-badge&logo=gitpod)](https://gitpod.io/#https://github.com/shadowwalker/next-pwa/)

## Install

> If you are new to `next.js` or `react.js` at all, you may want to first checkout [learn next.js](https://nextjs.org/learn/basics/create-nextjs-app) or [next.js document](https://nextjs.org/docs/getting-started). Then start from [a simple example](https://github.com/shadowwalker/next-pwa/tree/master/examples/next-9) or [progressive-web-app example in next.js repository](https://github.com/vercel/next.js/tree/canary/examples/progressive-web-app).
``` bash
```bash
yarn add next-pwa
```

Expand All @@ -49,13 +49,13 @@ yarn add next-pwa

Update or create `next.config.js` with

``` javascript
const withPWA = require('next-pwa')
```javascript
const withPWA = require('next-pwa')({
dest: 'public'
})

module.exports = withPWA({
pwa: {
dest: 'public'
}
// next.js config
})
```

Expand All @@ -65,7 +65,6 @@ If you are using Next.js version 9 or newer, then skip the options below and mov

If you are using Next.js older than version 9, you'll need to pick an option below before continuing to Step 2.


### Option 1: Host Static Files

Copy files to your static file hosting server, so that they are accessible from the following paths: `https://yourdomain.com/sw.js` and `https://yourdomain.com/workbox-*.js`.
Expand All @@ -89,23 +88,21 @@ const next = require('next')
const app = next({ dev: process.env.NODE_ENV !== 'production' })
const handle = app.getRequestHandler()

app.prepare()
.then(() => {
createServer((req, res) => {
const parsedUrl = parse(req.url, true)
const { pathname } = parsedUrl

if (pathname === '/sw.js' || /^\/(workbox|worker|fallback)-\w+\.js$/.test(pathname)) {
const filePath = join(__dirname, '.next', pathname)
app.serveStatic(req, res, filePath)
} else {
handle(req, res, parsedUrl)
}
})
.listen(3000, () => {
console.log(`> Ready on http://localhost:${3000}`)
})
app.prepare().then(() => {
createServer((req, res) => {
const parsedUrl = parse(req.url, true)
const { pathname } = parsedUrl

if (pathname === '/sw.js' || /^\/(workbox|worker|fallback)-\w+\.js$/.test(pathname)) {
const filePath = join(__dirname, '.next', pathname)
app.serveStatic(req, res, filePath)
} else {
handle(req, res, parsedUrl)
}
}).listen(3000, () => {
console.log(`> Ready on http://localhost:${3000}`)
})
})
```

> The following setup has nothing to do with `next-pwa` plugin, and you probably have already set them up. If not, go ahead and set them up.
Expand Down Expand Up @@ -148,43 +145,43 @@ Create a `manifest.json` file in your `public` folder:

Add the following into `_document.jsx` or `_app.tsx`, in `<Head>`:

``` html
<meta name='application-name' content='PWA App' />
<meta name='apple-mobile-web-app-capable' content='yes' />
<meta name='apple-mobile-web-app-status-bar-style' content='default' />
<meta name='apple-mobile-web-app-title' content='PWA App' />
<meta name='description' content='Best PWA App in the world' />
<meta name='format-detection' content='telephone=no' />
<meta name='mobile-web-app-capable' content='yes' />
<meta name='msapplication-config' content='/icons/browserconfig.xml' />
<meta name='msapplication-TileColor' content='#2B5797' />
<meta name='msapplication-tap-highlight' content='no' />
<meta name='theme-color' content='#000000' />

<link rel='apple-touch-icon' href='/icons/touch-icon-iphone.png' />
<link rel='apple-touch-icon' sizes='152x152' href='/icons/touch-icon-ipad.png' />
<link rel='apple-touch-icon' sizes='180x180' href='/icons/touch-icon-iphone-retina.png' />
<link rel='apple-touch-icon' sizes='167x167' href='/icons/touch-icon-ipad-retina.png' />

<link rel='icon' type='image/png' sizes='32x32' href='/icons/favicon-32x32.png' />
<link rel='icon' type='image/png' sizes='16x16' href='/icons/favicon-16x16.png' />
<link rel='manifest' href='/manifest.json' />
<link rel='mask-icon' href='/icons/safari-pinned-tab.svg' color='#5bbad5' />
<link rel='shortcut icon' href='/favicon.ico' />
<link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Roboto:300,400,500' />
<meta name='twitter:card' content='summary' />
<meta name='twitter:url' content='https://yourdomain.com' />
<meta name='twitter:title' content='PWA App' />
<meta name='twitter:description' content='Best PWA App in the world' />
<meta name='twitter:image' content='https://yourdomain.com/icons/android-chrome-192x192.png' />
<meta name='twitter:creator' content='@DavidWShadow' />
<meta property='og:type' content='website' />
<meta property='og:title' content='PWA App' />
<meta property='og:description' content='Best PWA App in the world' />
<meta property='og:site_name' content='PWA App' />
<meta property='og:url' content='https://yourdomain.com' />
<meta property='og:image' content='https://yourdomain.com/icons/apple-touch-icon.png' />
```html
<meta name="application-name" content="PWA App" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="apple-mobile-web-app-title" content="PWA App" />
<meta name="description" content="Best PWA App in the world" />
<meta name="format-detection" content="telephone=no" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="msapplication-config" content="/icons/browserconfig.xml" />
<meta name="msapplication-TileColor" content="#2B5797" />
<meta name="msapplication-tap-highlight" content="no" />
<meta name="theme-color" content="#000000" />

<link rel="apple-touch-icon" href="/icons/touch-icon-iphone.png" />
<link rel="apple-touch-icon" sizes="152x152" href="/icons/touch-icon-ipad.png" />
<link rel="apple-touch-icon" sizes="180x180" href="/icons/touch-icon-iphone-retina.png" />
<link rel="apple-touch-icon" sizes="167x167" href="/icons/touch-icon-ipad-retina.png" />

<link rel="icon" type="image/png" sizes="32x32" href="/icons/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/icons/favicon-16x16.png" />
<link rel="manifest" href="/manifest.json" />
<link rel="mask-icon" href="/icons/safari-pinned-tab.svg" color="#5bbad5" />
<link rel="shortcut icon" href="/favicon.ico" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" />

<meta name="twitter:card" content="summary" />
<meta name="twitter:url" content="https://yourdomain.com" />
<meta name="twitter:title" content="PWA App" />
<meta name="twitter:description" content="Best PWA App in the world" />
<meta name="twitter:image" content="https://yourdomain.com/icons/android-chrome-192x192.png" />
<meta name="twitter:creator" content="@DavidWShadow" />
<meta property="og:type" content="website" />
<meta property="og:title" content="PWA App" />
<meta property="og:description" content="Best PWA App in the world" />
<meta property="og:site_name" content="PWA App" />
<meta property="og:url" content="https://yourdomain.com" />
<meta property="og:image" content="https://yourdomain.com/icons/apple-touch-icon.png" />

<!-- apple splash screen images -->
<!--
Expand All @@ -198,17 +195,20 @@ Add the following into `_document.jsx` or `_app.tsx`, in `<Head>`:
-->
```

> Tip: Put the `viewport` head meta tag into `_app.js` rather than in `_document.js` if you need it.
> Tip: Put the `viewport` head meta tag into `_app.js` rather than in `_document.js` if you need it.
``` typescript
<meta name='viewport' content='minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no, user-scalable=no, viewport-fit=cover' />
```typescript
<meta
name='viewport'
content='minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no, user-scalable=no, viewport-fit=cover'
/>
```

## Offline Fallbacks

Offline fallbacks are useful when the fetch failed from both cache and network, a precached resource is served instead of present an error from browser.

To get started simply add a `/_offline` page such as `pages/_offline.js` or `pages/_offline.jsx` or `pages/_offline.ts` or `pages/_offline.tsx`. Then you are all set! When the user is offline, all pages which are not cached will fallback to '/_offline'.
To get started simply add a `/_offline` page such as `pages/_offline.js` or `pages/_offline.jsx` or `pages/_offline.ts` or `pages/_offline.tsx`. Then you are all set! When the user is offline, all pages which are not cached will fallback to '/\_offline'.

**[Use this example to see it in action](https://github.com/shadowwalker/next-pwa/tree/master/examples/offline-fallback-v2)**

Expand All @@ -221,17 +221,17 @@ You can also setup `precacheFallback.fallbackURL` in your [runtimeCaching config
There are options you can use to customize the behavior of this plugin by adding `pwa` object in the next config in `next.config.js`:

```javascript
const withPWA = require('next-pwa')
const withPWA = require('next-pwa')({
dest: 'public'
// disable: process.env.NODE_ENV === 'development',
// register: true,
// scope: '/app',
// sw: 'service-worker.js',
//...
})

module.exports = withPWA({
pwa: {
dest: 'public',
// disable: process.env.NODE_ENV === 'development',
// register: true,
// scope: '/app',
// sw: 'service-worker.js',
//...
}
// next.js config
})
```

Expand Down Expand Up @@ -260,7 +260,7 @@ module.exports = withPWA({
- example: `['!img/super-large-image.jpg', '!fonts/not-used-fonts.otf']`
- buildExcludes - an array of extra pattern or function to exclude files from being precached in `.next/static` (or your custom build) folder
- default: `[]`
- example: `[/chunks\/images\/.*$/]` - Don't precache files under `.next/static/chunks/images` (Highly recommend this to work with `next-optimized-images` plugin)
- example: `[/chunks\/images\/.*$/]` - Don't precache files under `.next/static/chunks/images` (Highly recommend this to work with `next-optimized-images` plugin)
- doc: Array of (string, RegExp, or function()). One or more specifiers used to exclude assets from the precache manifest. This is interpreted following the same rules as Webpack's standard exclude option.
- cacheStartUrl - whether to cache start url
- default: `true`
Expand Down Expand Up @@ -311,7 +311,7 @@ Here is the [document on how to write runtime caching configurations](https://de
3. When you are debugging service worker, constantly `clean application cache` to reduce some flaky errors.
4. If you are redirecting the user to another route, please note [workbox by default only cache response with 200 HTTP status](https://developer.chrome.com/docs/workbox/modules/workbox-cacheable-response#what_are_the_defaults), if you really want to cache redirected page for the route, you can specify it in `runtimeCaching` such as `options.cacheableResponse.statuses=[200,302]`.
5. When debugging issues, you may want to format your generated `sw.js` file to figure out what's really going on.
6. Force `next-pwa` to generate worker box production build by specify the option `mode: 'production'` in your `pwa` section of `next.config.js`. Though `next-pwa` automatically generate the worker box development build during development (by running `next`) and worker box production build during production (by running `next build` and `next start`). You may still want to force it to production build even during development of your web app for following reason:
6. Force `next-pwa` to generate worker box production build by specify the option `mode: 'production'` in your `pwa` section of `next.config.js`. Though `next-pwa` automatically generate the worker box development build during development (by running `next`) and worker box production build during production (by running `next build` and `next start`). You may still want to force it to production build even during development of your web app for following reason:
1. Reduce logging noise due to production build doesn't include logging.
2. Improve performance a bit due to production build is optimized and minified.
7. If you just want to disable worker box logging while keeping development build during development, [simply put `self.__WB_DISABLE_DEV_LOGS = true` in your `worker/index.js` (create one if you don't have one)](https://github.com/shadowwalker/next-pwa/blob/c48ef110360d0138ad2dacd82ab96964e3da2daf/examples/custom-worker/worker/index.js#L6).
Expand Down
10 changes: 4 additions & 6 deletions examples/cache-on-front-end-nav/next.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
const withPWA = require('next-pwa')

module.exports = withPWA({
pwa: {
dest: 'public'
}
const withPWA = require('next-pwa')({
dest: 'public'
})

module.exports = withPWA()
14 changes: 6 additions & 8 deletions examples/cookie/next.config.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
const withPWA = require('next-pwa')

module.exports = withPWA({
pwa: {
dest: 'public',
dynamicStartUrl: true, // this is same as default value
dynamicStartUrlRedirect: '/login' // recommend to config this for best user experience if your start-url redirects on first load
}
const withPWA = require('next-pwa')({
dest: 'public',
dynamicStartUrl: true, // this is same as default value
dynamicStartUrlRedirect: '/login' // recommend to config this for best user experience if your start-url redirects on first load
})

module.exports = withPWA()
33 changes: 14 additions & 19 deletions examples/custom-ts-worker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,37 @@ Simply create a `worker/index.ts` and start implementing your service worker. `n

In this way, you get benefit of code splitting and size minimization automatically. Yes! `require` modules works! Yes! you can share codes between web app and the service worker!

> - In dev mode, `worker/index.ts` is not watch, so it will not hot reload.
> - In dev mode, `worker/index.ts` is not watched, so it will not hot reload.
### Custom Worker Directory

You can customize the directory of your custom worker file by setting the `customWorkerDir` relative to the `basedir` in the `pwa` section of your `next.config.js`:


``` javascript
const withPWA = require('next-pwa')
```javascript
const withPWA = require('next-pwa')({
customWorkerDir: 'serviceworker'
// ...
})

module.exports = withPWA({
pwa: {
customWorkerDir: 'serviceworker'
...
}
// next.js config
})
```

In this example, `next-pwa` would look for `serviceworker/index.ts`.


## Old Method (Still Works)

Basically you need to create a file such as `worker.js` in `public` folder, then add an option `importScripts` to `pwa` object in `next.config.js`:

``` javascript
const withPWA = require('next-pwa')
```javascript
const withPWA = require('next-pwa')({
dest: 'public',
importScripts: ['/worker.js']
})

module.exports = withPWA({
pwa: {
dest: 'public',
importScripts: ['/worker.js']
}
// next.js config
})
```

Expand All @@ -52,7 +50,7 @@ Then service worker generated will automatically import your code and run it bef

[![Open in Gitpod](https://img.shields.io/badge/Open%20In-Gitpod.io-%231966D2?style=for-the-badge&logo=gitpod)](https://gitpod.io/#https://github.com/shadowwalker/next-pwa/)

``` bash
```bash
cd examples/custom-ts-server
yarn install
yarn build
Expand All @@ -66,6 +64,3 @@ yarn start
**/public/sw.js
**/public/worker-*.js
```



10 changes: 4 additions & 6 deletions examples/custom-ts-worker/next.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
const withPWA = require('next-pwa')

module.exports = withPWA({
pwa: {
dest: 'public'
}
const withPWA = require('next-pwa')({
dest: 'public'
})

module.exports = withPWA()
Loading

0 comments on commit 1e6af5f

Please sign in to comment.