Building a Progressive Web App (PWA) with Next.js – Installable, Offline-Ready, and Push-Enabled

With Next.js, you can build a Progressive Web App that behaves like a native mobile app — installable, fast, offline-capable, and able to send push notifications. This article walks you through each step: creating a manifest, setting up push notifications, registering a service worker, securing your app, and testing locally.

PWAPush NotificationsService WorkerWeb App Manifest

~2 min read • Updated Dec 13, 2025

What is a PWA?


A Progressive Web App combines the best of web and mobile:

  • Installable: Add to home screen like a native app
  • Push Notifications: Engage users even when the site is closed
  • Offline Support: Works without internet
  • Fast & Responsive: Smooth experience even on slow networks
  • No App Store: Instant updates, no approval needed

Step 1: Create Web App Manifest


Create app/manifest.ts with metadata and icons:

export default function manifest() {
  return {
    name: 'Next.js PWA',
    short_name: 'NextPWA',
    description: 'A Progressive Web App built with Next.js',
    start_url: '/',
    display: 'standalone',
    background_color: '#ffffff',
    theme_color: '#000000',
    icons: [
      { src: '/icon-192x192.png', sizes: '192x192', type: 'image/png' },
      { src: '/icon-512x512.png', sizes: '512x512', type: 'image/png' },
    ],
  }
}

Place icons in the public/ folder.


Step 2: Add Push Notifications


In app/page.tsx, create a client component that:

  • Registers a service worker
  • Subscribes/unsubscribes the user
  • Sends test notifications

Step 3: iOS Install Prompt


Detect iOS and standalone mode to show install instructions only when needed.


Step 4: Server Actions


In app/actions.ts, implement:

  • subscribeUser: Save subscription
  • unsubscribeUser: Remove subscription
  • sendNotification: Send push using web-push

Step 5: Generate VAPID Keys


npm install -g web-push
web-push generate-vapid-keys

Add keys to .env.local:

NEXT_PUBLIC_VAPID_PUBLIC_KEY=...
VAPID_PRIVATE_KEY=...

Step 6: Create Service Worker


In public/sw.js, add listeners for:

  • push: Show notification
  • notificationclick: Open site

Step 7: Security Headers


In next.config.js, add headers for:

  • X-Content-Type-Options
  • X-Frame-Options
  • Referrer-Policy
  • Content-Security-Policy for /sw.js

Step 8: Test Locally


next dev --experimental-https

Verify:

  • HTTPS is enabled
  • Notifications are allowed
  • Service Worker is registered
  • Manifest is valid (DevTools → Application)

Optional: Offline Support with Serwist


npm install serwist

See Serwist + Next.js example for full offline support.


Written & researched by Dr. Shahin Siami