66 lines
2.7 KiB
Markdown
66 lines
2.7 KiB
Markdown
---
|
|
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.
|