App Router Basics
The file-system routing model where folders define routes and special files define UI for each segment.
How The App Router Works
The App Router maps folders in the `app` directory to URL segments. A folder named `dashboard` creates the `/dashboard` route. The `page.tsx` file exports the UI for that segment; without it, the folder is a route group organizer but not a publicly accessible URL.
Special files — `layout.tsx`, `loading.tsx`, `error.tsx`, `not-found.tsx`, `route.ts` — attach behavior to segments. This convention replaces Pages Router files like `_app.tsx` and `getServerSideProps` with colocated route modules.
- Folders map to URL segments
- page.tsx required for public routes
- Special files attach segment behavior
app/
layout.tsx // root layout
page.tsx // /
blog/
page.tsx // /blog
[slug]/
page.tsx // /blog/:slugRoot Layout First
The root `app/layout.tsx` wraps every page. It must include `<html>` and `<body>` tags. Define global fonts, metadata defaults, providers, and shared chrome here.
Nested layouts add UI per section without remounting parent layout on navigation — navigating between `/dashboard/settings` and `/dashboard/analytics` keeps the dashboard layout mounted while swapping page content.
- Root layout includes html and body
- Nested layouts persist across child navigation
- Global providers belong in root layout
Route Groups and Private Folders
Parentheses folders like `(marketing)` organize routes without affecting the URL — `app/(marketing)/about/page.tsx` serves `/about`. Use groups to split layouts (marketing vs app shell) without nested URL paths.
Prefix folders with underscore (e.g., `_components`) or use colocation patterns to keep non-route files near routes. Only `page.tsx` and route handlers create public endpoints.
- (group) folders omit URL segment
- Split layouts without URL nesting
- Underscore prefixes for non-route folders
Server vs Client Default
Components in the App Router are Server Components by default — no JavaScript shipped for their logic unless they import client modules. Add `"use client"` only where interactivity, hooks, or browser APIs are required.
This default reduces client bundle size dramatically compared to Pages Router where pages were typically client-heavy. Plan client boundaries during route design, not as an afterthought.
- Server Components are the default
- "use client" only when needed
- Design client boundaries early
Migrating Mental Models
Replace `pages/index.tsx` with `app/page.tsx`. Replace `pages/api/*` with `app/**/route.ts` Route Handlers. Replace `getServerSideProps` with async Server Components that fetch directly.
Incremental adoption uses Next.js hybrid mode — both `pages` and `app` directories coexist during migration. New features should land in `app` exclusively.
- pages/ and app/ can coexist
- getServerSideProps → async Server Components
- New features in app/ directory