Next.js Learning Series

From Zero
to Next.js

Web evolution, core concepts, rendering strategies, routing, hydration — all in one place. Visual-first, no textbook walls.

Part 1 · The Journey

How the Web Evolved

Six eras that brought us from simple HTML files to full-stack React apps. Click any card to expand.

🌐
01
02
🗄️
03
📱
04
⚛️
05
06
Part 2 · 01

What is Next.js?

Think of Next.js as React with superpowers. React is great, but you have to set up a lot of things yourself. Next.js comes with all those things already built in — so you can just focus on building your app.

🗺️

Routing

Just create a file and Next.js makes it a page automatically. No extra setup.

🖥️

Rendering

You can choose — build the page on the server, or in the browser. Your call.

📡

Data Fetching

Easily load data from APIs or databases. It even saves the result so you don't fetch it again and again.

🧩

Server Components

Some parts of your page run on the server only. No JavaScript is sent to the user's browser for those parts.

Optimisation

Images load faster, fonts don't flash, scripts don't slow you down — Next.js handles it all.

🔍

SEO Friendly

Google can read your page content properly because the HTML is ready before the browser even runs JavaScript.

Part 2 · 02

Rendering Environments

To grasp the capabilities of Next.js, one must start at the core — rendering environments. There are two primary environments: the server and the client.

Rendering is the process of converting code into a visual and interactive display that users can view and interact with within a web browser. This process begins when a browser requests a webpage and ends with the server’s response, culminating in the rendered application the user interacts with.

There are two primary rendering environments: server and client. Server-side rendering (SSR) means that the assembly of the webpage happens mainly on the server, while Client-side rendering (CSR) assembles mainly on the client’s browser. A well-optimized web application utilizes a combination of both methods, leveraging the strength of each.

While React supports both, it lacks built-in SSR. This makes Next.js a go-to choice for developers, as it offers robust support for both SSR and CSR. With Next.js, we can specify rendering granularity down to the component level, choosing if it should be server-rendered, client-rendered, or a combination of both.

Explore the visual step-by-step differences below between client-rendered and server-rendered environments.

🖥️ Server-Side (SSR) Flow
💻 Client-Side (CSR) Flow
Step 1
Server
Browser
REQUEST

Client Sends Request

The user's browser sends a request to the website's server when the user visits a website.

Step 2
Server
Browser
REQUEST

Server Receives Request

The server receives the request from the browser and prepares to construct the page.

Step 3
Server
Browser
🗄️📄

Server Fetches Data & Files

The server fetches the required data (from databases or APIs) and files needed to construct the complete webpage.

Step 4
Server
Browser
Website

Server Renders HTML

The server compiles the data and runs React components to render the webpage into static HTML.

Step 5
Server
Browser
RESPONSE

Server Composes Response

The server has finished rendering the webpage to HTML and wraps it up inside a completed response.

Step 6
Server
Browser
RESPONSE

Server Sends Response

The server sends the fully rendered HTML webpage back to the user's browser.

Step 7
Server
Browser
RESPONSE

Browser Receives Response

The user's browser receives the fully built HTML response, showing content instantly.

Step 8
Server
Website
Browser

Display Website

The user's browser displays the fully rendered page to the user (which then hydrates in the background).

Part 2 · 03

Client-Side Rendering (CSR)

Client-side rendering is key to modern dynamic single-page applications. The server delivers a barebones HTML file, and the client browser runs JavaScript to construct the full page and enable interactivity.

Think of a website that offers a highly interactive, seamless, and dynamic user experience like YouTube and Airbnb. Client-side rendering (CSR) plays a significant role in making such experiences possible.

In Next.js, client-side can be implemented explicitly through client components, an opt-in feature that allows developers to designate specific components to be rendered on the client.

In a later lesson, we’ll dive into the details of client components, but for now, know that you can define a client component as you would a regular React component with a 'use client' directive. This directive specifies that the component and its children components should be rendered on the client side.

Interactive Code Sandbox

Click the interactive toggle box on the right to see the live rendering and how React updates state inside the client.

components/ToggleBox.tsx
CLIENT
'use client'
import React, { useState } from 'react'

export default function Page() {
  const [toggle, setToggle] = useState<boolean>(false)

  return (
    <div onClick={() => setToggle(!toggle)}>
      {toggle ? 'True' : 'False'}
    </div>
  )
}
Live Interactive Preview
Rendered Value: FalseClick card to fire onClick events

Dynamic Single Page Application (SPA) Demo

Simulate how client-side applications fetch raw JSON data and update the UI instantly without reloading the entire page.

✉️ MailBox (SPA Client)
Vercel Team
Your project nextjs-notes is deployed!
10:42 AM
Dan Abramov
Thoughts on Server Components vs. Client Components
9:15 AM
🛰️ Network console (JSON data only)
Idle. Click "Simulate New Email" to see XHR/fetch network requests.
Part 2 · 04

Server-Side Rendering (SSR)

SSR compiles dynamic pages directly on capable server infrastructure. This improves speed, SEO crawlability, and offloads rendering work from the client hardware.

While client-side rendering allows websites to be dynamic and interactive, constructing and loading the page all on the client’s hardware can be an expensive endeavor. A slow internet connection or slow client hardware can compound the wait time for the user, who is busy staring at nothing as the browser assembles the webpage.

In server-side rendering (SSR), the webpage is assembled on the server. Offloading the rendering to the server leverages the more capable server infrastructure, reducing the load on the client’s hardware.

Server-side rendering is ideal for web applications that need a lot of data fetching, search engine optimization (SEO), and speed. By moving the fetching requests closer to the database, developers reduced the latency of these requests. Sending fully rendered pages also means users can view them immediately when visiting a website, regardless of their hardware’s capabilities. The rendered pages can then be crawled and indexed by search engine bots, leading to better SEO.

By default, Next.js renders components on the server side. You can define a React component without additional configurations, as Next.js automatically handles the server-side rendering.

Within server-side rendering itself, Next.js offers three distinct approaches: static rendering, dynamic rendering, and streaming. In a later lesson on Server Components, we will delve deeper into these subsets and their specific applications.

At this stage, while the page is visible and contains elements like buttons and form fields, they are not fully interactive. In a sense, it is like a fresh first layer of paint on our page. In the next exercise, we’ll be discussing what comes after to make the web application interactive.

Next.js SSR Subsets

Next.js offers three core environments under Server-Side Rendering. Click each card to see the details.

Static Rendering

Build Time (Once)

HTML is rendered once during project build. The result is cached and served...

Dynamic Rendering

Request Time (Every visit)

HTML is generated on the server for each user request. Best for personalize...

Streaming

Progressive loading

The server renders pages in chunks. Highly critical HTML parts load first, ...

Static Rendering (Build Time (Once))

HTML is rendered once during project build. The result is cached and served instantly to everyone via a CDN.

🏆 Best for: Blogs, marketing pages, landing pages, documentation.
📦 Serve Cached HTML

SEO Bot Indexing & Paint Layer Analogy

SSR outputs static HTML first, providing instant visibility to users and search engines.

🤖
Googlebot / Search crawlerStatus: Crawling static HTML
🔍 Googlebot reads index page...
✓ Found structural text nodes: "NextJS Notes..."
✓ Found 10 core anchors/links.
✓ Indexing complete immediately (no JS execution delay!)
🎨 Static Paint Preview

Everything is painted on the screen right away, but not yet interactive:

Part 2 · 05

Starting a New Project

You don't have to set up a Next.js project from zero. Just run one command in the terminal and it asks you a few questions, then builds the whole project for you automatically. It's like pressing a “new project” button.

Terminal — zsh
~ $ npx create-next-app@latest my-app
 
✔ Would you like to use TypeScript? Yes
✔ Would you like to use ESLint? Yes
✔ Would you like to use Tailwind CSS? No
✔ Would you like to use the App Router? Yes
 
✅ Project created in ./my-app
 
~ $ cd my-app && npm run dev
▲ Next.js 15 · ready on http://localhost:3000
Part 2 · 06

The App Router — Pages from Folders

In Next.js, you don't need to write any code to set up your pages. Just create a folder with a file inside it, and that automatically becomes a page on your website. The folder name becomes the URL. Click on the files below to see how it maps.

📁 Project Files
📁app/
📄page.tsx/ route
📄layout.tsx
📁about/
📄page.tsx/about
📁blog/
📄page.tsx/blog
📁[id]/
📄page.tsx/blog/:id
↑ Click files to explore

Route Map

/
app/page.tsx · Home page
layout.tsx
Wraps ALL pages · shared UI like navbar
/about
app/about/page.tsx
/blog
app/blog/page.tsx · Blog list
/blog/:id
app/blog/[id]/page.tsx · Dynamic!
💡

Simple Rule: Folder name = URL address. Put a page.tsx inside the folder = anyone can visit that page. No page.tsx = page not found (404 error).

Part 2 · 07

What is Hydration?

When SSR sends you a ready-made page, it looks good — but buttons don't work yet. Hydration is when JavaScript loads and makes everything clickable. Think of it like: the page is a statue, hydration gives it a heartbeat. Click each step below.

Step 1
📄 HTML
📦 JS Bundle
🗄️ DATA
Ready to parse

Receive Files

A client device receives a fully rendered HTML page. It also receives a bundle of JavaScript files, and any extra data needed to make the page is sent.

Step 2
Server DOM
documentHTMLbodyhead<button><button>title

Represent Server DOM

The fully rendered HTML page received from the server is parsed and represented as a standard DOM tree in the browser.

Step 3
Constructing Virtual DOM...
documentHTMLbodyhead<button><button>title

Construct Virtual DOM

Once the client's device receives the HTML page and the JavaScript bundle, React initializes and starts constructing a Virtual DOM tree.

Step 4
Virtual DOM Constructed
documentHTMLbodyhead<button><button>title

Virtual DOM Ready

The Virtual DOM structure is successfully built in client-side memory, reflecting the expected React component structure.

Step 5
Locating Attachment Points
documentHTMLbodyhead<button><button>titleattach onClickattach onClick

Locate Attachments

React parses the Virtual DOM to locate where dynamic events (like onClick, onSubmit) and other interactivities should be attached.

Step 6
Matching Actual DOM Elements
documentHTMLbodyhead<button><button>title

Match DOM Elements

React walks the real Server DOM tree to locate the actual matching physical elements corresponding to the event attachment points.

Step 7
Server DOM
documentHTMLbodyhead<button><button>title
↔️Comparing
Virtual DOM
documentHTMLbodyhead<button><button>title

Reconciliation Check

React compares the constructed Virtual DOM with the actual Server DOM nodes to ensure consistency. If there is a mismatch, a hydration warning is thrown.

Step 8
Attaching Event Listeners
documentHTMLbodyhead<button><button>title🔗 click active🔗 click active

Attach Interactivity

React attaches the event handlers to the corresponding real DOM nodes. The application starts listening to events from the elements.

Step 9
Active Page

Page Interactive

The HTML page is now fully interactive. Click handlers are bound, input fields update, and any buttons on the screen can be clicked.

Part 2 · 08

CSS Modules — Styling Without Mess

Normally, if two components both have a CSS class called .btn, they crash into each other and break the style. CSS Modules fix this — each component gets its own private styles that never mix with anyone else's. Just name your file with .module.css at the end.

Without CSS Modules GLOBAL

styles.css
/* Applies EVERYWHERE */
.btn { background: blue; }

/* Another component's .btn */
.btn { background: red; /* 💥 CONFLICT! */ }
⚠️ The .btn style applies to the whole app — any component that uses .btngets affected, even if you didn't want that

With CSS Modules SCOPED

Button.module.css + Button.tsx
/* Button.module.css */
.btn { background: blue; }

import styles from './Button.module.css'
export function Button() {
  return <button className={styles.btn}>Click!</button>
}
✅ Next.js secretly renames .btn to something like .btn_x7a3k so it only applies to thiscomponent — never anyone else's
Part 3 · Intro

Level 1 — Core Next.js (App Router)

A visual guide to structuring routes, layouts, links, and pages. Learn how Next.js translates the folder structure directly into your web application URL system.

🎓 What You Will Learn to Build

By the end of this level, you should be able to create a fully-routed, cohesive site with a shared navigation layout and dynamic segments:

🏠 Home Pageapp/page.js
ℹ️ About Pageapp/about/page.js
⚙️ Services Pageapp/services/page.js
📞 Contact Pageapp/contact/page.js
📝 Blog Pageapp/blog/page.js
⚡ Dynamic Postsapp/blog/[slug]
🗺️ Shared Navbarlayout.js Navbar
🦶 Shared Footerlayout.js Footer
Part 3 · 01

1. The App Folder & Route Segments

The app/ folder is the heart of Next.js routing. Every folder nested inside app/ becomes a Route Segment in the URL path.

📁 Interactive Project Tree
📁src/
📁app/
📄layout.jsshared frame
📄page.js/
📁about/
📄page.js/about
📁contact/
📄page.js/contact
📁blog/
📄page.js/blog

💡 Click on any file to inspect how the route structures mapping works.

src/app/page.jsMaps to URL: /

How it works

The main entry page of your website. Next.js maps the root folder directly to the homepage.

page.js
export default function HomePage() {
  return <h1>Home Page</h1>;
}
📐

Rule: Folder name = Route Segment. The page.js file defines the actual screen content the user sees. Without a page.js file inside a folder, that path returns a 404 error.

Part 3 · 02

2 & 3. page.js & layout.js

Every route needs a page.js. To avoid repeating shared UI like Navbars and Footers on every page, Next.js uses layout.js to wrap nested files automatically.

Layout Option
Select URL Route
🟢 The layout.js renders shared structure. Next.js passes the page component into the layout as the { children } prop, so the navbar and footer stay in place.
https://my-nextjs-app.edu/
▲ Layout Navbar
HomeAboutContact
Page Content (page.js children)

🏠 Home Page content renders here

▲ layout.js Footer · Shared across all directories
Part 3 · 03

4. Nested Layouts

Next.js allows layouts to be nested. Layouts in subfolders act as wrappers around pages in their directory, nested inside the outer root layout.

📁 Nested Folder Structure
📁app/
📄layout.js (Root Layout)
📁dashboard/
📄layout.js (Dashboard Layout)
📄page.js/dashboard
📁settings/
📄page.js/dashboard/settings
👈 Settings Page renders inside the Dashboard Layout, which in turn renders inside the Root Layout.

Visual Nesting Hierarchy

1. Root Layout WrapperMain Navbar
🌐 main-navbar.jsx
2. Dashboard Layout WrapperSidebar
📂 Sidebar menu
3. Active PageSettings Content
Part 3 · 04

5 - 8. Route Types (Static & Dynamic)

Next.js supports static routing, dynamic segments using brackets [slug], and catch-all routes [...slug] to handle flexible page configurations.

⚡ Dynamic Routes Parser ([slug])

Select or type a slug to observe how Next.js routes it inside app/blog/[slug]/page.js:

Folder:app/blog/[slug]/page.js
Request URL:/blog/react
Component Props:
export default function BlogPost({ params }) {
  // params = { slug: "react" }
  return <h1>{params.slug}</h1>;
}

🗂️ Catch-All Routes Parser ([...slug])

Catch-all folders catch all subfolders. Type a slash-separated pathway to analyze the results:

Example: react/hooks/useState
Folder:app/docs/[...slug]/page.js
Visited URL:/docs/react/hooks/useState
Params Structure:
// params.slug represents sub-segments
params = {
  slug: ["react","hooks","useState"]
}
Part 3 · 05

9 & 10. Route Groups & Navigation

Route Groups group folders together without impacting URLs. Next.js <Link> enables Single Page Application navigation without full page reloads.

📁 Route Groups (marketing)

Parentheses folders like (marketing) or (dashboard) tell Next.js to ignore this folder name when creating URL links.

📁 Route Group Tree
📁app/
📁(marketing)/skipped
📁about/
📄page.js/about
📝 Result: Visiting /about works perfectly. Visting /marketing/about returns a 404.
Part 3 · 06

11. Mini Blog Project Structure

Below is the finalized file hierarchy and website router map for our level 1 blog application, incorporating navigation wrappers and dynamic subpaths.

📁 final-project/src/
📁app/
📄layout.js
📄page.js
📁about/
📄page.js
📁services/
📄page.js
📁contact/
📄page.js
📁blog/
📄page.js
📁[slug]/
📄page.js
📁components/
📄Navbar.jsx
📄Footer.jsx

📍 Application Sitemap Map

/🏡 Home Page (Root)
/aboutℹ️ About Details
/services🛠️ Offered Services
/contact📞 Contact Directory
/blog📝 Blog Article list
/blog/react└ ⚛️ Article: react (dynamic)
/blog/nextjs└ ▲ Article: nextjs (dynamic)
/blog/javascript└ 📄 Article: javascript (dynamic)
💡

Next.js matches paths like /blog/react automatically by injecting the string “react” into params.slug on the page template.

Part 3 · Complete

Level 1 Mastery Checklist

Check off items as you master them to track your learning progress. Try to build the mini-blog from memory!

Your Progress0 of 11 skills acquired
0% Complete
Create routes using folders
Create page.js files
Create shared layout.js
Create nested layouts
Create static routes
Create dynamic routes
Create catch-all routes
Create route groups
Use Link component
Build a 5-page website
Build a blog with [slug]
Part 4 · Rendering System

Level 2 — Rendering System (Modern Next.js)

One golden rule governs modern Next.js development: Where does this code run? Server or Browser? Learn to architecture client interactivity on top of lightning-fast server infrastructure.

🎓 Level 2 Curriculum Overview

Master the App Router rendering system across 6 comprehensive modules:

M1
Intro to RenderingSyllabus Steps 1
M2
Server ComponentsSyllabus Steps 2 - 6
M3
Client ComponentsSyllabus Steps 7 - 12
M4
Combining SystemsSyllabus Steps 13 - 15
M5
Decision MakingSyllabus Steps 16 - 17
M6
Practical ProjectSyllabus Step 18
Module 1 · Intro to Rendering

1. What is Rendering?

Rendering is the process of Next.js taking your React components and translating them into HTML elements that browsers can parse and show on the screen.

Interactive Lifecycle Stepper
🌐
1. Request
2. Next.js
🏗️
3. HTML Build
🖼️
4. Fast Paint
💧
5. Hydrate
6. Active
💡

Step 1: User requests a page (e.g. clicks a link or enters the URL).

Module 2 · Server Components

2 - 6. React Server Components (RSC)

Server Components run exclusively on the server, offloading computations from user hardware. In Next.js, every component is a Server Component by default.

2. Default Server Component

No special keywords required. Standard code runs natively on the backend.

app/page.js
export default function Home() {
  return <h1>Hello Server</h1>;
}

3. Async Server Component

Next.js allows components to be declared `async` to await database queries or APIs directly.

app/page.js
export default async function Page() {
  const res = await fetch('...');
  return <div>Data Ready</div>;
}

4. Fetching Data in Server Components

Click a database target to simulate server fetching. Notice how simple the data request flows directly inside the component body:

Async Component
const res = await fetch(
  'https://api.com/users'
);
const data = await res.json();
Server Payload Output✓ 200 OK
[
  {
    "id": 1,
    "name": "Leanne Graham",
    "email": "Sincere@april.biz",
    "company": "Romaguera-Crona",
    "city": "Gwenborough"
  },
  {
    "id": 2,
    "name": "Ervin Howell",
    "email": "Shanna@melissa.tv",
    "company": "Deckow-Crist",
    "city": "Wisokyburgh"
  }
]

5. Reading Databases Directly

Since Server Components run in the secure backend environment, you can query database engines directly. No intermediate API endpoints required!

MONGODB OR PRISMADbEngine Status
CONNECTED
Query: User.find()Credentials: process.env.DB_URI (Hidden from browser)
page.jsx
import { db } from "@/lib/db";

export default async function Dashboard() {
  const users = await db.users.findMany(); // Runs directly on Server!
  return <div>Loaded {users.length} users.</div>;
}

6. Server Components Limitations Matrix

An interview favorite. Understand what Server Components are natively allowed to execute vs what breaks.

✓ Server Component Capabilities
⚡ Fetch raw APIs directly
🗄️ Run DB requests & SQL queries
🔑 Access secure .env variables
📁 Read local server filesystem (fs)
❌ Server Component Limitations
useState / state hooks (Throws error)
useEffect / lifecycle hooks (Throws error)
Event listeners (onClick, onChange)
Browser APIs (window, localStorage)
Module 3 · Client Components

7 - 12. React Client Components

Client Components allow you to add interactivity to your application. They run in the browser and are hydrated after loading.

7. The "use client" Boundary

Add the `"use client"` string directive at the very top of a file. This declares a boundary, informing Next.js that this component and any imports it makes will run in the browser.

components/Counter.jsx
"use client";

import } useState } from "react";
export default function Counter() { ... }

8. useState in Action

Allows dynamic UI reactivity based on interactions. Test the client widgets:

Click Counter
Like State
Toggle State
const [count, setCount] = useState(0);
<button onClick={() => setCount(count + 1)}>

10. Event Handlers

Capturing user gestures directly in browser (e.g. typing, hovering, submitting):

Hover mouse cursor here

Captured Events: onMouseEnter, onChange, onSubmit

9. useEffect Side Effects

Running side effects in the client (updating DOM, starting intervals, window listeners). Test the effect tasks:

Effect Task 1: Timer Interval
Seconds: 10
Effect Task 2: Resize Listener
Mock Viewport Width:
window.innerWidth = 1024px
Client Effect Console LogsuseEffect(() => { ... }, [dep])
[System] Effect hook initialized.

11. Interacting with Browser APIs

Only Client Components can access browser APIs like `window`, `document`, and `localStorage` because they execute inside the browser sandbox.

localStorage Preferences Sandbox
Retrieved LocalStorage:"empty"
Localstorage interaction
useEffect(() => {
  // Safe to access browser APIs inside client side hooks
  const pref = localStorage.getItem('theme_preference');
  setPref(pref);
}, []);

12. Client Components Limitations Matrix

Avoid heavy calculations, and never include credentials or secret keys in Client Components. They are compiled into JS bundles and sent directly to the client browser!

✓ Client Component Capabilities
🎨 Manage states (useState, useActionState)
🔄 Trigger lifecycles (useEffect)
🖥️ Manipulate DOM elements & Window
⚡ Capture user interactive click/change gestures
❌ Client Component Pitfalls
Exposing Secret Env Vars (Leaks to browser)
Direct SQL Queries (Fails completely)
Importing server-only engines (fs, child_process)
Bloating client bundle sizes with massive packages
Module 4 · Combining Server & Client

13 - 15. Server and Client Composition

Next.js allows you to nest Client Components inside Server Components. You fetch data securely on the server and pass it down as props.

13. Passing Props Across the Boundary

Props passed from Server Components to Client Components must be serializable (e.g. JSON strings, arrays, basic objects). Databases connections or classes cannot cross this boundary:

🖥️
1. Server PageFetches user array
Passing Props →
💻
2. Client SearchReceives users [ ] prop
Interactions →
3. Active FilterRe-renders instantly

14. Mixing Components

Place the interactive client segments in isolated leaves. Keep parent containers running as Server Components.

app/page.js
import Search from '@/components/Search';

export default async function Page() {
  const data = await fetchUsers();
  return (
    <main>
      <h1>Directory</h1>
      <Search initialUsers={data} />
    </main>
  );
}

15. Composition Pattern

To nest a Server Component inside a Client Component, pass it as the children prop. This ensures the Server Component is compiled before reaching the browser.

components/ClientWrapper.jsx
"use client"

export default function ClientWrapper({ children }) {
  return (
    <div className="interactive-layout">
      {children} {/* Server components render fine here */}
    </div>
  );
}
Module 5 · Decision Making

16 - 17. Server vs Client Component Choice

Failing to choose the correct component environment leads to runtime errors or performance penalties. Use this step-by-step decision tool.

16. Checklist Cheat Sheet

Interaction / State?Client
Read DB / Database?Server
Secret credentials / API keys?Server
Event click / input handlers?Client
Hooks (useState, useEffect)?Client

17. Choosing the Right Component Builder

Click options to evaluate the environment selection tree:

1. Does the component need user interactivity, inputs, or state?
Module 6 · Practical Project

12. User Directory Project Structure

Below is the finalized file hierarchy and visual components map for our Level 2 user directory application, integrating Server and Client components.

📁 user-directory/src/
📁app/
📄layout.js
📄globals.css
📄page.js
📁components/
📄Search.jsx
📄Counter.jsx
📄Modal.jsx
📄ThemeToggle.jsx

📍 Application Components Map

app/layout.js🧱 Root html/body layout wrapper
app/globals.css🎨 Global styling & Tailwind configs
app/page.js🖥️ Server Page (fetches user records)
components/Search.jsx💻 Client query search input & lists
components/Counter.jsx💻 Client stateful increase widget
components/Modal.jsx💻 Client conditional overlay window
components/ThemeToggle.jsx💻 Client theme local storage switcher
💡

Data fetches securely on the Server Component (page.js) and flows down via serializable props to the interactive Client Components.

🖥️ Nearly Expected Website Sketch

The final application layout renders the dynamic search filter and active widgets sequentially:

--------------------------------

          User Directory

Search: ___________

------------------------

Leanne Graham

Ervin Howell

Clementine Bauch

...

------------------------

Counter: 0

[+]

------------------------

[Open Modal]

------------------------

Dark Mode Toggle

--------------------------------

🚀 My recommendation for how we proceed

Don't build the whole thing at once. Treat this like a guided Next.js course.

📚 Lesson 1 (today):
  • Project setup
  • Understand the folder structure
  • Build app/page.js
  • Convert it to an async Server Component
  • Fetch users from the API
  • Render the user list
  • Understand why the logs appear in the terminal instead of the browser
After Lesson 1, we'll review what happened, discuss the underlying Next.js concepts, and then move to Lesson 2: creating the first Client Component (Search.jsx) and passing data from the Server Component to it.
Part 4 · Mastery

Level 2 Practice Checklist

Check off items as you master them to track your learning progress. Try to build the user directory simulator app from scratch!

Your Level 2 Progress0 of 13 skills acquired
0% Complete
Create Server Component
Create Async Server Component
Fetch API Data
Read Database Data
Create Client Component
Add useState
Add useEffect
Add Event Handlers
Use Browser APIs
Pass Props Server → Client
Mix Server + Client Components
Decide when to use each
Build User Directory Project

⚡ Quick Cheatsheet

Everything from Part 1 + Part 2 + Part 3 in one glance

Static Web
HTML files served as-is · same page for everyone
Ajax / XHR
Update parts of page without full reload
SPA
Load HTML once · JS renders everything client-side
React
Component-based · Virtual DOM · declarative UI
Next.js
React + routing + SSR + optimisation, out of the box
SSR
Server builds HTML → fast load → then hydrates
CSR
Add 'use client' → renders in browser
Hydration
JS attaches events to server-rendered HTML
App Router
folder = URL · page.tsx = accessible route
CSS Modules
Name .module.css → auto-scoped classnames
Client Nav
Pre-fetched, instant transition without reloading browser tab
Layout vs Temp
Layouts persist state · Templates re-mount and reset state
Dynamic Routes
Bracket folders like [id] / [[...slug]] inject params
Hierarchy
Nested wrapping layers: Layout → Template → Error → Loading → Page