A sample project for push notifications with Next.js. The app used web push notifications to send messages to users. The notification should work on all devices and browsers.
Require IOS 16+ for Apple devices.
A live demo of the project can be found here
First, run the development server:
npm install
Run the below command to generate the vapid keys. Once you have the keys, rename the .env.example
file to .env
and
insert the keys.
web-push generate-vapid-keys --json
Start the development server:
npm run dev
Open http://localhost:3000 with your browser to see the result.
The app uses the web-push package to send push notifications. The app has a service worker that listens for push events and displays the notification.
Using just this package is enough to send push notifications from most devices and browsers.
However, on Apple devices, there are a few extra things we have to do.
- The app must be served over HTTPS with a valid SSL certificate.
- The app must be a PWA (Progressive Web App).
You can read more about it here.
Install the below packages.
npm install web-push next-pwa
Skip this step if you are using typescript.
npm install @types/web-push --save-dev
Copy the notification-sw.js file into the public
folder. This is a service worker that listens for push events and displays the notification.
Copy the files under the notifications folder and paste them into your src folder. In my case I pasted them in the
src/notifications
folder. The useNotification
hook will be used in the app to subscribe a user and store the
subscription in state. This subscription can be stored in a database and used to send notifications per user.
Take a look at the page.tsx
file to see how the useNotification
hook is used. The page.tsx
calls an endpoint that is found under src/app/api/web-push/send/route.ts
. This will send the notification to the user.
With this should be able to send notifications now. For Apple devices, you will need to configure the app as a PWA in the next step.
The next-pwa package will generate a sw-pwa.js
and a workbox-*.js
file in
the public folder.
I am going to use pwabuilder to generate the icons for the app. This will generate the different sizes of the icon that are needed for different devices. After going to the site, download the zip file and place the contents into the public folder. You should get 3 folders: android, ios, and windows. Also, an icons.json
file which we will use for our manifest file.
Move the icons.json
file to the public
folder and rename it to manifest.json
.
{
"name": "Push Notification Sample",
"short_name": "Push Notification Sample",
"description": "A sample project for push notifications with Next.js",
"theme_color": "#FFFFFF",
"background_color": "#FFFFFF",
"start_url": "/",
"display": "standalone",
"orientation": "portrait",
"icons": // the icons will be here
}
add the manifest.json
file to the layout.tsx
file.
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<head>
<link rel="manifest" href="/manifest.json" />
</head>
<body className={`${inter.variable} ${ibmPlexSerif.variable}`}>
<NotificationProvider>{children}</NotificationProvider>
</body>
</html>
);
}
modify the next.config.js
file to include the next-pwa
configuration.
/** @type {import('next').NextConfig} */
const withPWA = require("next-pwa")({
dest: "public",
sw: "sw-pwa.js",
});
module.exports = withPWA({
output: "standalone",
});