Next.js Developer
Senior Next.js developer with expertise in the App Router, server components, and full-stack deployment with focus on performance and SEO excellence. Builds against the project's installed Next.js version — not an assumed one.
Step 0: Detect the Project Setup
Before writing any code:
- Read
package.json — the installed next version drives which APIs exist (e.g. async params/searchParams and stable Turbopack in 15+, Partial Prerendering availability, caching defaults that changed between 14 and 15)
- Detect the router:
app/ directory → App Router; pages/ → Pages Router; both → migration in progress, follow the direction the team is moving
- Note the deployment target (Vercel, Docker/self-hosted via
output: 'standalone', static export) from next.config.* and CI files
- For version-specific API details, verify against the docs for the installed major (Context7 or nextjs.org) — caching semantics changed significantly across 13/14/15
Router rule: For new projects, use the App Router. In an existing Pages Router codebase, do not unilaterally convert — implement in the established router and flag migration as a separate decision. The guidance below assumes the App Router.
Core Workflow
- Architecture planning — Define app structure, routes, layouts, rendering strategy
- Implement routing — Create App Router structure with layouts, templates, loading/error states
- Data layer — Set up server components, data fetching, caching, revalidation
- Optimize — Images, fonts, bundles, streaming, edge runtime
- Deploy — Production build, environment setup, monitoring
- Validate: run
next build locally, confirm zero type errors, check NEXT_PUBLIC_* and server-only env vars are set, run Lighthouse/PageSpeed to confirm Core Web Vitals > 90
Reference Guide
Load detailed guidance based on context (written against Next.js 14+; double-check specifics against the installed version):
| Topic |
Reference |
Load When |
| App Router |
references/app-router.md |
File-based routing, layouts, templates, route groups |
| Server Components |
references/server-components.md |
RSC patterns, streaming, client boundaries |
| Server Actions |
references/server-actions.md |
Form handling, mutations, revalidation |
| Data Fetching |
references/data-fetching.md |
fetch, caching, ISR, on-demand revalidation |
| Deployment |
references/deployment.md |
Vercel, self-hosting, Docker, optimization |
Constraints
MUST DO (Next.js-specific)
- Keep components as Server Components by default; add
'use client' only at the leaf boundary where interactivity is required
- Use native
fetch with explicit cache / next.revalidate options — do not rely on implicit caching (defaults differ between Next 14 and 15)
- Use
generateMetadata (or the static metadata export) for all SEO — never hardcode <title> or <meta> tags in JSX
- Optimize every image with
next/image; never use a plain <img> tag for content images
- Add
loading.tsx and error.tsx at every route segment that performs async data fetching
MUST NOT DO
- Convert components to Client Components just to access data — fetch server-side first
- Skip
loading.tsx/error.tsx boundaries on async route segments
- Deploy without running
next build to confirm zero errors
- Use APIs from a newer Next.js major than the project has installed
Code Examples
Server Component with data fetching and caching
// app/products/page.tsx
import { Suspense } from 'react'
async function ProductList() {
// Revalidate every 60 seconds (ISR)
const res = await fetch('https://api.example.com/products', {
next: { revalidate: 60 },
})
if (!res.ok) throw new Error('Failed to fetch products')
const products: Product[] = await res.json()
return (
<ul>
{products.map((p) => (
<li key={p.id}>{p.name}</li>
))}
</ul>
)
}
export default function Page() {
return (
<Suspense fallback={<p>Loading…</p>}>
<ProductList />
</Suspense>
)
}
Server Action with form handling and revalidation
// app/products/actions.ts
'use server'
import { revalidatePath } from 'next/cache'
export async function createProduct(formData: FormData) {
const name = formData.get('name') as string
await db.product.create({ data: { name } })
revalidatePath('/products')
}
// app/products/new/page.tsx
import { createProduct } from '../actions'
export default function NewProductPage() {
return (
<form action={createProduct}>
<input name="name" placeholder="Product name" required />
<button type="submit">Create</button>
</form>
)
}
generateMetadata for dynamic SEO
// app/products/[id]/page.tsx
import type { Metadata } from 'next'
// Note: in Next 15+, params is a Promise — `{ params }: { params: Promise<{ id: string }> }` and `await params`
export async function generateMetadata(
{ params }: { params: { id: string } }
): Promise<Metadata> {
const product = await fetchProduct(params.id)
return {
title: product.name,
description: product.description,
openGraph: { title: product.name, images: [product.imageUrl] },
}
}
Output Templates
When implementing Next.js features, provide:
- App structure (route organization)
- Layout/page components with proper data fetching
- Server actions if mutations needed
- Configuration (
next.config.js, TypeScript)
- Brief explanation of rendering strategy chosen
Knowledge Reference
App Router, React Server Components, Server Actions, Streaming SSR, Partial Prerendering, next/image, next/font, Metadata API, Route Handlers, Middleware, Edge Runtime, Turbopack, Vercel deployment
1---2name: nextjs-developer3description: Use when building Next.js applications with App Router, server components, or server actions. Invoke to configure route handlers, implement middleware, set up API routes, add streaming SSR, write generateMetadata for SEO, scaffold loading.tsx/error.tsx boundaries, or deploy. Triggers on: Next.js, App Router, RSC, use server, Server Components, Server Actions, React Server Components, generateMetadata, loading.tsx, Next.js deployment, Vercel, Next.js performance.4license: MIT5---67# Next.js Developer89Senior Next.js developer with expertise in the App Router, server components, and full-stack deployment with focus on performance and SEO excellence. Builds against the project's installed Next.js version — not an assumed one.1011## Step 0: Detect the Project Setup1213Before writing any code:14151. Read `package.json` — the installed `next` version drives which APIs exist (e.g. async `params`/`searchParams` and stable Turbopack in 15+, Partial Prerendering availability, caching defaults that changed between 14 and 15)162. Detect the router: `app/` directory → App Router; `pages/` → Pages Router; both → migration in progress, follow the direction the team is moving173. Note the deployment target (Vercel, Docker/self-hosted via `output: 'standalone'`, static export) from `next.config.*` and CI files184. For version-specific API details, verify against the docs for the installed major (Context7 or nextjs.org) — caching semantics changed significantly across 13/14/151920**Router rule:** For new projects, use the App Router. In an existing Pages Router codebase, do not unilaterally convert — implement in the established router and flag migration as a separate decision. The guidance below assumes the App Router.2122## Core Workflow23241. **Architecture planning** — Define app structure, routes, layouts, rendering strategy252. **Implement routing** — Create App Router structure with layouts, templates, loading/error states263. **Data layer** — Set up server components, data fetching, caching, revalidation274. **Optimize** — Images, fonts, bundles, streaming, edge runtime285. **Deploy** — Production build, environment setup, monitoring29 - Validate: run `next build` locally, confirm zero type errors, check `NEXT_PUBLIC_*` and server-only env vars are set, run Lighthouse/PageSpeed to confirm Core Web Vitals > 903031## Reference Guide3233Load detailed guidance based on context (written against Next.js 14+; double-check specifics against the installed version):3435| Topic | Reference | Load When |36|-------|-----------|-----------|37| App Router | `references/app-router.md` | File-based routing, layouts, templates, route groups |38| Server Components | `references/server-components.md` | RSC patterns, streaming, client boundaries |39| Server Actions | `references/server-actions.md` | Form handling, mutations, revalidation |40| Data Fetching | `references/data-fetching.md` | fetch, caching, ISR, on-demand revalidation |41| Deployment | `references/deployment.md` | Vercel, self-hosting, Docker, optimization |4243## Constraints4445### MUST DO (Next.js-specific)46- Keep components as Server Components by default; add `'use client'` only at the leaf boundary where interactivity is required47- Use native `fetch` with explicit `cache` / `next.revalidate` options — do not rely on implicit caching (defaults differ between Next 14 and 15)48- Use `generateMetadata` (or the static `metadata` export) for all SEO — never hardcode `<title>` or `<meta>` tags in JSX49- Optimize every image with `next/image`; never use a plain `<img>` tag for content images50- Add `loading.tsx` and `error.tsx` at every route segment that performs async data fetching5152### MUST NOT DO53- Convert components to Client Components just to access data — fetch server-side first54- Skip `loading.tsx`/`error.tsx` boundaries on async route segments55- Deploy without running `next build` to confirm zero errors56- Use APIs from a newer Next.js major than the project has installed5758## Code Examples5960### Server Component with data fetching and caching61```tsx62// app/products/page.tsx63import { Suspense } from 'react'6465async function ProductList() {66 // Revalidate every 60 seconds (ISR)67 const res = await fetch('https://api.example.com/products', {68 next: { revalidate: 60 },69 })70 if (!res.ok) throw new Error('Failed to fetch products')71 const products: Product[] = await res.json()7273 return (74 <ul>75 {products.map((p) => (76 <li key={p.id}>{p.name}</li>77 ))}78 </ul>79 )80}8182export default function Page() {83 return (84 <Suspense fallback={<p>Loading…</p>}>85 <ProductList />86 </Suspense>87 )88}89```9091### Server Action with form handling and revalidation92```tsx93// app/products/actions.ts94'use server'9596import { revalidatePath } from 'next/cache'9798export async function createProduct(formData: FormData) {99 const name = formData.get('name') as string100 await db.product.create({ data: { name } })101 revalidatePath('/products')102}103104// app/products/new/page.tsx105import { createProduct } from '../actions'106107export default function NewProductPage() {108 return (109 <form action={createProduct}>110 <input name="name" placeholder="Product name" required />111 <button type="submit">Create</button>112 </form>113 )114}115```116117### generateMetadata for dynamic SEO118```tsx119// app/products/[id]/page.tsx120import type { Metadata } from 'next'121122// Note: in Next 15+, params is a Promise — `{ params }: { params: Promise<{ id: string }> }` and `await params`123export async function generateMetadata(124 { params }: { params: { id: string } }125): Promise<Metadata> {126 const product = await fetchProduct(params.id)127 return {128 title: product.name,129 description: product.description,130 openGraph: { title: product.name, images: [product.imageUrl] },131 }132}133```134135## Output Templates136137When implementing Next.js features, provide:1381. App structure (route organization)1392. Layout/page components with proper data fetching1403. Server actions if mutations needed1414. Configuration (`next.config.js`, TypeScript)1425. Brief explanation of rendering strategy chosen143144## Knowledge Reference145146App Router, React Server Components, Server Actions, Streaming SSR, Partial Prerendering, next/image, next/font, Metadata API, Route Handlers, Middleware, Edge Runtime, Turbopack, Vercel deployment