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.
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.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> }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> }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.exampleexport 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> }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.exampleimport Link from 'next/link' <Link href="/blog/hello">Read the post</Link>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>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> }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> }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> }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.exampleexport const metadata = { title: 'My Blog', description: 'Thoughts on building for the web', }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.exampleimport Image from 'next/image' <Image src="/hero.png" alt="Hero" width={800} height={400} priority />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