File-Based Routing
In Next.js, the file system is your router. Every page.tsx file inside the app/ directory automatically becomes a route:
app/
├── page.tsx # → /
├── about/
│ └── page.tsx # → /about
├── blog/
│ ├── page.tsx # → /blog
│ └── [slug]/
│ └── page.tsx # → /blog/my-post (dynamic)No configuration needed. No router setup. Just create files.
Dynamic Routes
Wrap a folder name in square brackets to create a dynamic route:
// app/blog/[slug]/page.tsx
export default async function BlogPost({ params }) {
const { slug } = await params
return <h1>Post: {slug}</h1>
}Visiting /blog/hello-world renders this page with slug = "hello-world".
Layouts
Layouts wrap child routes and persist across navigation. They don't re-render when you navigate between sibling routes:
// app/blog/layout.tsx
export default function BlogLayout({ children }) {
return (
<div>
<nav>Blog Navigation</nav>
<main>{children}</main>
</div>
)
}This layout wraps both /blog and /blog/[slug].
Navigation with Link
Use the Link component for client-side navigation:
import Link from 'next/link'
export default function Nav() {
return (
<nav>
<Link href="/">Home</Link>
<Link href="/blog">Blog</Link>
<Link href="/blog/my-post">A Post</Link>
</nav>
)
}Link prefetches the page in the background, making navigation instant.
Route Groups
Use parentheses to organize routes without affecting the URL:
app/
├── (marketing)/
│ ├── about/page.tsx # → /about
│ └── pricing/page.tsx # → /pricing
├── (app)/
│ ├── dashboard/page.tsx # → /dashboard
│ └── settings/page.tsx # → /settingsRoute groups let you apply different layouts to different sections.