Next.js App Router 审查 Prompt(16 + Cache Components)

15 个可直接复制的 Next.js App Router 代码审查 Prompt,已适配 Next.js 16——server/client 边界、Server Action、use cache、cacheTag、proxy.ts、streaming。2026 年 6 月更新。

一句”帮我审审 Next.js 代码”会漏掉真正拖垮生产的 App Router 陷阱:一个 useState 污染了服务端组件、一个本该裹进 use cache 的 fetch、一个改完数据却没调 updateTag 的 Server Action。到了 Next.js 16(2025 年 10 月 21 日起稳定,截至 2026 年 6 月 npm 稳定版为 16.2.7),默认行为又变了:缓存改成显式 opt-in、middleware.ts 正被 proxy.ts 取代、Turbopack 成为默认打包器、cookies() / params 变成异步。下面 15 个 Prompt 各盯一个 App Router 特有的失败模式,已按 Next.js 16 模型刷新。每个 Prompt 都把确切的 next 版本贴进去:模型通常比框架慢好几个月,回答只跟你给的版本一样新。

一句话总结

  • 先跑 Prompt 1(边界审计)——边界 bug 会级联到后面每一条发现。
  • Next.js 16 把缓存改成显式 opt-inuse cache + cacheLife() + cacheTag() 取代旧的隐式 fetch 缓存。Prompt 2、4、5、13 都按新模型重写了。
  • middleware.tsproxy.ts(Node runtime)、cookies() / headers() / params 异步化,分别在 Prompt 9、10 里查。
  • 每个 Prompt 都要求 file:line 证据、并禁止 AI 重写代码,输出始终可 review。
  • 每次都把 next.config.ts 和确切的 next 版本贴进 Prompt——模型的回答只跟你给的版本一样新。

适合哪些场景

正在发 App Router 应用的工程师(Next.js 13.4 到 16)、审 Server Action PR 的 reviewer、从 Pages Router 迁移的独立开发者、版本升级后排 hydration / 缓存意外的团队。

Next.js 16 改了什么(审查前先看)

如果你审的是刚升级过的代码库,下面这些默认行为都变了。每个缓存类 Prompt 都要先确认代码库用的是哪套模型。

方面Next.js 13–15Next.js 16(截至 2026 年 6 月)
缓存隐式;13/14 默认缓存 fetch,15 默认不缓存显式 use cache 指令 + cacheLife() / cacheTag()(Cache Components)
默认渲染不用动态 API 就是静态部分预渲染(PPR)——静态外壳 + 流式动态空洞
Edge/Node 拦截层middleware.tsproxy.ts(Node runtime);middleware.ts 已弃用,仅保留给 Edge
缓存失效revalidateTag(tag)updateTag(tag)(read-your-writes,仅 action)和 revalidateTag(tag, profile)
cookies() / headers() / params / searchParams同步(15 起改异步)异步——必须 await
打包 / lint默认 webpack;next lint默认 Turbopack;next lint 已移除(直接跑 ESLint/Biome)

Pages Router 代码跳过这套(缓存、数据获取、组件模型都不一样),纯静态营销站也跳过(根本不碰 App Router 的服务端特性)。最适合的场景:App Router 迁移 PR、上线前的缓存 / revalidate 审计、Server Action 安全审查、hydration / 边界排错,以及 Next.js 升级后的性能回归排查。

15 个可直接复制的 Prompt 模板

1. server vs client 边界审计

第一个跑——边界 bug 会级联。

You are a senior Next.js reviewer. Audit this App Router code for SERVER vs CLIENT boundary violations: (1) files with `"use client"` that should be server (no interactivity), (2) server files importing client-only APIs (window, useState), (3) client components receiving non-serializable props, (4) deep client trees that could be shifted to server. For each: file:line, why it's wrong, the fix. Do not refactor.

2. Server Action 正确性 review

Review every `"use server"` action in this code for: (1) input validation (zod / valibot / manual), (2) auth check at the TOP of the action — server actions are publicly callable endpoints, (3) cache invalidation after mutation: `updateTag` (read-your-writes, preferred in Next.js 16), `revalidateTag(tag, profile)` with its required cacheLife profile, or `revalidatePath`, (4) error handling that returns a typed result object (not throw), (5) idempotency for retries. Output: action name | finding | severity.

3. route handler review

Review `route.ts` handlers in `app/api/`: (1) Method handlers (GET/POST/etc) — any missing? (2) Response shape consistency, (3) `dynamic = "force-dynamic"` vs default — is the choice intentional? (4) Auth middleware coverage, (5) CORS for cross-origin. List findings with file:line.

4. fetch 缓存 / use cache 审计

Next.js 16 把”缓存模式”这一问换成 use cache 覆盖率。

This is a Next.js 16 codebase using Cache Components (`cacheComponents: true`). Audit data fetching in server components and route handlers. For each fetch/db call: (1) Is it inside a `use cache` function/component, wrapped in `<Suspense>`, or neither (which throws "Uncached data was accessed outside of <Suspense>")? (2) Does cached data have a `cacheLife()` profile matching its freshness needs and a `cacheTag()` for targeted invalidation? (3) Any user-specific data inside `use cache` without the user key in scope (cross-user leak)? (4) Duplicate fetches per request that should be deduped. File:line evidence required. If the repo is on Next 13/14/15, review classic `fetch` cache modes (default / no-store / force-cache / revalidate=N) instead.

5. 缓存失效覆盖

updateTag / revalidateTag / revalidatePath / refresh 行为各不相同——把每个写操作映射到对的那个。

Map every mutation (server action, POST route handler, webhook). For each: (1) Does it invalidate the cache it changed? (2) Is the API correct for the intent — `updateTag` for read-your-writes (user sees their own edit immediately, actions only), `revalidateTag(tag, profile)` for stale-while-revalidate content, `revalidatePath` for whole-path, `refresh` for uncached live data? (3) Does the tag match a `cacheTag()` actually set on the read side? (4) Reads that won't reflect the mutation because they aren't tagged? Note: in Next.js 16 single-arg `revalidateTag(tag)` is deprecated and needs a cacheLife profile. List gaps as: mutation | should invalidate | currently invalidates.

6. streaming 与 Suspense 审计

Review use of Suspense boundaries and streaming in this App Router code (Next.js 16 uses Partial Prerendering by default, so anything not in `use cache` and not wrapped in `<Suspense>` blocks the static shell). Identify: (1) uncached/runtime data not wrapped in Suspense, (2) loading.tsx files missing where they'd help LCP, (3) waterfalls of awaited fetches that should be parallelized, (4) Suspense boundaries placed too high (whole-page loading) or too low (jittery), (5) an empty Suspense fallback above <body> in a root layout that accidentally opts the whole app out of the static shell. Suggest specific Suspense placements.

7. metadata 与 SEO review

Audit Next.js metadata (`generateMetadata` + static metadata): (1) every route has a title and description? (2) Open Graph and Twitter card present for shareable routes? (3) `alternates.canonical` set for routes reachable at multiple URLs? (4) Dynamic metadata using the same data as the page (no duplicate fetch)? File:line.

8. <Image> 与资源优化 review

Review `<Image>` usage in this code: (1) `width` and `height` explicit (no layout shift)? (2) `priority` set on above-fold images? (3) `sizes` attribute correct for responsive use? (4) `remotePatterns` in next.config covers all sources? (5) Any `<img>` tags that should be `<Image>`? Output: image | issue.

9. middleware / proxy.ts review

Next.js 16 把 middleware.ts 改名为 proxy.ts(Node runtime);把漏改的揪出来。

Review the request interceptor (`proxy.ts` in Next.js 16, or legacy `middleware.ts`): (1) On Next.js 16, is it still named `middleware.ts` and exporting `middleware()` when it should be `proxy.ts` exporting `proxy()`? (2) matcher config covers the intended routes only — no overmatching that runs on every asset? (3) Auth checks early-return correctly? (4) Header / cookie mutations applied via `NextResponse.next({ headers })` rather than mutating the request? (5) Any heavy business logic that belongs in a route handler or server action, not the interceptor? File:line findings.

10. cookies 与 session review

Audit cookie usage across server components, server actions, and route handlers: (1) On Next.js 15+ is every `cookies()` / `headers()` call `await`ed (they are async)? (2) Reads via `cookies()` outside a `<Suspense>` boundary that block the static shell when the surrounding content could be cached? (3) httpOnly / secure / sameSite flags correct? (4) Session reads duplicated per request that should be deduped with React `cache()` or pulled out and passed into a `use cache` component as a prop? (5) Cookies set in server components (illegal — must be in actions / route handlers)?

11. error / not-found 边界 review

Review `error.tsx`, `global-error.tsx`, `not-found.tsx`: (1) Every route segment with possible errors has one? (2) Error boundaries log to observability? (3) `reset()` functions are wired up? (4) `notFound()` called from data-fetch paths that 404? List missing files and missing handlers.

12. 并行 / 拦截路由 review

If this app uses parallel routes (`@slot`) or intercepting routes (`(.)folder`), audit: (1) Default slots present where required? (2) Slot loading / error files in place? (3) Intercepting routes degrade correctly when accessed directly via URL? If no parallel/intercepting routes exist, say so — do not invent.

13. dynamic / static 渲染审计

For each route segment, determine rendering mode. On Next.js 16 with Cache Components, classify as: fully prerendered static shell / PPR (static shell + streamed dynamic holes) / fully dynamic. Output a table: route | mode | what forces request-time work (cookies()/headers()/searchParams/connection()/uncached fetch) | could it be moved into `use cache` instead? Flag routes that defer the whole shell to request time (e.g. an empty Suspense fallback over <body>) — those are usually perf regressions. On Next 13/14/15, classify as static / dynamic / ISR instead.

14. App Router 升级兼容 review

升级 Next.js minor/major 后用。

I just upgraded Next.js from `[fromVersion]` to `[toVersion]`. Review this code for breakage and new-best-practice opportunities specific to that jump. If upgrading to 16, specifically flag: sync `cookies()`/`headers()`/`params`/`searchParams` that must now be awaited; `middleware.ts` that should become `proxy.ts`; implicit fetch caching that now needs `use cache` + `cacheLife`/`cacheTag`; single-arg `revalidateTag(tag)` missing its cacheLife profile; `next lint` scripts (removed); and any `runtime = 'edge'` defaults. Output: file | change | severity (breaking / warning / nice-to-have).

可替换变量: 两个版本占位符——例如 15.416.2

15. App Router 发现 → 修复 PR 计划

最后跑——把发现转成 PR 序列。

Take the findings from previous App Router reviews and group them into 3-5 PRs sized for solo review (each < 400 LOC diff). For each PR: title, files touched, dependency on other PRs, rollback plan. Output as markdown.

容易踩的坑

  • 当 Pages Router 审——缓存、数据获取、组件模型都不同。
  • 用 Next 14 的认知审 Next.js 16 仓库——缓存现在是显式的(use cache),不再隐式。先确认版本。
  • 写操作后没做缓存失效——read-your-writes 用 updateTag,能容忍短暂滞后的内容用 revalidateTag(tag, profile)。典型症状就是生产读到旧数据。
  • 全部 "use client"——服务端组件的好处全没了,要审多余的 client 边界。
  • 看到 dynamic = "force-dynamic" 就放过——多半藏着缓存配错。
  • 不查 proxy.ts / middleware.ts matcher——overmatch 会在每个静态资源上都跑一遍,拖垮性能。
  • Server Action 顶部不加 auth 门——它是公开可调用的端点。
  • 忘了 Next.js 15+ 的 cookies() / headers() / params 是异步的——没 await 的 Promise 当真值用,会埋下静默 bug。

优化技巧

  • 永远先跑 server/client 边界(Prompt 1),其他发现都源自这里。
  • 每个 Prompt 都把确切的 next 版本和 next.config.ts(好让模型知道有没有开 cacheComponents)一起贴进去。模型的回答只跟你给的版本一样新。
  • 每条发现都要 file:line 证据和触发这个问题的具体 import 或 directive。
  • 缓存审计按路由跑,别全局跑——不同路由缓存预期不同。
  • Server Action 必须显式 review auth、validation、失效。
  • 每次 Next.js 升级跑升级兼容 Prompt(14)——能抓默认值变化(缓存、异步 API、proxy.ts)。
  • 把发现做成 checklist,每个修复 PR 后重跑——缓存 bug 爱回来。
  • 人工 review 配合 next build(现在会报 Suspense 外的未缓存数据)和 next start LCP 对比——Prompt 抓不到真实运行时回归。

FAQ

  • 这套也适用于 Pages Router 吗?: 不适用——模型完全不同。Pages Router 代码用通用的 React 审查 Prompt。
  • 代码库升到了 Next.js 16 但还在用旧缓存写法,怎么审?: 这是最常见的升级缺口。先跑 Prompt 14 把隐式 fetch 缓存找出来,再用 Prompt 4 把每个 fetch 映射到 use cache + cacheLife / cacheTag。同时告诉模型 next.config.ts 里有没有设 cacheComponents: true
  • updateTagrevalidateTag——Server Action 该用哪个?: updateTag(tag) 给的是 read-your-writes(用户立刻看到自己刚改的内容,会阻塞到数据刷新为止),只能在 Server Action 里用。在 Route Handler 或 webhook 里改用 revalidateTag(tag, profile)——它是 stale-while-revalidate,适合能容忍短暂滞后的内容。到了 Next.js 16,单参数的 revalidateTag(tag) 已弃用,必须带一个 cacheLife profile(内置名如 'hours' / 'days' / 'max',或 next.config.ts 里自定义的)。
  • Server Action 调了很多 helper,怎么界定审查范围?: 粘 Server Action 文件加上它直接调用的那几个 helper,别粘整个仓库——聚焦比覆盖更重要。
  • AI 知道最新的 Next.js 版本吗?: 只有你告诉它才知道。在 Prompt 里写明确切版本;对刚发布的版本,把相关的 changelog 或升级指南片段也贴一段。模型通常比框架慢好几个月。
  • 15 个能一次跑完吗?: 能,但发现会糊成一团。先跑边界,再跑缓存,最后其他。
  • Edge runtime 怎么办?: 在 Prompt 里加一句:“Some routes run on Edge — flag Node-only APIs in Edge-runtime files.” 注意 Next.js 16 里 Node-runtime 的拦截层是 proxy.tsmiddleware.ts 仅保留给 Edge,但已弃用。

相关阅读

外部参考:Next.js 16 发布说明Cache Components 缓存指南use cache 模型的权威来源;审查刚升级过的代码时,把相关章节贴进 Prompt 里。

标签: #Prompt #编程 #Next.js #代码审查