Buildwithclaude app-router
This skill should be used when the user asks to "create a Next.js route", "add a page", "set up layouts", "implement loading states", "add error boundaries", "organize routes", "create dynamic routes", or needs guidance on Next.js App Router file conventions and routing patterns.
git clone https://github.com/davepoon/buildwithclaude
T=$(mktemp -d) && git clone --depth=1 https://github.com/davepoon/buildwithclaude "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/nextjs-expert/skills/app-router" ~/.claude/skills/davepoon-buildwithclaude-app-router && rm -rf "$T"
plugins/nextjs-expert/skills/app-router/SKILL.mdNext.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 |
|---|---|
| Unique UI for a route, makes route publicly accessible |
| Shared UI wrapper, preserves state across navigations |
| Loading UI using React Suspense |
| Error boundary for route segment |
| UI for 404 responses |
| Like layout but re-renders on navigation |
| Fallback for parallel routes |
Folder Conventions
| Pattern | Purpose | Example |
|---|---|---|
| Route segment | → |
| Dynamic segment | → |
| Catch-all segment | → |
| Optional catch-all | → or |
| Route group (no URL) | → |
| Named slot (parallel routes) | |
| Private folder (excluded) | |
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
for non-route files_folder - Route groups: Use
to organize without URL impact(folder) - Parallel routes: Use
for complex layouts@slot - Intercepting routes: Use
patterns for modals(.)
Resources
For detailed patterns, see:
- Complete file conventionsreferences/routing-conventions.md
- Layout composition patternsreferences/layouts-templates.md
- Suspense and error handlingreferences/loading-error-states.md
- Dynamic routing examplesexamples/dynamic-routes.md
- Parallel and intercepting routesexamples/parallel-routes.md