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.

🧠 Test Your Knowledge

How do you create a dynamic route in Next.js?