This plugin is powered by workbox and other good stuff.
👋 Share your awesome PWA project 👉 here
Features
next-i18next exampleblitz.config.js).module.js when next.config.js has experimental.modern set to trueNOTE 1 -
next-pwaversion 2.0.0+ should only work withnext.js9.1+, and static files should only be served throughpublicdirectory. This will make things simpler.NOTE 2 - If you encounter error
TypeError: Cannot read property **'javascript' of undefined**during build, please consider upgrade to webpack5 innext.config.js.
If you are new to
next.jsorreact.jsat all, you may want to first checkout learn next.js or next.js document. Then start from a simple example or progressive-web-app example in next.js repository.
yarn add next-pwa
Update or create next.config.js with
const withPWA = require('next-pwa')({
dest: 'public'
})
module.exports = withPWA({
// next.js config
})
After running next build, this will generate two files in your public: workbox-*.js and sw.js, which will automatically be served statically.
If you are using Next.js version 9 or newer, then skip the options below and move on to Step 2.
If you are using Next.js older than version 9, you'll need to pick an option below before continuing to Step 2.
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.
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 reasons, you must host these files directly from your domain. If the content is delivered using a redirect, the browser will refuse to run the service worker.
When an 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' || /^\/(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-pwaplugin, and you probably have already set them up. If not, go ahead and set them up.
Create a manifest.json file in your public folder:
{
"name": "PWA App",
"short_name": "App",
"icons": [
{
"src": "/icons/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "/icons/android-chrome-384x384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#FFFFFF",
"background_color": "#FFFFFF",
"start_url": "/",
"display": "standalone",
"orientation": "portrait"
}
Add the following into _document.jsx or _app.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="/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="https://github.com/shadowwalker/next-pwa/raw/5.6.1/icons/touch-icon-iphone.png" />
<link rel="apple-touch-icon" sizes="152x152" href="https://github.com/shadowwalker/next-pwa/raw/5.6.1/icons/touch-icon-ipad.png" />
<link rel="apple-touch-icon" sizes="180x180" href="https://github.com/shadowwalker/next-pwa/raw/5.6.1/icons/touch-icon-iphone-retina.png" />
<link rel="apple-touch-icon" sizes="167x167" href="https://github.com/shadowwalker/next-pwa/raw/5.6.1/icons/touch-icon-ipad-retina.png" />
<link rel="icon" type="image/png" sizes="32x32" href="https://github.com/shadowwalker/next-pwa/raw/5.6.1/icons/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="https://github.com/shadowwalker/next-pwa/raw/5.6.1/icons/favicon-16x16.png" />
<link rel="manifest" href="https://github.com/shadowwalker/next-pwa/raw/5.6.1/manifest.json" />
<link rel="mask-icon" href="https://github.com/shadowwalker/next-pwa/raw/5.6.1/icons/safari-pinned-tab.svg" color="#5bbad5" />
<link rel="shortcut icon" href="https://github.com/shadowwalker/next-pwa/raw/5.6.1/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" />
Tip: Put the
viewporthead meta tag into_app.jsrather than in_document.jsif you need it.
<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 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'.
Use this example to see it in action
next-pwa helps you precache those resources on the first load, then inject a fallback handler to handlerDidError plugin to all runtimeCaching configs, so that precached resources are served when fetch failed.
You can also setup precacheFallback.fallbackURL in your runtimeCaching config entry to implement similar functionality. The difference is that above method is based on the resource type, this method is based matched url pattern. If this config is set in the runtimeCaching config entry, resource type based fallback will be disabled automatically for this particular url pattern to avoid conflict.
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:
const withPWA = require('next-pwa')({
dest: 'public'
// disable: process.env.NODE_ENV === 'development',
// register: true,
// scope: '/app',
// sw: 'service-worker.js',
//...
})
module.exports = withPWA({
// next.js config
})
falsedisable: false, so that it will generate service worker in both dev and proddisable: true to completely disable PWAdev, you can set disable: process.env.NODE_ENV === 'development'truefalse 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.basePath in next.config.js or //app so that path under /app will be PWA while others are not/sw.jspublic folder from being precached.['!noprecache/**/*'] - this means that the default behavior will precache all the files inside your public folder but files inside /public/noprecache folder. You can simply put files inside that folder to not precache them without config this.['!img/super-large-image.jpg', '!fonts/not-used-fonts.otf'].next/static (or your custom build) folder[][/chunks\/images\/.*$/] - Don't precache files under .next/static/chunks/images (Highly recommend this to work with next-optimized-images plugin)$ claude mcp add next-pwa \
-- python -m otcore.mcp_server <graph>