app-router
Next.js App Router Patterns
Overview
The App Router is Next.js's file-system based router built on React Server Components. It uses a app/ directory structure where folders define routes and special files control UI behavior.
Core File Conventions
Route Files
Each route segment is defined by a folder. Special files within folders control behavior:
| File | Purpose |
|---|---|
page.tsx |
Unique UI for a route, makes route publicly accessible |
layout.tsx |
Shared UI wrapper, preserves state across navigations |
loading.tsx |
Loading UI using React Suspense |
error.tsx |
Error boundary for route segment |
not-found.tsx |
UI for 404 responses |
template.tsx |
Like layout but re-renders on navigation |
default.tsx |
Fallback for parallel routes |
Folder Conventions
| Pattern | Purpose | Example |
|---|---|---|
folder/ |
Route segment | app/blog/ → /blog |
[folder]/ |
Dynamic segment | app/blog/[slug]/ → /blog/:slug |
[...folder]/ |
Catch-all segment | app/docs/[...slug]/ → /docs/* |
[[...folder]]/ |
Optional catch-all | app/shop/[[...slug]]/ → /shop or /shop/* |
(folder)/ |
Route group (no URL) | app/(marketing)/about/ → /about |
@folder/ |
Named slot (parallel routes) | app/@modal/login/ |
_folder/ |
Private folder (excluded) | app/_components/ |
Creating Routes
Basic Route Structure
To create a new route, add a folder with page.tsx:
app/
├── page.tsx # / (home)
├── about/
│ └── page.tsx # /about
└── blog/
├── page.tsx # /blog
└── [slug]/
└── page.tsx # /blog/:slug
Page Component
A page is a Server Component by default:
// app/about/page.tsx
export default function AboutPage() {
return (
<main>
<h1>About Us</h1>
<p>Welcome to our company.</p>
</main>
)
}
Dynamic Routes
Access route parameters via the params prop:
// app/blog/[slug]/page.tsx
interface PageProps {
params: Promise<{ slug: string }>
}
export default async function BlogPost({ params }: PageProps) {
const { slug } = await params
const post = await getPost(slug)
return <article>{post.content}</article>
}
Layouts
Root Layout (Required)
Every app needs a root layout with <html> and <body>:
// app/layout.tsx
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}
Nested Layouts
Layouts wrap their children and preserve state:
// app/dashboard/layout.tsx
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<div className="flex">
<Sidebar />
<main className="flex-1">{children}</main>
</div>
)
}
Loading and Error States
Loading UI
Create instant loading states with Suspense:
// app/dashboard/loading.tsx
export default function Loading() {
return <div className="animate-pulse">Loading...</div>
}
Error Boundaries
Handle errors gracefully:
// app/dashboard/error.tsx
'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>
)
}
Route Groups
Organize routes without affecting URL structure:
app/
├── (marketing)/
│ ├── layout.tsx # Marketing layout
│ ├── about/page.tsx # /about
│ └── contact/page.tsx # /contact
└── (shop)/
├── layout.tsx # Shop layout
└── products/page.tsx # /products
Metadata
Static Metadata
// app/about/page.tsx
import { Metadata } from 'next'
export const metadata: Metadata = {
title: 'About Us',
description: 'Learn more about our company',
}
Dynamic Metadata
// app/blog/[slug]/page.tsx
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
const { slug } = await params
const post = await getPost(slug)
return { title: post.title }
}
Key Patterns
- Colocation: Keep components, tests, and styles near routes
- Private folders: Use
_folderfor non-route files - Route groups: Use
(folder)to organize without URL impact - Parallel routes: Use
@slotfor complex layouts - Intercepting routes: Use
(.)patterns for modals
Resources
For detailed patterns, see:
references/routing-conventions.md- Complete file conventionsreferences/layouts-templates.md- Layout composition patternsreferences/loading-error-states.md- Suspense and error handlingexamples/dynamic-routes.md- Dynamic routing examplesexamples/parallel-routes.md- Parallel and intercepting routes
More from davepoon/buildwithclaude
file-organizer
Intelligently organizes your files and folders across your computer by understanding context, finding duplicates, suggesting better structures, and automating cleanup tasks. Reduces cognitive load and keeps your digital workspace tidy without manual effort.
212xlsx
Comprehensive spreadsheet creation, editing, and analysis with support for formulas, formatting, data analysis, and visualization. When Claude needs to work with spreadsheets (.xlsx, .xlsm, .csv, .tsv, etc) for: (1) Creating new spreadsheets with formulas and formatting, (2) Reading or analyzing data, (3) Modify existing spreadsheets while preserving formulas, (4) Data analysis and visualization in spreadsheets, or (5) Recalculating formulas
187content-research-writer
Assists in writing high-quality content by conducting research, adding citations, improving hooks, iterating on outlines, and providing real-time feedback on each section. Transforms your writing process from solo effort to collaborative partnership.
141docx
Comprehensive document creation, editing, and analysis with support for tracked changes, comments, formatting preservation, and text extraction. When Claude needs to work with professional documents (.docx files) for: (1) Creating new documents, (2) Modifying or editing content, (3) Working with tracked changes, (4) Adding comments, or any other document tasks
122auth-patterns
This skill should be used when the user asks about "authentication in Next.js", "NextAuth", "Auth.js", "middleware auth", "protected routes", "session management", "JWT", "login flow", or needs guidance on implementing authentication and authorization in Next.js applications.
104server-actions
This skill should be used when the user asks about "Server Actions", "form handling in Next.js", "mutations", "useFormState", "useFormStatus", "revalidatePath", "revalidateTag", or needs guidance on data mutations and form submissions in Next.js App Router.
99