Files
cozsweet-frontend-nextjs/next.config.ts
T
admin 2acc005809 feat(pwa): wire up @ducanh2912/next-pwa + register SW in layout
PWA install flow was wired but unusable: pwaUtil.install() calls
deferred.prompt(), but Chrome only fires beforeinstallprompt when a
valid Service Worker is registered + a manifest is linked. The project
had both intent (manifest, usePwaInstall hook) but no live SW —
public/sw.js was a stale workbox build artifact from a previous
attempt with hardcoded chunk URLs that no longer matched any build.

What this commit does:

1. Add @ducanh2912/next-pwa@10.2.9 as devDependency.
2. Wrap nextConfig with withPWA({...}):
   - dest: "public" SW outputs to public/sw.js
   - disable: true skip SW generation in dev (HMR-friendly)
   - register: false don't auto-inject registration
   - workboxOptions.skipWaiting: true + clientsClaim: true — new SW
     takes over immediately
3. Add --webpack flag to dev/build/dev:proxy scripts.
   @ducanh2912/next-pwa is webpack-only; Turbopack (Next 16 default)
   doesn't load webpack plugins. Per user decision to accept the perf
   trade-off in exchange for a working PWA.
4. Delete stale public/sw.js (workbox will regenerate it at build
   time with the correct chunk URLs).
5. Add src/app/_components/core/sw-register.tsx: a no-UI client
   component that registers /sw.js in production. Mounted at the end
   of <body> in layout.tsx. disable: true means dev mode skips
   registration (no /sw.js to fetch anyway).

After this commit + pnpm build, public/sw.js is regenerated with
correct chunk URLs, registered on first prod load, and Chrome fires
beforeinstallprompt — usePwaInstall + pwaUtil.install() then trigger
the native install prompt end-to-end.
2026-06-16 19:36:03 +08:00

43 lines
1.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { NextConfig } from "next";
import withPWAInit from "@ducanh2912/next-pwa";
/**
* Next.js 16 临时绕过 `/_global-error` prerender 的 workStore bug
* 标记根 layout 不参与静态预渲染(global-error 会在请求时渲染)
* https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config
*
* 默认部署模型:`.next/` + `public/` + `next start`(或 Vercel 零配置)
* - `pnpm build` 产出 .next/(含 build manifest / chunks / 路由表 / 静态预渲染)
* - 脚本侧:scripts/deploy/_deploy_lib.sh 同步 .next/ + public/
* - 服务器启动:`cd <path> && next start -H 0.0.0.0 -p 3000`
* 或用 PM2`pm2 start "next start" --name cozsweet`
*
* PWA 集成:`@ducanh2912/next-pwa` 在 build 阶段用 workbox 生成 public/sw.js。
* - `dest: "public"` SW 输出到 public/sw.js
* - `disable: true` + dev NODE_ENV 跳过 dev —— 避免 HMR + 老 SW cache 冲突
* - `register: false` 不自动注入注册脚本 —— App Router 下走 <SwRegister /> 客户端组件更可控
* - `skipWaiting: true` 新 SW 立即接管(避免旧 SW 卡住页面)
*
* 已知 trade-off`@ducanh2912/next-pwa` 是 webpack-only 插件,与 Turbopack 不兼容。
* scripts 中加 `--webpack` flag 取消 Turbopack。等未来 next-pwa 支持 Turbopack 时再切回。
* Serwist 同样 webpack-only —— 见 node_modules/next/dist/docs/.../progressive-web-apps.md
*/
const nextConfig: NextConfig = {
experimental: {
// 关闭静态优化以规避 16.2.7 global-error prerender bug
staticGenerationRetryCount: 0,
},
};
const withPWA = withPWAInit({
dest: "public",
disable: true, // 仅当 NODE_ENV === "development" 时跳过 SW 生成
register: false,
workboxOptions: {
// skipWaiting + clientsClaim 嵌在 workboxOptionsGenerateSWOptions 字段)
skipWaiting: true,
clientsClaim: true,
},
});
export default withPWA(nextConfig);