Next.js
Install and configure Next.js as a PWA
Automatic Install
npx pwawtf next-app
Manual Install
Initialize project
Create a new Next.js project with create-next-app
:
npx create-next-app@latest my-app --typescript --tailwind
Install @ducanh2912/next-pwa
Once your Next.js project has been initialized, install @ducanh2912/next-pwa
:
npm i @ducanh2912/next-pwa
Configure @ducanh2912/next-pwa
Open up your next.config.js
file:
my-app/
├── public/
├── ...
├── next.config.js <- open
├── ...
└── tsconfig.json
And add the following:
// <rootDir>/next.config.js
const withPwa = require('@ducanh2912/next-pwa').default({
dest: 'public'
})
/** @type {import('next').NextConfig} */
const nextConfig = {}
module.exports = nextConfig
module.exports = withPwa(nextConfig)
Add a Manifest File
Create a manifest.json
file in your public
folder:
my-app/
├── public/
│ └── manifest.json
├── src/
├── ...
└── tsconfig.json
And fill it with:
// <rootDir>/public/manifest.json
{
"name": "My App",
"short_name": "My App",
"icons": [],
"theme_color": "#FFFFFF",
"background_color": "#FFFFFF",
"start_url": "/",
"display": "standalone",
"orientation": "portrait"
}
Add Icons
You will need to add 32x32
, 192x192
and 512x512
resolution icons to your public
folder:
my-app/
├── public/
│ ├── icon@32x32.png
│ ├── icon@192x192.png
│ ├── icon@512x512.png
│ └── manifest.json
├── src/
├── .gitignore
├── next-env.d.ts
├── next.config.js
├── package.json
├── README.md
└── tsconfig.json
If you don't have these handy yet, you can use ours as a placeholder for now:
32x32 | 192x192 | 512x512 |
---|---|---|
![]() | ![]() | ![]() |
Add Maskable Icon
Next, we will need to add a maskable icon (opens in a new tab) to adapt to different shapes.
We can take our icon@512x512.png
icon and run it through Maskable.app Editor (opens in a new tab) to generate a maskable icon.
If you don't want to do this now, you can use the maskable icon in the Download zip file we gave you.
Add the 512x512
maskable icon to your public
folder:
my-app/
├── public/
│ ├── icon@32x32.png
│ ├── icon@192x192.png
│ ├── icon@512x512.png
| ├── icon-maskable@512x512.png
│ └── manifest.json
├── src/
├── .gitignore
├── next-env.d.ts
├── next.config.js
├── package.json
├── README.md
└── tsconfig.json
Add Icons to manifest.json
Now that we have our icons, we can add them to our manifest.json
file:
// <rootDir>/public/manifest.json
{
"name": "My App",
"short_name": "My App",
"icons": [
{
"src": "icon@32x32.png",
"type": "image/png",
"sizes": "32x32"
},
{
"src": "icon@192x192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "icon@512x512.png",
"type": "image/png",
"sizes": "512x512"
},
{
"src": "icon-maskable@512x512.png",
"type": "image/png",
"sizes": "512x512",
"purpose": "maskable"
},
],
"theme_color": "#FFFFFF",
"background_color": "#FFFFFF",
"start_url": "/",
"display": "standalone",
"orientation": "portrait"
}
Add <meta>
tags to layout.tsx
Open the root layout.tsx
file:
my-app/
├── public/
├── src/
│ └── app/
│ └── layout.tsx <- open
├── ...
└── tsconfig.json
And add the following:
// <rootDir>/src/app/layout.tsx
import './globals.css'
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
const inter = Inter({ subsets: ['latin'] })
export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
manifest: '/manifest.json',
icons: [
{
url: '/icon@32x32.png',
sizes: '32x32',
type: 'image/png',
rel: 'icon',
},
{
url: '/icon@192x192.png',
sizes: '192x192',
type: 'image/png',
rel: 'icon',
},
{
url: '/icon@512x512.png',
sizes: '512x512',
type: 'image/png',
rel: 'icon',
}
],
themeColor: '#FFFFFF',
viewport: 'width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no',
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
)
}
Check your work
To make sure we've set everything up correctly, let's run a Lighthouse audit.
- Run
npm run dev
to start your Next.js App - Open up your Chromium browser and navigate to
http://localhost:3000
- Open up DevTools and go to the Lighthouse tab
- Click Progressive Web App under Categories
- Press the Analyze page load button to run the audit.
After auditing, you should see a score of 100 for PWA.