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.