Next.js App Router Review Prompts (16 + Cache Components)

15 copy-ready Next.js App Router code review prompts for Next.js 16 — server/client boundaries, server actions, use cache, cacheTag, proxy.ts, streaming. Updated June 2026.

A generic “review my Next.js code” misses the App-Router traps that actually break production: a stray useState poisoning a Server Component, a fetch that should have been wrapped in use cache, a Server Action that mutates without calling updateTag. Next.js 16 (stable since October 21, 2025; 16.2.7 is the current npm stable as of June 2026) moved the defaults again — caching is opt-in, middleware.ts is being replaced by proxy.ts, Turbopack is the default bundler, and cookies() / params are async. These 15 prompts each interrogate one App-Router-specific failure mode, refreshed for the Next.js 16 model. Paste the exact next version with every one; models trail the framework by months, so the answer is only as current as the version you hand it.

TL;DR

  • Run prompt 1 (boundary audit) first — boundary bugs cascade into every other finding.
  • Next.js 16 made caching opt-in: use cache + cacheLife() + cacheTag() replace the old implicit fetch cache. Prompts 2, 4, 5, and 13 are rewritten for this model.
  • middleware.tsproxy.ts (Node runtime) and async cookies() / headers() / params are checked in prompts 9 and 10.
  • Each prompt demands file:line evidence and forbids the AI from refactoring, so output stays reviewable.
  • Paste your next.config.ts and the exact next version with every prompt — the model’s answer is only as current as the version you give it.

Who this is for

Engineers shipping App Router apps (Next.js 13.4 through 16), reviewers approving Server Action PRs, indie devs migrating from Pages Router, and teams debugging hydration or caching surprises after a version bump.

What changed in Next.js 16 (read before reviewing)

If you are reviewing a recently upgraded codebase, these are the defaults that moved. Anchor every caching prompt to whichever model the repo is on.

AreaNext.js 13–15Next.js 16 (as of June 2026)
CachingImplicit; fetch cached by default in 13/14, uncached by default in 15Explicit use cache directive + cacheLife() / cacheTag() (Cache Components)
Rendering defaultStatic unless a dynamic API is usedPartial Prerendering (PPR) — static shell + streamed dynamic holes
Edge/Node interceptormiddleware.tsproxy.ts (Node runtime); middleware.ts deprecated, kept for Edge
Cache invalidationrevalidateTag(tag)updateTag(tag) (read-your-writes, actions only) and revalidateTag(tag, profile)
cookies() / headers() / params / searchParamssync (15 made them async)async — must be awaited
Bundler / lintwebpack default; next lintTurbopack default; next lint removed (run ESLint/Biome directly)

Skip these for Pages-Router code (different caching, data-fetching, and component model) and for static-only marketing sites that never exercise App Router’s server features. Best fit: App Router migration PRs, pre-launch caching/revalidation audits, Server Action security review, hydration/boundary debugging, and performance-regression hunts after a Next.js upgrade.

15 copy-ready prompt templates

1. Server vs client boundary audit

Run first — boundary bugs cascade.

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 correctness 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 caching / use cache audit

In Next.js 16, swap the cache-mode question for use cache coverage.

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. Cache invalidation coverage

updateTag / revalidateTag / revalidatePath / refresh each behave differently — map mutations to the right one.

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 and Suspense audit

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 and 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 and asset optimization 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 renames middleware.ts to proxy.ts (Node runtime); flag stragglers.

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 and 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 and not-found boundary 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. Parallel and intercepting routes 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 rendering audit

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 upgrade compat review

Use after bumping the 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).

Variables to swap: the two version placeholders — e.g., 15.4 and 16.2.

15. App Router findings → fix PR plan

Run last to convert findings into a PR sequence.

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.

Common mistakes

  • Reviewing as if it were Pages Router — App Router has different caching, data fetching, and component models.
  • Reviewing a Next.js 16 repo with Next 14 assumptions — caching is now explicit (use cache), not implicit. Confirm the version first.
  • Missing cache invalidation after mutations — pick updateTag for read-your-writes, revalidateTag(tag, profile) for stale-while-revalidate. A stale read in production is the classic symptom.
  • Marking everything "use client" — kills the Server Component benefit; review for unnecessary client boundaries.
  • Accepting dynamic = "force-dynamic" without questioning — often hides a cache misconfiguration.
  • Skipping the proxy.ts / middleware.ts matcher review — overmatching runs on every asset and tanks performance.
  • Not checking Server Actions for an auth gate at the top — they are publicly callable endpoints.
  • Forgetting that cookies() / headers() / params are async on Next.js 15+ — an un-awaited Promise reads as truthy and ships a silent bug.

How to push results further

  • Always start a Next.js review with the server/client boundary pass (prompt 1) — other findings cascade from there.
  • Paste the exact next version and your next.config.ts (so the model knows whether cacheComponents is on) with every prompt. The model’s answer is only as current as the version you hand it.
  • Demand file:line evidence and the exact import or directive that triggered the issue.
  • Run the cache audit per route, not globally — caching expectations differ by route type.
  • For Server Actions, require the reviewer to call out auth, validation, and invalidation explicitly.
  • Use the upgrade-compat prompt (14) every time you bump Next.js — it catches default changes (caching, async APIs, proxy.ts).
  • Track findings in a checklist and re-run after each fix PR — caching bugs love to come back.
  • Pair human review with next build output (which now flags uncached data outside Suspense) and a next start LCP comparison — prompts don’t catch real runtime regressions.

FAQ

  • Does this work for Pages Router too?: No — the model is different. Use generic React review prompts for Pages Router code.
  • How do I review a Next.js 16 codebase that still uses the old caching style?: That’s the most common upgrade gap. Run prompt 14 first to surface implicit fetch caching, then prompt 4 to map each fetch to use cache + cacheLife / cacheTag. Tell the model whether cacheComponents: true is set in next.config.ts.
  • updateTag vs revalidateTag — which should a Server Action use?: updateTag(tag) gives read-your-writes (the user sees their own edit immediately, blocks until fresh) and works only inside Server Actions. In a Route Handler or webhook, use revalidateTag(tag, profile) instead — it is stale-while-revalidate for content that tolerates a brief lag. As of Next.js 16 the single-argument revalidateTag(tag) is deprecated and needs a cacheLife profile (a built-in name like 'hours' / 'days' / 'max' or a custom one from next.config.ts).
  • How do I scope a Server Action review when the action calls many helpers?: Paste the action file plus the immediate helpers it calls. Don’t paste the whole repo — focus beats coverage.
  • Will the AI know about the latest Next.js version?: Only if you tell it. Specify the exact version in the prompt; for recent releases, paste the relevant changelog or upgrade-guide snippet. Models trail the framework by months.
  • Can I run all 15 in one prompt?: You can, but findings blur. Run boundary first, then caching, then everything else.
  • What about Edge runtime?: Add: “Some routes run on Edge — flag Node-only APIs in Edge-runtime files.” Note that in Next.js 16 the Node-runtime interceptor is proxy.ts; middleware.ts remains for Edge but is deprecated.

External references: the Next.js 16 release notes and the Caching with Cache Components guide are the canonical source for the use cache model; paste the relevant section into your prompt when reviewing recently upgraded code.

Tags: #Prompt #Coding #Next.js #Code review