Next.js App Router: server vs client boundaries
This page exists to answer: “where does this code run?” and “where should we put it?”
Default rule
- In App Router, files are Server Components by default.
- You only get client-side React features (state/effects/browser APIs) inside Client Components marked with
"use client".
Quick decision checklist
Use a Server Component when you:
- fetch data from internal services/databases
- need secrets (tokens, service credentials)
- want caching/streaming benefits
- render non-interactive UI
Use a Client Component when you need:
useState,useEffect, DOM events, browser APIs- highly interactive widgets (modals, complex forms, drag/drop)
The boundary pattern (recommended)
- Server Component fetches/loads data (often via tRPC server-side call pattern).
- Server Component renders a Client Component and passes plain serializable props.
Avoid these common mistakes
- Putting microservice calls in the browser (leaks network topology, can leak secrets, harder to secure).
- Adding
"use client"at the top of a big page “just to make it work” (kills server benefits and increases bundle size). - Duplicating state (keeping both “field value” and “isValid” as separate sources of truth).
Official sources
- Server Components / Client Components: https://nextjs.org/docs/app/building-your-application/rendering
- Data fetching: https://nextjs.org/docs/app/building-your-application/data-fetching
- Route handlers: https://nextjs.org/docs/app/building-your-application/routing/route-handlers
Exercises
content/exercises/03-nextjs/01-app-router-boundaries.mdx
Last updated on