Next.js App Router
Production guidance for Next.js 16 App Router applications. Server-first: keep rendering, data access, and secrets on the server; add 'use client' only for interactivity.
Architecture Overview
Request → proxy.ts → Route (layout/page) → Server Components → DB/API
│ │
│ ▼
│ RSC Payload + HTML
│ │
▼ ▼
Route Handlers Streaming + Suspense
│
▼
Client Components (hydrate)
Quick Reference
| Need help with... |
Resource |
| Server vs Client Components |
server-components.md |
Data fetching, Suspense, use() |
data-fetching.md |
| Cache Components, revalidation |
caching.md |
| Layouts, navigation, dynamic routes |
routing.md |
proxy.ts, auth gates |
proxy.md |
error.tsx, loading.tsx, notFound() |
error-handling.md |
| Metadata, App Router ownership |
metadata-and-seo.md |
next/image, next/font |
assets.md |
| Pages Router migration |
migration.md |
| Next.js 15 → 16 upgrade |
version-changes.md |
Decision Matrix: "What Do I Use?"
| Need |
Solution |
Resource |
| Read database / API |
Server Component |
server-components, data-fetching |
| User interaction / state |
Client Component |
server-components |
| Form mutation |
Server Action |
data-fetching |
| HTTP endpoint / webhook |
Route Handler |
data-fetching |
| Cache expensive data |
'use cache' + cacheLife |
caching |
| Invalidate after user edit |
updateTag() |
caching |
| Invalidate from webhook |
revalidateTag(tag, 'max') |
caching |
| Auth redirect before render |
proxy.ts |
proxy |
| Loading UI |
loading.tsx or <Suspense> |
error-handling, data-fetching |
| Uncaught error |
error.tsx |
error-handling |
| Missing resource |
notFound() |
error-handling |
| SEO metadata |
metadata / generateMetadata |
metadata-and-seo |
| Optimize images/fonts |
next/image, next/font |
assets |
Component Decision Tree
Need useState, useEffect, onClick, or browser APIs?
├── YES → Client Component ('use client' at leaf)
└── NO → Server Component (default — no directive)
Need to mutate data?
├── HTML form / button → Server Action
└── External HTTP API → Route Handler
Data & Caching
| Scenario |
Pattern |
| Independent fetches |
Promise.all() in Server Component |
| Slow section |
<Suspense> + streaming |
| User-specific data |
'use cache: private' (or Suspense — no shared 'use cache') |
| Shared catalog |
'use cache' + cacheTag |
| After mutation |
updateTag() (actions) or revalidateTag (webhooks) |
Routing Conventions
| File |
Purpose |
page.tsx |
Route UI |
layout.tsx |
Shared chrome (persists on navigation) |
loading.tsx |
Suspense fallback |
error.tsx |
Error boundary (Client Component) |
not-found.tsx |
404 UI |
route.ts |
HTTP handler |
proxy.ts |
Pre-render interception (root or src/) |
Code Review Checklist
Components & Data
Mutations & Cache
Routing & UX
Security
Performance & SEO
Anti-Patterns
Resource Map
| Resource |
Owns |
| server-components.md |
RSC, Client boundaries, composition, context, server-only |
| data-fetching.md |
fetch, ORM, parallel fetch, Suspense, use(), Route Handlers |
| caching.md |
'use cache', cacheLife, cacheTag, revalidation, PPR |
| routing.md |
Layouts, pages, parallel/intercepting routes, Link |
| proxy.md |
proxy.ts, matcher, redirects, auth gates |
| error-handling.md |
loading, error, not-found boundaries |
| metadata-and-seo.md |
Metadata API ownership; SEO depth → seo skill |
| assets.md |
next/image, next/font |
| migration.md |
Pages Router → App Router |
| version-changes.md |
Next.js 15 → 16 breaking changes |
References
Verified against Next.js 16 App Router documentation.
Last verified: July 2026
1---2name: nextjs-app-router3description: Use when building or reviewing Next.js App Router applications. Covers Server vs Client Components, data fetching, Server Functions, Route Handlers, Cache Components, revalidation, routing, metadata, proxy.ts, error handling, streaming, and migration from the Pages Router. Verified against the official Next.js 16 App Router documentation.4---56# Next.js App Router78Production guidance for Next.js 16 App Router applications. **Server-first:** keep rendering, data access, and secrets on the server; add `'use client'` only for interactivity.910## Architecture Overview1112```13Request → proxy.ts → Route (layout/page) → Server Components → DB/API14 │ │15 │ ▼16 │ RSC Payload + HTML17 │ │18 ▼ ▼19 Route Handlers Streaming + Suspense20 │21 ▼22 Client Components (hydrate)23```2425## Quick Reference2627| Need help with... | Resource |28|-------------------|----------|29| Server vs Client Components | [server-components.md](resources/server-components.md) |30| Data fetching, Suspense, `use()` | [data-fetching.md](resources/data-fetching.md) |31| Cache Components, revalidation | [caching.md](resources/caching.md) |32| Layouts, navigation, dynamic routes | [routing.md](resources/routing.md) |33| `proxy.ts`, auth gates | [proxy.md](resources/proxy.md) |34| `error.tsx`, `loading.tsx`, `notFound()` | [error-handling.md](resources/error-handling.md) |35| Metadata, App Router ownership | [metadata-and-seo.md](resources/metadata-and-seo.md) |36| `next/image`, `next/font` | [assets.md](resources/assets.md) |37| Pages Router migration | [migration.md](resources/migration.md) |38| Next.js 15 → 16 upgrade | [version-changes.md](resources/version-changes.md) |3940## Decision Matrix: "What Do I Use?"4142| Need | Solution | Resource |43|------|----------|----------|44| Read database / API | Server Component | server-components, data-fetching |45| User interaction / state | Client Component | server-components |46| Form mutation | Server Action | data-fetching |47| HTTP endpoint / webhook | Route Handler | data-fetching |48| Cache expensive data | `'use cache'` + `cacheLife` | caching |49| Invalidate after user edit | `updateTag()` | caching |50| Invalidate from webhook | `revalidateTag(tag, 'max')` | caching |51| Auth redirect before render | `proxy.ts` | proxy |52| Loading UI | `loading.tsx` or `<Suspense>` | error-handling, data-fetching |53| Uncaught error | `error.tsx` | error-handling |54| Missing resource | `notFound()` | error-handling |55| SEO metadata | `metadata` / `generateMetadata` | metadata-and-seo |56| Optimize images/fonts | `next/image`, `next/font` | assets |5758## Component Decision Tree5960```61Need useState, useEffect, onClick, or browser APIs?62├── YES → Client Component ('use client' at leaf)63└── NO → Server Component (default — no directive)6465Need to mutate data?66├── HTML form / button → Server Action67└── External HTTP API → Route Handler68```6970## Data & Caching7172| Scenario | Pattern |73|----------|---------|74| Independent fetches | `Promise.all()` in Server Component |75| Slow section | `<Suspense>` + streaming |76| User-specific data | `'use cache: private'` (or Suspense — no shared `'use cache'`) |77| Shared catalog | `'use cache'` + `cacheTag` |78| After mutation | `updateTag()` (actions) or `revalidateTag` (webhooks) |7980## Routing Conventions8182| File | Purpose |83|------|---------|84| `page.tsx` | Route UI |85| `layout.tsx` | Shared chrome (persists on navigation) |86| `loading.tsx` | Suspense fallback |87| `error.tsx` | Error boundary (Client Component) |88| `not-found.tsx` | 404 UI |89| `route.ts` | HTTP handler |90| `proxy.ts` | Pre-render interception (root or `src/`) |9192## Code Review Checklist9394### Components & Data9596- [ ] Server Components by default; `'use client'` only at leaves97- [ ] Data fetched in Server Components, not via client `useEffect`98- [ ] Parallel fetching with `Promise.all()` where independent99- [ ] `params` / `searchParams` / `cookies()` / `headers()` awaited100- [ ] No secrets or DB clients in Client Components101102### Mutations & Cache103104- [ ] Server Actions authenticate and authorize105- [ ] `updateTag` or `revalidateTag` after mutations106- [ ] No `cookies()` inside shared `'use cache'` scopes (use `'use cache: private'` for per-user)107108### Routing & UX109110- [ ] Nested layouts; no duplicated page wrappers111- [ ] `loading.tsx` / `error.tsx` on slow or critical routes112- [ ] `notFound()` for missing resources113114### Security115116- [ ] `proxy.ts` gates auth; Server Actions re-verify117- [ ] Input validated in Server Actions and Route Handlers118119### Performance & SEO120121- [ ] `next/image` and `next/font` used122- [ ] Metadata on every public page123- [ ] Suspense for slow streaming sections124125## Anti-Patterns126127- [ ] `'use client'` on entire pages or layouts128- [ ] Client Component fetching data the server could fetch129- [ ] Route Handlers for internal reads (use Server Components)130- [ ] Sequential awaits for independent requests131- [ ] `middleware.ts` instead of `proxy.ts` (Next.js 16)132- [ ] Sync `params` or `cookies()` (removed)133- [ ] `revalidateTag(tag)` without second argument134- [ ] Auth only in proxy — not in Server Actions135136## Resource Map137138| Resource | Owns |139|----------|------|140| [server-components.md](resources/server-components.md) | RSC, Client boundaries, composition, context, server-only |141| [data-fetching.md](resources/data-fetching.md) | fetch, ORM, parallel fetch, Suspense, `use()`, Route Handlers |142| [caching.md](resources/caching.md) | `'use cache'`, cacheLife, cacheTag, revalidation, PPR |143| [routing.md](resources/routing.md) | Layouts, pages, parallel/intercepting routes, Link |144| [proxy.md](resources/proxy.md) | proxy.ts, matcher, redirects, auth gates |145| [error-handling.md](resources/error-handling.md) | loading, error, not-found boundaries |146| [metadata-and-seo.md](resources/metadata-and-seo.md) | Metadata API ownership; SEO depth → seo skill |147| [assets.md](resources/assets.md) | next/image, next/font |148| [migration.md](resources/migration.md) | Pages Router → App Router |149| [version-changes.md](resources/version-changes.md) | Next.js 15 → 16 breaking changes |150151## References152153Verified against [Next.js 16 App Router documentation](https://nextjs.org/docs/app).154155- [Project Structure](https://nextjs.org/docs/app/getting-started/project-structure)156- [Server and Client Components](https://nextjs.org/docs/app/getting-started/server-and-client-components)157- [Fetching Data](https://nextjs.org/docs/app/getting-started/fetching-data)158- [Caching](https://nextjs.org/docs/app/getting-started/caching)159- [Route Handlers](https://nextjs.org/docs/app/api-reference/file-conventions/route)160- [Proxy](https://nextjs.org/docs/app/api-reference/file-conventions/proxy)161- [Upgrading to Version 16](https://nextjs.org/docs/app/guides/upgrading/version-16)162163**Last verified:** July 2026