npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@byhuz/next-pwa

v2.4.3

Published

Next.js with PWA, powered by workbox.

Downloads

6

Readme

Zero Config PWA Plugin for Next.js

This plugin is powered by workbox and other good stuff.

size dependencies downloads license

Features

  • 0️⃣ Zero config for registering and generating service worker
  • 📴 Completely offline support
  • 💯 Maximize lighthouse score
  • 📦 Use workbox and workbox-window v5
  • 🎈 Easy to understand examples
  • ☕ No custom server needed for Next.js 9+ example
  • 🔧 Handle PWA lifecycle events opt-in example
  • 📐 Custom worker to run extra code in service worker with code splitting example 🆕
  • 🌏 Internationalization (a.k.a I18N) with next-i18next example
  • ✨ Optimized precache and runtime cache
  • 🛠 Configurable by the same workbox configuration options for GenerateSW and InjectManifest
  • 🚀 Spin up a GitPod and try out examples in rocket speed

NOTE - next-pwa version 2.0.0+ should only work with next.js 9.1+, and static files should only be served through public directory. This will make things simpler.

VERSION 2.3.0

  • service worker runs in dev mode as well, good for debugging functionality with service worker during development
  • custom worker with code splitting, simply write your service worker in worker/index.js
  • new option to exclude files in public folder from being precached

Open in Gitpod

Install

yarn add next-pwa

Basic Usage

Step 1: withPWA

Update or create next.config.js with

const withPWA = require('next-pwa')

module.exports = withPWA({
  // other next config
})

After running next build, this will generate two files in your distDir (default is .next folder): workbox-*.js and sw.js, which you need to serve statically, either through static file hosting service or using custom server.js.

If you are using Next.js 9+, you may not need a custom server to host your service worker files. Skip to next section to see the details.

Option 1: Host Static Files

Copy files to your static file hosting server, so that they could be access using URL: https://yourdomain.com/sw.js and https://yourdomain.com/workbox-*.js.

One example is using firebase hosting service to host those files statically. You can automate the copy step using scripts in your deployment workflow.

For security reason, these files must be hosted directly from your domain. If the content is delivered using a redirect, the browser will refuse to run the service worker.

Option 2: Use Custom Server

When a http request is received, test if those files are requested, then return those static files.

Example server.js

const { createServer } = require('http')
const { join } = require('path')
const { parse } = require('url')
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' || pathname.startsWith('/workbox-')) {
        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.

Step 2: Add Manifest File (Example)

Create a manifest.json file in your static folder:

{
  "name": "PWA App",
  "short_name": "App",
  "icons": [
    {
      "src": "/static/icons/android-chrome-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "/static/icons/android-chrome-384x384.png",
      "sizes": "384x384",
      "type": "image/png"
    },
    {
      "src": "/static/icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "theme_color": "#FFFFFF",
  "background_color": "#FFFFFF",
  "start_url": "/",
  "display": "standalone",
  "orientation": "portrait"
}

Step 3: Add Head Meta (Example)

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

<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='/static/icons/browserconfig.xml' />
<meta name='msapplication-TileColor' content='#2B5797' />
<meta name='msapplication-tap-highlight' content='no' />
<meta name='theme-color' content='#000000' />
<meta name='viewport' content='minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no, user-scalable=no, viewport-fit=cover' />
          
<link rel='apple-touch-icon' sizes='180x180' href='/static/icons/apple-touch-icon.png' />
<link rel='icon' type='image/png' sizes='32x32' href='/static/icons/favicon-32x32.png' />
<link rel='icon' type='image/png' sizes='16x16' href='/static/icons/favicon-16x16.png' />
<link rel='manifest' href='/static/manifest.json' />
<link rel='mask-icon' href='/static/icons/safari-pinned-tab.svg' color='#5bbad5' />
<link rel='shortcut icon' href='/static/icons/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/static/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/static/icons/apple-touch-icon.png' />

Usage Without Custom Server (next.js 9+)

Thanks to Next.js 9+, we can use public folder to serve static files from root / url path. It cuts the need to write custom server only to serve those files. Therefore the setup is more easy and concise. We can use next.config.js to config next-pwa to generates service worker and workbox files into publicfolder.

withPWA

const withPWA = require('next-pwa')

module.exports = withPWA({
  pwa: {
    dest: 'public'
  }
})

Use this example to see it in action

Configuration

There are options you can use to customize behavior of this plugin by adding pwa object in the next config in next.config.js:

const withPWA = require('next-pwa')

module.exports = withPWA({
  pwa: {
    disable: false,
    register: true,
    scope: '/app',
    sw: 'service-worker.js',
    //...
  }
})

Available Options

  • disable: boolean - whether to disable pwa feature as a whole
    • default to false
    • set disable: false, so that it will generate service worker in both dev and prod
    • set disable: true to completely disable PWA
    • if you don't need debug service worker in dev, you can set disable: process.env.NODE_ENV === "development"
  • register: boolean - whether to let this plugin register service worker for you
    • default to true
    • set to false when you want to handle register service worker yourself, this could be done in componentDidMount of your root app. you can consider the register.js as an example.
  • scope: string - url scope for pwa
    • default to /
    • set to /app, so that all sub url under /app will be PWA, other url paths are still normal web app with no PWA support.
  • sw: string - service worker script file name
    • default to /sw.js
    • set to other file name if you want to customize the output service worker file name
  • runtimeCaching - caching strategies (array or callback function)
    • default: see the Default Runtime Caching section for the default configuration
    • accept an array of cache configurations
  • publicExcludes - array of glob pattern strings to excludes files in public folder being precached.
    • default: [] - i.e. default behavior will precache all the files inside your public folder
    • example: ['!img/super-large-image.jpg', '!fonts/not-used-fonts.otf']
  • subdomainPrefix: string - url prefix to allow hosting static files on a subdomain
    • default: "" - i.e. default with no prefix
    • example: /subdomain if the app is hosted on example.com/subdomain

Other Options

next-pwa uses workbox-webpack-plugin, other options which could also be put in pwa object can be find ON THE DOCUMENTATION for GenerateSW and InjectManifest. If you specify swSrc, InjectManifest plugin will be used, otherwise GenerateSW will be used to generate service worker.

Default Runtime Caching

next-pwa use a default runtime cache.js

Tips

  1. Common UX pattern to ask user to reload when new service worker is installed
  2. Use a convention like {command: 'doSomething', message: ''} object when postMessage to service worker. So that on the listener, it could do multiple different tasks using if...else....
  3. When you debugging service worker, constantly clean application cache to reduce some flaky errors.

Reference

  1. Google Workbox
  2. ServiceWorker, MessageChannel, & postMessage by Nicolás Bevacqua

License

MIT