OWolf

BlogToolsProjectsAboutContact
© 2025 owolf.com
HomeAboutNotesContactPrivacy

2025-06-30 Web Development

How to Create a Super Minimal Progressive Web App (PWA) with Next.js 15

By O. Wolfson

Progressive Web Apps offer app-like experiences directly in the browser: installable, offline-capable, and fast. With Next.js 15 and its App Router, you can turn a basic web app into a minimal PWA in just a few steps—no push notifications, no extras, just the core requirements.

Code: Minimal PWA with Next.js 15

Deployed: Minimal PWA with Next.js 15


1. Project Setup

If you don’t have a Next.js project yet:

sh
npx create-next-app@latest my-minimal-pwa
cd my-minimal-pwa

2. Add App Manifest

Create the manifest file at app/manifest.json (not in /public, not /src/app):

json
{
  "name": "Minimal Next.js PWA",
  "short_name": "MinimalPWA",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#317EFB",
  "icons": [
    {
      "src": "/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}

Tip: The manifest must include at least one 192x192 and one 512x512 PNG icon (add these to /public).


3. Add Icons

Place your icons in /public:

  • /public/icon-192x192.png
  • /public/icon-512x512.png

You can generate these with realfavicongenerator.net or any image editor.


4. Minimal Service Worker

Create a file /public/sw.js:

js
// public/sw.js
self.addEventListener("install", () => self.skipWaiting());
self.addEventListener("activate", () => self.clients.claim());

This is a no-op (doesn’t cache files), but registers the service worker, which is required for installability.


5. Register the Service Worker

Create a simple registration component: components/sw-register.tsx

tsx
"use client";
import { useEffect } from "react";

export default function SWRegister() {
  useEffect(() => {
    if ("serviceWorker" in navigator) {
      navigator.serviceWorker.register("/sw.js");
    }
  }, []);
  return null;
}

6. Link Everything in Your Layout

Edit app/layout.tsx:

tsx
import SWRegister from "@/components/sw-register";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <head>
        <link rel="manifest" href="/manifest.json" />
        <meta name="theme-color" content="#317EFB" />
      </head>
      <body>
        <SWRegister />
        {children}
      </body>
    </html>
  );
}

7. Add a Home Page

Edit app/page.tsx:

tsx
export default function Page() {
  return (
    <main>
      <h1>Minimal Next.js PWA</h1>
      <p>This is the simplest possible PWA using Next.js 15.</p>
    </main>
  );
}

8. Deploy and Test

  • Deploy to Vercel or run locally with pnpm dev or npm run dev.
  • Visit the site in Chrome.
  • You’ll see the “Install” (computer with download arrow) icon in the address bar.
  • Click it to install your PWA!

DevTools Checks

  • Open Chrome DevTools → Application tab → Manifest
  • You should see all green checkmarks and no manifest errors.

FAQ

  • Is offline support included? Not with this minimal SW, but you can add caching later.
  • Where are icons stored? In /public/ so they’re accessible at the root.
  • Can I add features later? Yes—add caching, push, badges, etc., as you need them.

Conclusion

This is the absolute minimum you need for a true PWA in Next.js 15: manifest.json, two icons, a minimal service worker, and one registration component. From here, you can expand to add whatever features your users need—offline support, install prompts, push notifications, and more.


Chat with me

Ask me anything about this blog post. I'll do my best to help you.