Repository navigation
Progressive Web Application #685
Copy link
Copy link
Open
Description
You are an expert Next.js and PWA developer.
I have an existing Next.js application (using App Router, Next.js 14+). Convert it into a fully functional Progressive Web App (PWA) that can be installed/downloaded as a native-like app on Android (via Chrome) with the following requirements:
Core PWA Features Required:
-
Web App Manifest (
manifest.json)- Proper
name,short_name,description - Multiple icon sizes (192x192, 512x512, maskable icons)
start_url,display: standalone,theme_color,background_colororientation: portraitoranyas needed- Categories and screenshots if possible
- Proper
-
Service Worker
- Workbox or custom service worker for caching (pages, assets, API responses)
- Offline support (show cached content or offline page)
- Background sync / push notification readiness (even if not implementing push yet)
- Proper caching strategies (NetworkFirst for API, CacheFirst for static assets)
-
Next.js Configuration
- Use
next-pwaplugin if recommended, or manual setup withnext.config.js/next.config.mjs - Correct handling of App Router (
app/directory) - Environment variables and build optimizations for PWA
- HTTPS enforcement reminder / secure context
- Use
-
Installation Experience on Android
- Make the "Install" / "Add to home screen" prompt appear reliably in Chrome on Android
- Proper meta tags (
<meta name="theme-color">, apple-touch icons for broader compatibility) - Custom install button (optional but recommended) with
beforeinstallpromptevent
-
Best Practices
- Lighthouse PWA score ≥ 90
- Fast loading (Core Web Vitals optimized)
- Responsive design already assumed
- Update handling (new version notification)
- Fallback offline page
Deliverables:
- Full updated
next.config.js/next.config.mjs - Complete
public/manifest.json - Service worker file(s) location and code
- Any new components (e.g., InstallPrompt component)
- Updated
app/layout.tsxor_document.jswith all necessary<Head>/ meta tags - Instructions for:
- Running in development mode with PWA
- Building and testing the PWA
- How to test installability on Android (Chrome DevTools + Android device)
- Deploying to Vercel/Netlify (PWA-compatible hosting)
Assume the project uses TypeScript and Tailwind. Provide the complete code changes with clear file paths and diff-style explanations where helpful.
Start by asking me for any specific details about my app (name, icons, features, current folder structure) if needed, otherwise provide a complete ready-to-use implementation.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
ngoiyaeric commentedon Jun 26, 2026
@coderabbitai plan
coderabbitai commentedon Jun 26, 2026
Coding Plan
Summary
@serwist/next(modern Workbox successor) for Next.js 15 App Router compatibility, wrapping the existingnext.config.mjswithout disturbing current settings.eva-logo.png), andMetadata/Viewport-based head tags using theearththeme colors — to make the Android/Chrome install prompt eligible.InstallPromptand update-notification UX (reusing the existing Toaster), plus concise dev/build/test/deploy documentation.Design Choices
Design Choice 1: PWA tooling/library for service worker and build integration
Options Considered:
next-pwa— classic plugin, widely documented but unmaintained and unreliable on Next 15/App Router.@ducanh2912/next-pwa— community fork of next-pwa, works but largely superseded.@serwist/next(Serwist) — actively maintained Workbox successor with first-class App Router + Next 15 support, TypeScript service worker, and built-in injection/precache manifest.Chosen Option: 3
Rationale: Option 3 (
@serwist/next): it is the modern, maintained choice with proven Next.js 15 App Router compatibility, satisfies the Workbox/caching-strategy requirements, and avoids the build fragility ofnext-pwa.Design Choice 2: Source asset for generating required PWA icons (192, 512, maskable)
Options Considered:
public/images/eva-logo.png(252 KB PNG) as the source to generate sized/maskable icons.public/images/logo.svg(2.2 MB) rasterized to required sizes.Chosen Option: 1
Rationale: Option 1:
eva-logo.pngis the most appropriately sized raster source and the simplest path to standard square + maskable icon variants.💡 User Tips
Regenerate the plan with different choices with
@coderabbitai <feedback>.Implementation Steps
Phase 1: PWA Tooling and Build Configuration
Introduce the service-worker build tooling and wire it into the existing Next.js configuration so the rest of the PWA assets have a working compilation/injection pipeline. This phase establishes the foundation without yet changing runtime UI.
Task 1: Add Serwist dependencies
Install the chosen PWA tooling and supporting types.
@serwist/nextandserwisttopackage.jsondependencies usingbun.next-pwa,workbox-*) should be added.Task 2: Wrap next.config.mjs with the Serwist plugin
Integrate service-worker generation into the build while preserving existing config.
next.config.mjsto import and apply the SerwistwithSerwist/withSerwistInitwrapper around the current exported config object.output: 'standalone',experimental.serverActions,transpilePackages).public/sw.js), and disable service-worker generation in development to avoid caching friction during local work.output: 'standalone'requires the generatedsw.jsto be served from the public root scope (which it is, as a static public asset).🤖 Prompt for AI agents
Phase 2: Manifest, Icons, and Installability Metadata
Provide the declarative install surface Android/Chrome needs: a valid manifest, a proper icon set, and the head metadata/theme-color tags that make the install prompt eligible and improve cross-platform (Apple) compatibility.
Task 1: Generate the PWA icon set
Create the standard and maskable icons required for installability.
public/images/eva-logo.pngand place them underpublic/icons/.192x192and512x512"any" icons plus a512x512"maskable" variant (with adequate safe-zone padding) and anapple-touch-icon(180x180).Task 2: Author the web app manifest
Define the installable app identity and presentation.
public/manifest.json(orapp/manifest.tsroute handler) withname,short_name,description,start_url(/),display: standalone,orientation(portraitorany),theme_color, andbackground_color.earththeme (e.g., background#ede8df, theme/accent#246024) documented inapp/globals.css.categories; include optionalscreenshotsentries only if assets are available.Task 3: Add PWA head metadata to the root layout
Make the manifest, theme color, and Apple compatibility tags discoverable.
Metadataexport inapp/layout.tsxto addmanifest(pointing to the manifest), aniconsfield (standard + apple-touch), andappleWebAppsettings (capable, status bar style, title).Viewportexport to addthemeColor(optionally light/dark media variants matchingearth/darktheme backgrounds), keeping the existing viewport zoom settings intact.<head>elements where theMetadata/Viewportexports already cover them; leave the existing HTMX shim script untouched.🤖 Prompt for AI agents
Phase 3: Service Worker, Caching Strategies, and Offline Fallback
Implement the runtime offline behavior: a service worker that precaches the app shell, applies route-appropriate caching strategies, serves an offline fallback page, and is structured to be push/background-sync ready.
Task 1: Create the service worker source
Define the Serwist-based service worker with caching strategies.
app/sw.ts) referenced by the Phase 1 plugin config.CacheFirstfor immutable static assets (_next/static, images, fonts, icons).NetworkFirstfor navigation/page requests and for/api/*responses (so authenticated, user-specific data stays fresh while remaining available offline); explicitly avoid caching mutating routes (POST /api/chat,DELETE /api/chats/all).StaleWhileRevalidatefor the deterministicGET /api/embeddingsroute.push/synclisteners or Serwist plugin hooks) to establish push/background-sync readiness without implementing a backend.Task 2: Add an offline fallback page
Provide cached content when the network is unavailable.
app/offline/(a simple, statically renderable page consistent with existing layout/theming).🤖 Prompt for AI agents
Phase 4: Install/Update UX and Documentation
Add the client-side experience that improves install reliability and surfaces new-version notifications, then document how to run, test, and deploy the PWA.
Task 1: Build a custom Install prompt component
Capture and trigger the Android install flow.
InstallPromptclient component incomponents/that listens for thebeforeinstallpromptevent, suppresses the default prompt, stores the deferred event, and renders a custom install button that callsprompt()on click.display-mode: standalone) or when the event is unavailable; follow existing component/styling conventions (Tailwind, theme-aware).app/layout.tsx's persistent UI region.Task 2: Add service-worker update notification handling
Notify users when a new version is available.
components/) that registers/observes the Serwist service-worker lifecycle, detects a waiting/updated worker, and surfaces a non-intrusive notification (reuse the existingToaster/sonner setup) prompting a reload to activate the new version.Task 3: Document development, testing, and deployment
Provide the operational instructions called out in the ticket deliverables.
docs/PWA.mdor README addition) covering: running locally (noting SW is disabled in dev), production build/serve to exercise the SW, testing installability via Chrome DevTools (Application tab → Manifest/Service Workers/Lighthouse) and on a physical Android device over HTTPS, and the HTTPS/secure-context requirement.public/manifest.json, generatedpublic/sw.js, and icons are served from the root and thatoutput: 'standalone'remains compatible.🤖 Prompt for AI agents
Research
This is a Next.js 15.3.8 / React 19 App Router project managed with
bun. The rootapp/layout.tsxuses the modernMetadataandViewportexports (currently only OG/Twitter cards, a locked-zoom viewport, and an inline HTMX shim in<head>), and wraps the app in a stack of context providers plusnext-themes(default themeearth).next.config.mjsis minimal withoutput: 'standalone', server-action origins, andtranspilePackages; it has no PWA tooling.middleware.tsis effectively pass-through and excludes_next/static, so a root-scoped service worker is unobstructed.public/contains onlyimages/(witheva-logo.pngas the sole viable icon source) — there is no manifest, no service worker, and no PWA icon set. API routes underapp/api/(chat/chats/embeddings/health) currently set no cache headers.🚀 Next Steps
🤖 All AI agent prompts combined
💡 Iterate on the plan with:
`@coderabbitai` <feedback>💬 Have feedback or questions? Drop into our discord!