Getting started
Install
If you are new to React or Next.js, you may want to checkout learn React, learn Next.js and Next.js documentation first, and then start from a simple example.
npm i @ducanh2912/next-pwa && npm i -D webpack
Implementation
Step 1: Wrap your Next config with withPWA
Update or create your next.config.js
with
const withPWA = require("@ducanh2912/next-pwa").default({
dest: "public",
});
module.exports = withPWA({
// Your Next.js config
});
If your deployment platform requires your production image's size to not exceed a certain limit, you can also install @ducanh2912/next-pwa
as one of your
devDependencies
and do this:
const {
PHASE_DEVELOPMENT_SERVER,
PHASE_PRODUCTION_BUILD,
} = require("next/constants");
/** @type {import("next").NextConfig} */
const nextConfig = {
reactStrictMode: true,
};
module.exports = (phase) => {
if (phase === PHASE_DEVELOPMENT_SERVER || phase === PHASE_PRODUCTION_BUILD) {
const withPWA = require("@ducanh2912/next-pwa").default({
dest: "public",
});
return withPWA(nextConfig);
}
return nextConfig;
};
This plugin is written in TypeScript and supports JSDoc. It is recommended to
add // @ts-check
to the top of your next.config.js
file to leverage
typechecking. This is especially useful when you use
PluginOptions.workboxOptions
, as you may unknowningly mix
InjectManifest-specific and GenerateSW-specific options up.
After running next build
, this will generate two files in your public
directory: workbox-*.js
and sw.js
, which will
automatically be served statically.
Step 2: Add a web application manifest
Update app/manifest.json
(App Router) or public/manifest.json
(Pages Router) with the following content:
{
"name": "My awesome PWA app",
"short_name": "PWA 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"
}
Step 3: Add metadata to <head />
Add the following to your app/layout.tsx
or pages/_app.tsx
:
import type { Metadata, Viewport } from "next";
const APP_NAME = "PWA App";
const APP_DEFAULT_TITLE = "My Awesome PWA App";
const APP_TITLE_TEMPLATE = "%s - PWA App";
const APP_DESCRIPTION = "Best PWA app in the world!";
export const metadata: Metadata = {
applicationName: APP_NAME,
title: {
default: APP_DEFAULT_TITLE,
template: APP_TITLE_TEMPLATE,
},
description: APP_DESCRIPTION,
manifest: "/manifest.json",
appleWebApp: {
capable: true,
statusBarStyle: "default",
title: APP_DEFAULT_TITLE,
// startUpImage: [],
},
formatDetection: {
telephone: false,
},
openGraph: {
type: "website",
siteName: APP_NAME,
title: {
default: APP_DEFAULT_TITLE,
template: APP_TITLE_TEMPLATE,
},
description: APP_DESCRIPTION,
},
twitter: {
card: "summary",
title: {
default: APP_DEFAULT_TITLE,
template: APP_TITLE_TEMPLATE,
},
description: APP_DESCRIPTION,
},
};
export const viewport: Viewport = {
themeColor: "#FFFFFF",
};