Level 2 · Intermediate Full-stack¶
Goal: turn a mostly static site into a full-stack application — one that reads and writes a real database, validates forms on the server, protects pages behind a login, exposes an API for other clients, and keeps its caches honest after data changes.
Level 1 covered what happens when a page is read. Level 2 is about what happens when data changes: where the change is handled, how you validate it, and how every page that showed the old data finds out.
Three ideas run through this level:
- The server is the source of truth, and mutations go through it. Server Actions
let a
<form>call a server function directly. They are public HTTP endpoints in disguise, so every one validates its input and checks authorisation. - Every cache needs an invalidation story. Static pages and cached data are fast
because they are old. When you write, you must say which cached results are now
stale — with
revalidatePath,revalidateTagorupdateTag. - Put checks where they can't be skipped. Proxy is good for fast redirects, but authorisation belongs next to the data, in the code that reads or writes it.
Modules¶
- Dynamic Routes & Params —
[id], catch-all segments, asyncparams,generateStaticParams - Loading, Error & Not-Found UI —
loading.tsx,error.tsx,not-found.tsxand status codes - Server Actions & Forms —
"use server",useActionState, validation, progressive enhancement - Caching & Revalidation — the previous model and Cache Components,
revalidatePath, tags - Route Handlers (API Endpoints) —
route.ts, the WebRequest/ResponseAPI, webhooks - Proxy (formerly Middleware) — running code before routing: redirects, rewrites, headers
- Authentication Patterns — sessions, cookies, Auth.js and a data access layer
- Databases with an ORM — Drizzle ORM with SQLite, schemas, queries and migrations
- URL State & Search Params — filters, sorting and pagination that live in the URL
- Project — Full-Stack Task Manager — CRUD with Drizzle + SQLite, validated Server Actions, and an end-to-end test
Before you start¶
- Finish Level 1, or be comfortable with layouts, Server/Client Components and
asyncdata fetching in pages. - Levels 2's database lessons use SQLite through
better-sqlite3, which runs as a local file — no database server or account needed. On some systems npm asks you to approve the package's install script (it compiles or downloads a native binary); approve it forbetter-sqlite3only. - A basic grasp of HTTP (methods, status codes, cookies, headers) helps a lot. The REST API Mastery Path covers it if you need a refresher.
Version-sensitive topics in this level
Two areas here changed significantly across recent versions: caching (lesson 04) and Middleware → Proxy (lesson 06). Both lessons state which version each behaviour applies to. If you maintain a Next.js 14 or 15 app, read those lessons' "what changed" notes carefully before applying code from them.