CoachnestCoachnest
Sign InGet Started
Back to course

Next.js 16: The Complete Developer Guide

…
—
Contents
1

What's New in Next.js 16

Reading14mFree
2

Installation, CLI & Your First Project

Reading12mFree
3

Project Structure & Conventions Deep Dive

Reading16m
4

Turbopack — The New Default Bundler

Video18m
5

Configuring TypeScript, ESLint & next.config.ts

Reading14m
6

Chapter 1 — Quiz

Quiz10m
7

App Router Fundamentals

Reading16m
8

Dynamic Routes, Catch-Alls & Type-Safe Params

Reading14m
9

Route Groups & Parallel Routes

Reading16m
10

Intercepting Routes & Modal Patterns

Reading12m
11

Loading, Error & Not-Found UI

Reading12m
12

Chapter 2 — Routing Quiz

Quiz12m
13

Understanding the Server/Client Boundary

Reading18m
14

Choosing When to use "use client"

Reading14m
15

Composing Server & Client Components

Reading14m
16

server-only, client-only & Code Splitting

Reading12m
17

Chapter 3 — Quiz

Quiz10m
18

Fetching Data in Server Components

Reading14m
19

The Next.js 16 Cache Model

Reading16m
20

Revalidation: revalidateTag, revalidatePath & On-Demand

Reading12m
21

Cache Components — Building Reusable Cached Functions

Reading14m

Search Params, Cookies & Dynamic APIs

Reading12m
23

Chapter 4 — Quiz

Quiz12m
24

Server Actions From First Principles

Reading16m
25

Forms with useActionState & Progressive Enhancement

Reading14m
26

Optimistic UI with useOptimistic

Reading12m
27

Validation with Zod + Server Actions

Reading12m
28

Chapter 5 — Quiz

Quiz10m
29

Static vs Dynamic vs Streaming

Reading14m
30

generateStaticParams & Pre-Rendering Dynamic Routes

Reading12m
31

Incremental Static Regeneration (ISR)

Reading12m
32

Partial Prerendering (PPR)

Reading16m
33

Edge Runtime vs Node.js Runtime

Reading12m
34

Rendering Strategies Deep Dive

Video22m
35

Chapter 6 — Quiz

Quiz12m
36

Tailwind CSS v4 with Next.js 16

Reading14m
37

CSS Modules, Global Styles & Scoped CSS

Reading10m
38

next/image — Smart, Fast Images

Reading14m
39

Fonts, Icons & Metadata

Reading12m
40

Chapter 7 — Quiz

Quiz10m
41

Middleware Fundamentals

Reading14m
42

Sessions, JWTs & Cookies

Reading16m
43

Protecting Server Components & Server Actions

Reading12m
44

Chapter 8 — Quiz

Quiz10m
45

Prisma with Next.js — The Production Setup

Reading14m
46

Mutations: Server Actions + Database Writes

Reading12m
47

Route Handlers & REST APIs

Reading12m
48

Chapter 9 — Quiz

Quiz10m
49

Unit & Component Testing with Vitest

Reading12m
50

End-to-End Testing with Playwright

Reading14m
51

Deploying to Vercel

Reading12m
52

Self-Hosting with Docker

Reading14m
53

Production Performance Checklist

Reading12m
54

Final Assessment — Next.js 16 Mastery

Quiz20m
←→navigate lessons
Chapter 4 of 10·Chapter 4 — Data Fetching & The Next.js 16 Cache Model
Lesson 22 of 54Reading12 min

Search Params, Cookies & Dynamic APIs

#Search Params, Cookies & Dynamic APIs¶

Any time you read a request-specific value (cookies, headers, search params), the route turns dynamic — it cannot be prerendered. Knowing this avoids surprise build failures.

searchParams (Promise in 16)¶

tsx
8 lines
1// app/search/page.tsx
2type SP = Promise<{ q?: string; page?: string }>;
3
4export default async function Search({ searchParams }: { searchParams: SP }) {
5  const { q = "", page = "1" } = await searchParams;
6  const results = await searchCourses(q, Number(page));
7  return <SearchResults results={results} query={q} />;
8}

Reading searchParams makes the page dynamic — that's correct here.

cookies() — Read & Write¶

ts
18 lines
1import { cookies } from "next/headers";
2
3// Read
4const session = (await cookies()).get("session")?.value;
5
6// Write (only inside Server Actions or Route Handlers)
7(await cookies()).set({
8  name: "session",
9  value: token,
10  httpOnly: true,
11  secure: true,
12  sameSite: "lax",
13  path: "/",
14  maxAge: 60 * 60 * 24 * 30,
15});
16
17// Delete
18(await cookies()).delete("session");

headers()¶

ts
5 lines
1import { headers } from "next/headers";
2
3const h = await headers();
4const ua = h.get("user-agent");
5const ip = h.get("x-forwarded-for")?.split(",")[0]?.trim();

headers() is read-only. To set response headers, return them from a Route Handler.

draftMode()¶

For previewing unpublished CMS content:

ts
3 lines
1import { draftMode } from "next/headers";
2
3const { isEnabled } = await draftMode();

Toggle from a route handler:

ts
7 lines
1// app/api/draft/route.ts
2import { draftMode } from "next/headers";
3
4export async function GET() {
5  (await draftMode()).enable();
6  return Response.redirect(new URL("/", request.url));
7}

When a Page Becomes Dynamic¶

Any of these calls flip the page to dynamic rendering:

  • cookies()
  • headers()
  • draftMode()
  • searchParams access
  • fetch with cache: "no-store"
  • A route handler with a non-GET method

If you want a page to stay static, push these calls into a Client Component, an Action, or a separate dynamic route segment.

A Pattern: Static Shell, Dynamic Island¶

Combine a static page with a small dynamic Server Component using Suspense:

tsx
24 lines
1// app/page.tsx — static
2import { Suspense } from "react";
3
4export default function Home() {
5  return (
6    <>
7      <Hero />
8      <Suspense fallback={<UserBadgeSkeleton />}>
9        <UserBadge />     {/* dynamic — reads cookies */}
10      </Suspense>
11      <Footer />
12    </>
13  );
14}
15
16// components/UserBadge.tsx — dynamic
17import { cookies } from "next/headers";
18
19export async function UserBadge() {
20  const session = (await cookies()).get("session")?.value;
21  if (!session) return <SignInPrompt />;
22  const user = await getUserBySession(session);
23  return <span>Hi, {user.name}</span>;
24}

Enable PPR on the route, and the shell prerenders while the badge streams in per-request — best of both worlds.

Previous

Cache Components — Building Reusable Cached Functions

Next

Chapter 4 — Quiz

Use ← → arrow keys to navigate between lessons