Next.js App Router prompt
Rules that make your coding agent write Next.js 16 the way it works today: Server Components first, Cache Components, async params, proxy.ts and Server Functions.
What it makes your agent good at
Agents trained on Next.js 13 to 15 still write middleware.ts, read params synchronously, add use client to whole pages and fetch their own API routes. This prompt points them at the docs that ship with your Next.js version and gives them the current model: Server Components by default, explicit caching, Server Functions for writes.
- Server Components by defaultuse client only on the interactive leaf; data read in Server Components, never through the app's own API routes.
- Cache Components, explicitlyuse cache with cacheLife and cacheTag for shared reads, Suspense around every request-time read, so pages prerender a static shell.
- Async request APIsparams, searchParams, cookies() and headers() awaited, typed with the generated PageProps and LayoutProps helpers.
- Writes that refresh the right dataValidated, authorized Server Functions that return errors as values, then updateTag, revalidateTag with a profile, or refresh.
- Next.js 16, not 13proxy.ts instead of middleware.ts, catchError and retry for errors, no Pages Router APIs or removed config.
- Checks its own workThe docs in node_modules/next/dist/docs and the dev server's MCP endpoint before guessing an API.
The Next.js App Router rules
90 lines, current to Next.js 16.4 and React 19.3. Last reviewed October 23, 2026. Plain Markdown, no front matter: each agent's is below.
nextjs-app-router.md
# Next.js App Router
You are working in a Next.js 16 App Router project with React 19 and TypeScript. Write code for the version in `package.json`, not the one in your training data: much of what you remember from Next.js 13 to 15 has changed.
## Before you write code
Read the version-matched docs in `node_modules/next/dist/docs/` (Next.js 16.2 and later ship them) before using an API you are not sure of. `01-app/03-api-reference/` holds the exact signatures; heed deprecation notes.
Check `next.config.ts` for `cacheComponents`, `partialPrefetching` and `typedRoutes`: they change how pages render, cache and type their links.
With `next dev` running, its MCP endpoint (`/_next/mcp`) reports compilation issues and errors per route. Prefer it to a full `next build` while you iterate.
## Project shape
Routes live in `app/` (or `src/app/`). Only `page.tsx` and `route.ts` are public; colocate private files in `_folders`, group without changing the URL with `(groups)`.
One `proxy.ts` at the root replaces `middleware.ts` (renamed in Next.js 16). Export `function proxy(request: NextRequest)` and a `config.matcher`. It runs on Node.js; use it for redirects, rewrites and headers, never for slow data fetching or as your only auth check.
Server-only modules (database, secrets, the session) start with `import "server-only"`. Only that data access layer reads `process.env` secrets.
Type page and layout props with the generated global helpers: `PageProps<"/blog/[slug]">`, `LayoutProps<"/dashboard">`, `RouteContext<"/api/items/[id]">`. They come from `next typegen`, `next dev` or `next build`.
## Server and Client Components
Components are Server Components by default. Add `"use client"` only to the leaf that needs state, effects, event handlers or browser APIs, never to a page or layout just to make an error go away.
Pass Server Components into Client Components as `children` or props instead of importing them there.
Props crossing to the client must be serializable: no functions (except Server Functions), class instances or Dates you rely on as objects.
Context providers are Client Components rendered as deep as possible, wrapping `{children}`.
Read data in Server Components: `await` a query or `fetch` directly in the component. No `useEffect` fetching, no API route the same app then calls from its own server.
Wrap shared reads in React's `cache()` so a layout and a page asking for the same user hit the database once.
## Request APIs are async
`params`, `searchParams`, `cookies()`, `headers()` and `draftMode()` return promises. Always `await` them in Server Components (or read them with `use()` in a Client Component).
export default async function Page(props: PageProps<"/blog/[slug]">) {
const { slug } = await props.params;
const post = await getPost(slug);
if (!post) notFound();
return <Article post={post} />;
}
## Caching with Cache Components
When `cacheComponents: true` is set (the default for new apps), nothing is cached unless you say so, and every page is prerendered into a static shell:
Mark cached work with the `"use cache"` directive at the top of an async function, component or page, and pair it with `cacheLife("hours" | "days" | "max" | …)` from `next/cache`. Arguments and captured values become the cache key.
Tag what a mutation will invalidate: ``cacheTag("posts", `post-${id}`)``.
Uncached reads (`fetch` without cache, the database, `cookies()`, `headers()`, `searchParams`) must sit inside a `<Suspense>` boundary with a real fallback; otherwise the dev overlay reports a blocking route. The fallback ships in the static shell and the content streams in.
Read request data outside the cached scope and pass the value in as an argument. Use `"use cache: private"` only for results that must read cookies or headers themselves, and `"use cache: remote"` for a durable shared cache.
Before reading `new Date()`, `Math.random()` or `crypto.randomUUID()` in a Server Component, either cache it or `await io()` (from `next/cache`) inside a Suspense boundary.
Do not use `export const dynamic`, `revalidate` or `fetchCache` segment options, `unstable_cache` or `unstable_noStore` in a Cache Components app: they belong to the previous model. If `cacheComponents` is off, follow the previous model's docs instead and do not mix the two.
## Mutations: Server Functions
Write mutations as Server Functions in a `"use server"` file (`app/actions.ts`) or inline in a Server Component. They are public HTTP endpoints: validate every input with a schema (Zod), check the session and authorize the user inside each one.
Call them from a `<form action={…}>` first, so forms work before JavaScript loads; use `useActionState` for pending state and returned errors, `useFormStatus` in a submit button, `useOptimistic` for instant feedback.
Return expected errors as values (`{ ok: false, errors }`); throw only for bugs.
After a write: `updateTag(tag)` when the user must see their own change at once (Server Functions only), `revalidateTag(tag, "max")` for stale-while-revalidate (the profile argument is required since Next.js 16), `revalidatePath` for a whole route, `refresh()` to refresh the client router without invalidating data, `redirect()` last, outside `try`/`catch`.
Route Handlers (`app/api/**/route.ts`) are for webhooks, streaming responses and clients outside your app, not for your own pages' data.
## Routing and navigation
Use `<Link>` for internal navigation and `next/navigation` (`useRouter`, `usePathname`, `useSearchParams`) in Client Components. `useSearchParams` needs a `<Suspense>` boundary above it.
Each segment can have `loading.tsx`, `error.tsx` (a Client Component receiving `error` and `retry`) and `not-found.tsx`. Call `notFound()` and `redirect()` from Server Components and Server Functions (`forbidden()` and `unauthorized()` need `experimental.authInterrupts`).
For an error boundary around one component rather than a route, use `catchError` from `next/error` instead of writing a class boundary.
Parallel route slots need a `default.tsx`.
Prerender known dynamic segments with `generateStaticParams`.
## Metadata and assets
Export `metadata` or `generateMetadata` from layouts and pages; set `metadataBase` once in the root layout. Use `opengraph-image.tsx`, `icon.tsx`, `sitemap.ts` and `robots.ts` file conventions instead of hand-written tags.
Use `next/image` with `width` and `height` (or `fill` and `sizes`) and remote patterns in `images.remotePatterns` (`images.domains` is deprecated); use `next/font` for fonts, applied once on `<html>`.
Load third-party scripts with `next/script`, never a raw `<script>` in a component.
## Config and tooling
Turbopack is the default for `next dev` and `next build`; its options live under `turbopack` in `next.config.ts`. Do not add a webpack config unless the project already has one.
`next lint` was removed: run ESLint or Biome directly as the project's scripts do.
Environment variables exposed to the browser start with `NEXT_PUBLIC_` and are inlined at build time; everything else stays on the server.
## Do not
Do not write `getServerSideProps`, `getStaticProps`, `next/router` or `pages/` APIs in an App Router project.
Do not read `params` or `searchParams` synchronously, or call `revalidateTag` with one argument.
Do not fetch your own Route Handlers from Server Components, or pass secrets and whole database rows to Client Components.
Do not add `"use client"` to a layout, put `async` on a Client Component, or call `redirect()` inside `try`.
## Before you finish
Run the type checker (`tsc --noEmit` or the project's typecheck script) and the linter, and fix what they report.
Check the dev overlay or `/_next/mcp` for blocking-route and hydration issues on every page you touched.
Say which routes are prerendered, cached or streamed when you change caching, so the reviewer knows what to test.
7,970 characters, 1,191 words. Under Windsurf's 12,000-character limit for a rule, as every prompt here is.
Use it in your agent
The same rules, where your agent reads them. Each file has the front matter its agent needs, set to apply on every request.
Claude Code
A rule it loads every session
- Save it as
.claude/rules/nextjs-app-router.mdin your project, front matter included, or run the install command. - Claude Code loads every file in
.claude/ruleswith yourCLAUDE.mdwhen a session starts. - Prefer one file? Paste it into
CLAUDE.mdunder its own heading instead.
.claude/rules/nextjs-app-router.md
# Next.js App RouterYou are working in a Next.js 16 App Router project with React 19 and TypeScript. Write code for the version in `package.json`, not the one in your training data: much of what you remember from Next.js 13 to 15 has changed.## Before you write code- Read the version-matched docs in `node_modules/next/dist/docs/` (Next.js 16.2 and later ship them) before using an API you are not sure of. `01-app/03-api-reference/` holds the exact signatures; heed deprecation notes.- Check `next.config.ts` for `cacheComponents`, `partialPrefetching` and `typedRoutes`: they change how pages render, cache and type their links.- With `next dev` running, its MCP endpoint (`/_next/mcp`) reports compilation issues and errors per route. Prefer it to a full `next build` while you iterate.## Project shape…
Or let the shadcn CLI write this file: sign in (free) for your command.
Cursor
A project rule with front matter
- Save it as
.cursor/rules/nextjs-app-router.mdc, front matter included, or run the install command. alwaysApply: trueadds it to every Agent request in this project.- Check it under Cursor Settings, Rules, then commit the folder for your team.
.cursor/rules/nextjs-app-router.mdc
---description: "Next.js 16 App Router conventions: Server and Client Components, caching, Server Functions, routing files and proxy.ts."alwaysApply: true---# Next.js App RouterYou are working in a Next.js 16 App Router project with React 19 and TypeScript. Write code for the version in `package.json`, not the one in your training data: much of what you remember from Next.js 13 to 15 has changed.## Before you write code- Read the version-matched docs in `node_modules/next/dist/docs/` (Next.js 16.2 and later ship them) before using an API you are not sure of. `01-app/03-api-reference/` holds the exact signatures; heed deprecation notes.- Check `next.config.ts` for `cacheComponents`, `partialPrefetching` and `typedRoutes`: they change how pages render, cache and type their links.- With `next dev` running, its MCP endpoint (`/_next/mcp`) reports compilation issues and errors per route. Prefer it to a full `next build` while you iterate.## Project shape…
Or let the shadcn CLI write this file: sign in (free) for your command.
Windsurf
A workspace rule for Cascade
- Save it as
.windsurf/rules/nextjs-app-router.md, or run the install command. trigger: always_onapplies it to every Cascade request in this workspace.- Windsurf reads up to 12,000 characters per rule; this one is 7,970.
.windsurf/rules/nextjs-app-router.md
---trigger: always_on---# Next.js App RouterYou are working in a Next.js 16 App Router project with React 19 and TypeScript. Write code for the version in `package.json`, not the one in your training data: much of what you remember from Next.js 13 to 15 has changed.## Before you write code- Read the version-matched docs in `node_modules/next/dist/docs/` (Next.js 16.2 and later ship them) before using an API you are not sure of. `01-app/03-api-reference/` holds the exact signatures; heed deprecation notes.- Check `next.config.ts` for `cacheComponents`, `partialPrefetching` and `typedRoutes`: they change how pages render, cache and type their links.- With `next dev` running, its MCP endpoint (`/_next/mcp`) reports compilation issues and errors per route. Prefer it to a full `next build` while you iterate.## Project shape…
Or let the shadcn CLI write this file: sign in (free) for your command.
GitHub Copilot
Instructions for the repository
- Save it as
.github/instructions/nextjs-app-router.instructions.md, or run the install command. applyTo: "**"applies it to every request in this repository.- Or paste it into
.github/copilot-instructions.md, which Copilot reads for every request.
.github/instructions/nextjs-app-router.instructions.md
---description: "Next.js 16 App Router conventions: Server and Client Components, caching, Server Functions, routing files and proxy.ts."applyTo: "**"---# Next.js App RouterYou are working in a Next.js 16 App Router project with React 19 and TypeScript. Write code for the version in `package.json`, not the one in your training data: much of what you remember from Next.js 13 to 15 has changed.## Before you write code- Read the version-matched docs in `node_modules/next/dist/docs/` (Next.js 16.2 and later ship them) before using an API you are not sure of. `01-app/03-api-reference/` holds the exact signatures; heed deprecation notes.- Check `next.config.ts` for `cacheComponents`, `partialPrefetching` and `typedRoutes`: they change how pages render, cache and type their links.- With `next dev` running, its MCP endpoint (`/_next/mcp`) reports compilation issues and errors per route. Prefer it to a full `next build` while you iterate.## Project shape…
Or let the shadcn CLI write this file: sign in (free) for your command.
Codex & AGENTS.md
The file most agents read
- Paste it into
AGENTS.mdat your project's root, under its own heading. - Codex reads
AGENTS.mdbefore it starts work, and so do Cursor, Zed, Jules, Amp and Copilot's coding agent. - A folder can have its own
AGENTS.md: the one closest to the file being edited wins.
AGENTS.md
## Next.js App RouterYou are working in a Next.js 16 App Router project with React 19 and TypeScript. Write code for the version in `package.json`, not the one in your training data: much of what you remember from Next.js 13 to 15 has changed.### Before you write code- Read the version-matched docs in `node_modules/next/dist/docs/` (Next.js 16.2 and later ship them) before using an API you are not sure of. `01-app/03-api-reference/` holds the exact signatures; heed deprecation notes.- Check `next.config.ts` for `cacheComponents`, `partialPrefetching` and `typedRoutes`: they change how pages render, cache and type their links.- With `next dev` running, its MCP endpoint (`/_next/mcp`) reports compilation issues and errors per route. Prefer it to a full `next build` while you iterate.### Project shape…
AGENTS.md is shared with your own instructions, so paste the rules in: the copy sets their headings a level down.
Rules teach it. The MCP equips it. With Pro, your agent installs every component, block and icon it needs, from a prompt.
Get ProMore prompts
Prompts that pair with this one. Each is short enough to sit beside the others.
Pricing
Give your agent the parts, with Pro
The prompts are free. Every Pro plan adds the MCP server, so your agent installs the components, blocks and icons it writes code around.
4.9/5 out of 5 · 150+ reviewsfrom 150+ founders and developers.
- Secure checkout via Stripe
- Code lives in your repo
- Keep what you've shipped if you cancel
- License terms
Next.js App Router prompt FAQ
What the Next.js App Router prompt covers and how to use it in your agent.
Does the Next.js App Router prompt cover Cache Components?
When does the agent use updateTag instead of revalidateTag?
Why does the prompt insist on Suspense around cookies and headers?
Why does my agent write proxy.ts instead of middleware.ts?
What changed with params and searchParams?
How does the prompt keep up with Next.js releases?
Can I use it on a Next.js 15 project?
What does the Next.js App Router prompt cover?
Should I combine it with the other Next.js prompts?
How do I add the Next.js App Router prompt to Claude Code?
How do I use the Next.js App Router prompt as a Cursor rule?
Does the Next.js App Router prompt fit in a Windsurf rule?
Can GitHub Copilot and Codex use the Next.js App Router prompt?
Can I edit the Next.js App Router prompt for my project?
4.9 out of 5 from 150+ developers
Rules teach it. The MCP equips it.
Every component, block and icon, installed by your AI agent on your stack. The prompts stay free.
- Cancel anytime
- Keep what you've shipped