Overview
Next.js App Router uses a file-system routing model where specific filenames carry special meaning. Every route segment maps to a folder; every folder can have one or more of these special files.
Core File Conventions
app/
layout.tsx # Root layout (wraps all pages, persists across navigations)
page.tsx # Home route (/)
loading.tsx # Loading UI (automatic Suspense boundary)
error.tsx # Error boundary ("use client" required)
not-found.tsx # 404 page
(marketing)/ # Route group — no URL segment
about/page.tsx # /about
blog/page.tsx # /blog
dashboard/
layout.tsx # Nested layout (sidebar, chrome)
page.tsx # /dashboard
settings/
page.tsx # /dashboard/settings
api/
route.ts # API route handler
Layout rules:
- Root layout: HTML shell, global providers, fonts, analytics
- Nested layouts: sidebar nav, dashboard chrome, section headers
- Layouts receive
{children}and persist across child navigations — no re-render on route change - Use
template.tsx(not layout) when you need to re-mount on navigation (enter/exit animations)
Route Groups (folder)
Organize routes without affecting the URL path:
app/
(marketing)/
pricing/page.tsx # /pricing
about/page.tsx # /about
(app)/
dashboard/page.tsx # /dashboard
profile/page.tsx # /profile
Both groups share the same root but can have different layouts. Use this to separate marketing pages (full-width) from app pages (with sidebar).
Parallel Routes @folder
Render multiple pages simultaneously in the same layout:
app/
@modal/
login/page.tsx
@sidebar/
default.tsx # Required: fallback when no active route
layout.tsx # Receives { modal, sidebar, children }
page.tsx
Use for modals, split views, and dashboard panels that load independently.
Intercepting Routes (.)folder
Show a modal on client navigation, full page on direct URL:
app/
photos/
[id]/page.tsx # /photos/123 (full page, direct URL)
@modal/
(.)photos/[id]/page.tsx # Intercepts /photos/123 during navigation
This is how Instagram-style photo modals work — click opens modal, direct URL or refresh shows full page.
Loading States
// app/dashboard/loading.tsx
export default function Loading() {
return <DashboardSkeleton />;
}
Automatically wraps the page in a <Suspense> boundary. Shows while page.tsx data loads. Zero boilerplate.
Error Boundaries
// app/dashboard/error.tsx — MUST be "use client"
"use client";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return (
<div>
<h2>Something went wrong</h2>
<button onClick={() => reset()}>Try again</button>
</div>
);
}
Catches rendering errors in the segment and all children below it. Place at every major route level.
Turbopack (Next.js 16+)
Turbopack is the default bundler in Next.js 16. No flags needed — next dev uses it automatically. Do NOT add --turbopack (deprecated). To opt out: next dev --no-turbopack.
Cache lives at .next/cache/turbopack/ — add to .gitignore, cache in CI between runs.
Pre-Deploy Checklist
- App Router structure follows conventions (layout, page, loading, error)
- TypeScript strict mode enabled
- Core Web Vitals > 90 (LCP < 2.5s, CLS < 0.1, INP < 200ms)
- Error boundaries at every route segment
- Deployment pipeline tested (preview + production)