Next.js

The React Framework for the Web

The React framework for production. Build full-stack web apps with server rendering, file-based routing, and a first-class developer experience.

📘 35 lessons🚀 6 projects🗺️ 3 roadmaps🐞 16 error fixes

Next.js Roadmap

A guided path from the fundamentals up. Tick off steps as you go.

Your progress0/12 steps · 0%

Next.js Foundations

The core mental model: routing, components, and data — the 20% that unlocks 80% of Next.js.

  1. What is Next.js (and why use it)?

    Next.js is a framework built on top of React. React gives you components; Next.js adds the *application* concerns around them: routing, rendering strategies (server vs. client), data fetching, and bundling — all pre-wired so you can focus on features.
  2. File-based routing with the App Router

    Folders inside `app/` become URL segments. A `page.tsx` makes a route public, and `layout.tsx` wraps everything beneath it. A folder like `[slug]` becomes a dynamic segment.
    example
    // app/blog/[slug]/page.tsx
    export default async function Page({
      params,
    }: {
      params: Promise<{ slug: string }>
    }) {
      const { slug } = await params
      return <h1>Post: {slug}</h1>
    }
  3. Server vs. Client Components

    Components are Server Components by default — they render on the server and ship zero JavaScript. Add `'use client'` at the top of a file only when you need interactivity (state, effects, event handlers, browser APIs).
    example
    'use client'
    import { useState } from 'react'
    
    export function Counter() {
      const [n, setN] = useState(0)
      return <button onClick={() => setN(n + 1)}>Clicked {n}</button>
    }
  4. Fetching data

    Server Components can be `async` and `await` data directly — no `useEffect`, no loading flags. The result is rendered on the server and streamed to the browser.
    example
    export default async function Page() {
      const res = await fetch('https://api.example.com/posts')
      const posts = await res.json()
      return <ul>{posts.map(p => <li key={p.id}>{p.title}</li>)}</ul>
    }
  5. Navigating with <Link>

    Use the `<Link>` component from `next/link` for navigation. It prefetches pages in the background and does client-side transitions, so moving between pages feels instant.
    example
    import Link from 'next/link'
    
    <Link href="/blog/hello">Read the post</Link>
  6. Styling your app

    Next.js supports Tailwind CSS, CSS Modules, global CSS, and CSS-in-JS. Tailwind is the most popular: utility classes right in your markup. CSS Modules (`*.module.css`) scope class names to a single component so they never collide.
    example
    // component.module.css
    .card { padding: 1rem; border-radius: 8px; }
    
    // Component.tsx
    import styles from './component.module.css'
    export default () => <div className={styles.card}>Hi</div>
  7. Shared layouts and templates

    A `layout.tsx` wraps every page beneath it and keeps its state across navigations (great for navbars and sidebars). A `template.tsx` is similar but re-mounts on every navigation — use it when you need a fresh instance each time (e.g. enter animations).
    example
    // app/dashboard/layout.tsx
    export default function Layout({ children }: { children: React.ReactNode }) {
      return <section><Sidebar />{children}</section>
    }
  8. Loading states & streaming with Suspense

    Add a `loading.tsx` next to a page and Next.js shows it instantly while the page's data loads — powered by React Suspense. You can also wrap any slow component in `<Suspense>` to stream the rest of the page immediately.
    example
    // app/dashboard/loading.tsx
    export default function Loading() {
      return <p>Loading your dashboard…</p>
    }
  9. Handling errors & not-found

    An `error.tsx` file (a Client Component) catches runtime errors in its segment and shows a fallback with a `reset()` button. A `not-found.tsx` renders when you call `notFound()` or hit an unknown route.
    example
    'use client'
    // app/error.tsx
    export default function Error({ reset }: { reset: () => void }) {
      return <button onClick={reset}>Try again</button>
    }
  10. Metadata & SEO

    Export a `metadata` object (or an async `generateMetadata` function) from any page or layout to set the title, description, and Open Graph tags. Next.js injects them into the `<head>` for you — no extra library needed.
    example
    export const metadata = {
      title: 'My Blog',
      description: 'Thoughts on building for the web',
    }
  11. Optimizing images & fonts

    Use `next/image` for automatic resizing, lazy loading, and modern formats — it prevents layout shift and slow loads. Use `next/font` to self-host Google Fonts with zero layout shift and no extra network request.
    example
    import Image from 'next/image'
    
    <Image src="/hero.png" alt="Hero" width={800} height={400} priority />
  12. Environment variables & config

    Put secrets in `.env.local` and read them with `process.env.MY_KEY` on the server. Variables prefixed with `NEXT_PUBLIC_` are exposed to the browser — never put secrets there. `next.config.ts` controls build-time options like image domains and redirects.
    example
    // .env.local
    DATABASE_URL="postgresql://..."
    NEXT_PUBLIC_SITE_NAME="DevPath"
    
    // server code
    const db = process.env.DATABASE_URL