T26: Next.js Routing & Rendering

Next.js is like upgrading from a food truck (React SPA) to a proper restaurant with a built-in address system. It adds file-based routing, server-side rendering, and a clear structure so you do not have to wire everything together yourself.

File-Based Routing

In Next.js, the file system is the router. Create a file at app/about/page.tsx and it becomes the /about route. No router configuration needed - compare this to the hash-based routing from T13.

// Directory structure = URL structure
app/
  page.tsx          // "/" route
  about/
    page.tsx        // "/about" route
  menu/
    page.tsx        // "/menu" route
    [id]/
      page.tsx      // "/menu/123" dynamic route

// app/menu/page.tsx
export default function MenuPage() {
    return (
        <main>
            <h1>Our Menu</h1>
            <p>Browse our selection below.</p>
        </main>
    );
}

Server vs Client Components

Next.js components are server components by default. They run on the server, can fetch data directly, and send only HTML to the browser. Add "use client" at the top when you need interactivity like state or event handlers.

// Server component (default) - runs on server, no JS sent to browser
export default async function MenuList() {
    const items = await fetch("https://api.example.com/menu").then(r => r.json());
    return <ul>{items.map(i => <li key={i.id}>{i.name}</li>)}</ul>;
}

// Client component - needs "use client" for interactivity
"use client";
import { useState } from "react";

export default function AddToCart({ itemId }: { itemId: number }) {
    const [added, setAdded] = useState(false);
    return (
        <button onClick={() => setAdded(true)}>
            {added ? "Added" : "Add to Cart"}
        </button>
    );
}

Layouts

A layout.tsx wraps all pages in its directory and below. It persists across navigation, keeping shared UI like headers and sidebars mounted.

When to Use What

Use server components for static content and data fetching. Use client components only when you need useState, useEffect, onClick, or browser-only APIs.

flowchart TB A[Browser Request] --> B[Next.js Server] B --> C[Server Components Rendered] C --> D[HTML Sent to Browser] D --> E[Client Components Hydrated] E --> F[Interactive Page Ready] style A fill:#4a90d9,stroke:#2a5f8f,color:#1a1a1a style B fill:#333333,stroke:#1a1a1a,color:#ffffff style C fill:#6ab04c,stroke:#3d7a28,color:#1a1a1a style E fill:#f9ca24,stroke:#c9a31e,color:#1a1a1a style F fill:#9b59b6,stroke:#6c3483,color:#1a1a1a

Key Takeaways

  • File-based routing maps directory structure to URLs - no configuration needed
  • Components are server-rendered by default, sending only HTML to the browser
  • Add "use client" only when a component needs state, effects, or event handlers
  • Layouts wrap child pages and persist across navigation for shared UI