Pages & Routing
Creating pages and navigating between routes
πΊοΈ Next.js Routing
Next.js uses file-based routing where folders and files in the app directory automatically become routes. No configuration needed - just create a file and it becomes a page!
app/
βββ page.js # Route: /
βββ about/
βββ page.js # Route: /about
Route Types
Static Routes
Fixed URL paths like /about or /contact
app/about/page.js
β /about
Dynamic Routes
Variable paths like /blog/[slug]
app/blog/[id]/page.js
β /blog/123
Nested Routes
Routes inside folders like /blog/posts
app/blog/posts/page.js
β /blog/posts
API Routes
Backend endpoints like /api/users
app/api/users/route.js
β /api/users
πΉ Creating Static Routes
Static routes have fixed URLs that don't change. Create them by adding folders with page.js files. Each folder name becomes part of the URL path automatically.
πΈ Home Page
// app/page.js
export default function HomePage() {
return (
<div>
<h1>Welcome Home</h1>
<p>This is the home page at /</p>
</div>
)
}
πΈ About Page
// app/about/page.js
export default function AboutPage() {
return (
<div>
<h1>About Us</h1>
<p>This page is at /about</p>
</div>
)
}
Output at /about:
About Us
This page is at /about
πΉ Dynamic Routes
Dynamic routes use square brackets to create flexible URLs that accept parameters. Perfect for blog posts, product pages, or any content with unique identifiers.
// app/blog/[id]/page.js
export default function BlogPost({ params }) {
return (
<div>
<h1>Blog Post #{params.id}</h1>
<p>You are viewing post {params.id}</p>
</div>
)
}
// Matches: /blog/1, /blog/2, /blog/hello, etc.
Output at /blog/123:
Blog Post #123
You are viewing post 123
πΉ Nested Routes
Organize related pages by nesting folders inside each other. This creates clean URL hierarchies and helps structure your application logically.
app/
βββ dashboard/
βββ page.js # /dashboard
βββ settings/
β βββ page.js # /dashboard/settings
βββ profile/
βββ page.js # /dashboard/profile
πΈ Dashboard Page
// app/dashboard/page.js
export default function Dashboard() {
return <h1>Dashboard Home</h1>
}
// app/dashboard/settings/page.js
export default function Settings() {
return <h1>Dashboard Settings</h1>
}
πΉ Route Groups
Use parentheses to organize routes without affecting the URL structure. This helps group related pages while keeping URLs clean and simple.
app/
βββ (marketing)/
β βββ about/page.js # /about (not /marketing/about)
β βββ contact/page.js # /contact
βββ (shop)/
βββ products/page.js # /products
βββ cart/page.js # /cart
Note: Folders in parentheses like (marketing) don't appear in the URL. They're just for organization!
πΉ Catch-All Routes
Catch-all routes match multiple URL segments at once, useful for flexible routing patterns like documentation sites or file browsers.
// app/docs/[...slug]/page.js
export default function Docs({ params }) {
return (
<div>
<h1>Documentation</h1>
<p>Path: {params.slug.join('/')}</p>
</div>
)
}
// Matches:
// /docs/getting-started
// /docs/api/reference
// /docs/guides/tutorial/basics
πΉ Loading States
Show loading UI while pages are being fetched. Next.js automatically displays loading.js content during navigation, improving user experience.
// app/dashboard/loading.js
export default function Loading() {
return (
<div>
<h2>Loading...</h2>
<p>Please wait</p>
</div>
)
}
πΉ Error Handling
Create custom error pages to handle problems gracefully. Error boundaries catch issues and display friendly messages instead of breaking your app.
// app/error.js
'use client'
export default function Error({ error, reset }) {
return (
<div>
<h2>Something went wrong!</h2>
<button onClick={() => reset()}>
Try again
</button>
</div>
)
}
πΉ Not Found Pages
Customize the 404 page that appears when users visit non-existent routes. Make it helpful by suggesting where they might want to go instead.
// app/not-found.js
export default function NotFound() {
return (
<div>
<h1>404 - Page Not Found</h1>
<p>The page you're looking for doesn't exist.</p>
</div>
)
}
Output:
404 - Page Not Found
The page you're looking for doesn't exist.