---
name: nextjs-app-router-patterns
description: Best practices and patterns for building applications with Next.js App Router (v13+).
---

# Next.js App Router Patterns

## Core Principles

### Server-First by Default

- **Use Server Components** for everything possible (data fetching, layout, static content).
- **Use Client Components** (`"use client"`) only when interactivity (hooks, event listeners) is needed.
- **Pass Data Down**: Fetch data in Server Components and pass it as props to Client Components.
- **Composition**: Wrap Client Components around Server Components to avoid "rendering undefined" issues or waterfall de-opts.

### Routing & Layouts

- **File Structure**:
  - `page.tsx`: Route UI.
  - `layout.tsx`: Shared UI (wraps pages).
  - `loading.tsx`: Loading state (Suspense).
  - `error.tsx`: Error boundary.
  - `not-found.tsx`: 404 UI.
  - `template.tsx`: Layout that re-mounts on navigation.
- **Parallel Routes**: Use `@folder` for parallel UI (e.g. dashboards).
- **Intercepting Routes**: Use `(..)` to intercept navigation (e.g. modals).
- **Route Groups**: Use `(group)` to organize routes without affecting the URL path.

## Data Fetching Patterns

### Server Side

- **Direct Async/Await**: `const data = await fetch(...)` inside the component.
- **Request Memoization**: `fetch` is automatically memoized. For DB calls, use `React.cache`.
- **Data Caching**:
  - `fetch(url, { next: { revalidate: 3600 } })` for ISR.
  - `fetch(url, { cache: 'no-store' })` for SSR.
  - Use `unstable_cache` for caching DB results.

### Client Side

- Use **SWR** or **TanStack Query** for client-side fetching.
- Avoid `useEffect` for data fetching to prevent waterfalls.
- Prefetch data using `queryClient.prefetchQuery` in Server Components and hydrate on client.

## Server Actions

- Use **Server Actions** (`"use server"`) for mutations (form submissions, button clicks).
- Define actions in separate files (e.g. `actions.ts`) for better organization and security.
- Use `useFormState` (or `useActionState` in React 19) to handle loading/error states.

## Optimization

- **Images**: Use `next/image` for automatic resizing and format conversion.
- **Fonts**: Use `next/font` to eliminate layout shift (CLS).
- **Scripts**: Use `next/script` with `strategy="afterInteractive"`.
- **Streaming**: Use `<Suspense>` to stream parts of the UI (e.g. slow data fetches).

## Common Anti-Patterns to Avoid

1. **Fetching in Client Components without cache lib**: Leads to waterfalls.
2. **"use client" at top level layout**: Forces the entire tree to be client-side.
3. **Prop Drilling**: specialized `Context` should be used sparingly; prefer Composition.
4. **Large Barrel Files**: Avoid `index.ts` exporting everything; import directly to aid tree-shaking.
