Optimize Next.js App Router Development
Principles for Next.js App Router: Server/Client component choice, data fetching, routing, caching, and anti-patterns.
Why it matters
Implement best practices for Next.js App Router development to build performant, scalable, and maintainable web applications.
Outcomes
What it gets done
Differentiate Server and Client Components effectively.
Implement optimal data fetching and caching strategies.
Structure routes and API handlers according to conventions.
Enhance performance with image and bundle optimization.
Install
Add it to your toolbox
Run in your project directory:
curl -fsSL https://spark.entire.vc/get/ag-nextjs-best-practices | bash Overview
Next.js Best Practices
A principles reference for Next.js App Router: Server/Client component decisions, data fetching and caching strategy, routing conventions, and performance/metadata best practices. Use when building or reviewing Next.js App Router applications for correct Server/Client boundaries, caching, and routing structure.
What it does
Next.js Best Practices covers principles for App Router development across ten areas. Server versus Client Component choice follows a decision tree: needing useState/useEffect/event handlers means a Client Component ('use client'); direct data fetching with no interactivity stays a Server Component (the default); needing both means splitting into a Server parent with a Client child. Data fetching has three cache strategies - default (static, cached at build), time-based revalidation (ISR), and no-store (dynamic, every request) - matched to source: database reads as Server Component fetches, API calls as cached fetch, and user input as client state plus a server action.
When to use - and when NOT to
Use it for App Router routing conventions (page.tsx, layout.tsx, loading.tsx, error.tsx, not-found.tsx), route organization (route groups (name) to organize without affecting the URL, parallel routes @slot for multiple same-level pages, intercepting routes (.) for modal overlays), API route handlers (GET/POST/PUT-PATCH/DELETE, validated with Zod, returning proper status codes, preferring Edge runtime when possible), and Server Actions ('use server', for form submissions, data mutations, and revalidation triggers - validating all inputs and returning typed responses). A recommended project structure separates route groups from API routes and shared components:
app/
├── (marketing)/ # Route group
│ └── page.tsx
├── (dashboard)/
│ ├── layout.tsx # Dashboard layout
│ └── page.tsx
├── api/
│ └── [resource]/
│ └── route.ts
└── components/
└── ui/
Inputs and outputs
Performance principles: use the next/image component with priority set for above-the-fold images and a blur placeholder, dynamic imports for heavy components, and automatic route-based code splitting (checked with a bundle analyzer). Metadata is either static (fixed) or generated per-route via generateMetadata, with essential tags kept within length limits - title 50-60 characters, description 150-160 characters - plus Open Graph images and a canonical URL. Caching operates across three layers (request-level via fetch options, data-level via revalidate/tags, and full-route via route config), revalidated by time (revalidate: 60), on-demand (revalidatePath/revalidateTag), or disabled (no-store).
Integrations
Documented anti-patterns and their fixes: 'use client' everywhere should default to Server Components instead, fetching inside client components should move to the server, skipped loading/error states should use loading.tsx/error.tsx, and large client bundles should use dynamic imports.
Who it's for
Next.js developers building App Router applications who want a concise, opinionated reference for Server/Client component boundaries, data fetching and caching strategy, routing conventions, and performance discipline - Server Components as the default, Client Components added only when genuinely needed.
FAQ
Common questions
Discussion
Questions & comments · 0
Sign In Sign in to leave a comment.