---
overlay: Next.js Specialization
parent_agent: Super Coder
description: "Next.js App Router, RSC, and full-stack patterns"
---

## NEXT.JS-SPECIFIC GUIDELINES

You are working in a **Next.js** codebase. Apply these principles with zero exceptions.

### App Router — The Default (Next.js 13+)
- Use the **App Router** (`app/` directory) — not Pages Router, unless the project explicitly uses it
- Understand the file conventions: `page.tsx`, `layout.tsx`, `loading.tsx`, `error.tsx`, `not-found.tsx`
- Use `route.ts` for API routes in the App Router
- Layouts persist across navigations — put shared UI (nav, sidebar) in layouts
- Use `template.tsx` only when you need re-mounting on navigation (rare)

### Server Components — Default Rendering
- **All components are Server Components by default** — only add `'use client'` when you NEED client interactivity
- Server Components can: fetch data directly, access backend, read fs, use async/await at component level
- Client Components need `'use client'` directive when using: hooks, event handlers, browser APIs, state
- **Minimize `'use client'`** — push it as far down the tree as possible
- Never add `'use client'` to a layout unless absolutely necessary — it makes all children client components

### Data Fetching
- Use `async` Server Components for data fetching — direct `await` in the component body
- Use **Server Actions** (`'use server'`) for mutations — form submissions, data writes
- Use `fetch()` in Server Components with Next.js caching: `fetch(url, { cache: 'force-cache' })` or `{ next: { revalidate: 3600 } }`
- Use `unstable_cache` or `cache()` from React for caching expensive operations
- Never use `getServerSideProps` / `getStaticProps` in App Router — those are Pages Router patterns

### Rendering Strategies
- **Static (SSG):** Default for pages without dynamic data. Use `generateStaticParams()` for dynamic routes
- **Dynamic (SSR):** Add `export const dynamic = 'force-dynamic'` or use `cookies()`, `headers()`, `searchParams`
- **ISR:** Use `{ next: { revalidate: N } }` in fetch or `export const revalidate = N` in page/layout
- Choose the least dynamic option that works — static > ISR > SSR

### Routing & Navigation
- Use `next/link` for client-side navigation — never `<a>` for internal links
- Use `next/navigation` hooks: `useRouter()`, `usePathname()`, `useSearchParams()` — not `next/router`
- Use dynamic routes: `app/users/[id]/page.tsx` — access via `params` prop
- Use route groups `(group)` for organizing without affecting URL structure
- Use parallel routes `@slot` and intercepting routes `(.)` for advanced patterns

### Image & Asset Optimization
- Use `next/image` for all images — automatic optimization, lazy loading, responsive sizing
- Use `next/font` for fonts — automatic self-hosting, no layout shift
- Set `width` and `height` or use `fill` with a sized container — prevent layout shift
- Use `priority` prop for above-the-fold images (LCP optimization)

### Middleware
- Use `middleware.ts` at the project root for: auth guards, redirects, geolocation, A/B testing
- Keep middleware fast — it runs on every request. No heavy computation or database queries
- Use `matcher` config to limit which routes trigger middleware

### Environment Variables
- `NEXT_PUBLIC_*` — exposed to the browser (public). Use for: API URLs, feature flags
- Variables without prefix — server-only. Use for: secrets, database URLs, API keys
- Access in Server Components directly from `process.env`
- Access in Client Components only via `process.env.NEXT_PUBLIC_*`

### Naming Conventions
- File-based routing: `page.tsx`, `layout.tsx`, `loading.tsx`, `error.tsx`
- Components: `PascalCase` — `UserProfile.tsx`
- Server Actions: `camelCase` with descriptive names — `createUser`, `deletePost`
- API routes: `route.ts` with exported HTTP method handlers: `GET`, `POST`, `PUT`, `DELETE`

### Testing Considerations
- Separate server and client component logic for testability
- Use server actions as the boundary for testing mutations
- Mock `next/navigation` hooks in component tests
