Skip to main content
Next.js Fundamentals·Lesson 3 of 5

Routing and Navigation

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].

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   #  /settings

Route groups let you apply different layouts to different sections.