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
22

Search Params, Cookies & Dynamic APIs

Reading12m
23

Chapter 4 — Quiz

Quiz12m

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 5 of 10·Chapter 5 — Server Actions & Forms
Lesson 24 of 54Reading16 min

Server Actions From First Principles

#Server Actions From First Principles¶

Server Actions are functions that run on the server but can be called from a Client Component or directly from a <form action={…}>. They replace 90% of the boilerplate of API routes for write operations.

Anatomy of a Server Action¶

ts
9 lines
1"use server";   // marks every export in this file as a Server Action
2
3import { db } from "@/lib/db";
4
5export async function createCourse(formData: FormData) {
6  const title = formData.get("title")?.toString() ?? "";
7  if (!title) throw new Error("Title is required");
8  return db.course.create({ data: { title, slug: slugify(title) } });
9}

Calling From a Form (No JS Required!)¶

tsx
10 lines
1import { createCourse } from "./actions";
2
3export default function NewCourse() {
4  return (
5    <form action={createCourse}>
6      <input name="title" required />
7      <button>Create</button>
8    </form>
9  );
10}

This is a Server Component with a server-side form action. It works without JavaScript — progressive enhancement by default.

Calling From a Client Component¶

tsx
12 lines
1"use client";
2import { createCourse } from "./actions";
3
4export function NewCourseButton() {
5  return (
6    <button onClick={async () => {
7      const fd = new FormData();
8      fd.append("title", "Untitled course");
9      await createCourse(fd);
10    }}>+ New course</button>
11  );
12}

Or with typed input (no FormData):

ts
6 lines
1// actions.ts
2"use server";
3
4export async function createCourseTyped(input: { title: string }) {
5  return db.course.create({ data: { title: input.title } });
6}
tsx
2 lines
1// Client
2const course = await createCourseTyped({ title: "New course" });

Where Actions Can Live¶

LocationNote
In a actions.ts file with "use server"; at the topEvery export is an action
Inline inside a Server Component bodyMark the function itself with "use server"
tsx
7 lines
1export default function Page() {
2  async function save(formData: FormData) {
3    "use server";
4    // …
5  }
6  return <form action={save}>{/* … */}</form>;
7}

Use file-level actions for anything reusable. Use inline actions for one-off forms close to where they're used.

Returning Data¶

ts
6 lines
1"use server";
2
3export async function rename(id: string, name: string) {
4  const course = await db.course.update({ where: { id }, data: { name } });
5  return { ok: true, course };
6}

The return value is a normal value to the caller — typed end-to-end.

Errors¶

ts
10 lines
1"use server";
2
3export async function deleteCourse(id: string) {
4  try {
5    await db.course.delete({ where: { id } });
6    return { ok: true };
7  } catch (e) {
8    return { ok: false, error: "Cannot delete a published course" };
9  }
10}

Prefer typed error return values over throwing. Form handlers cope with them gracefully via useActionState.

Behind the Scenes¶

Server Actions are POSTed as a multipart form (when called from a form) or as an RPC-style request (when called directly). Next.js generates a stable, signed action ID — there is no public API route you accidentally expose. The function body never reaches the browser.

What You Can't Do¶

  • Pass non-serializable arguments (React elements, class instances, Maps)
  • Call them from outside the request lifecycle (cron — use a Route Handler)
  • Stream large responses (Actions return atomically; for streaming use a Route Handler with a stream response)

Previous

Chapter 4 — Quiz

Next

Forms with useActionState & Progressive Enhancement

Use ← → arrow keys to navigate between lessons