A production-grade study plan for developers with a React and JavaScript foundation who want to master React Server Components, Server Actions, TypeScript, secure APIs, and modern deployment architecture.
App RouterRSCServer ActionsTypeScriptEnterprise
Architecture & enterprise project structure
Modern Next.js applications need an explicit separation between Server Components, Client Components, Server Actions, and Route Handlers. This typed structure is the reference architecture used throughout the curriculum.
Boundary rule Keep secrets and database utilities on the server. Add 'use client' only where browser APIs, hooks, or event handlers require it. Serialize props across the boundary.
Daily rhythm: spend 5–10 minutes on the architecture concept, then 15–20 minutes implementing one typed drill. On Day 7, complete the weekly quiz before reviewing the answers.
Build a reliable foundation in the RSC paradigm, file-system routing, nested layouts, loading UI, streaming, and boundary isolation.
Module 1.1 · Server vs. Client Component boundaries
RSCs are the default in app/; they execute on the server without shipping their component JavaScript to the browser.
Use 'use client' for state, effects, event listeners, and browser APIs. Keep server-only modules protected with import 'server-only'.
Practice: typed Counter, a client CardWrapper that accepts Server Components as children, a server-rendered dashboard, server-only database utilities, and serialized UserDTO props.
// components/client/counter.tsx
'use client';
import { useState } from 'react';
export function Counter({ initialCount }: { initialCount: number }) {
const [count, setCount] = useState(initialCount);
return ;
}
Module 1.2 · Advanced routing and nested layouts
Layouts preserve state across sibling navigation; route groups organize code without changing the URL.
Practice root metadata and fonts, dashboard layouts, typed dynamic segments such as [category]/[productId], catch-all docs routes, and parallel slots @analytics and @metrics.
Module 1.3 · Streaming, loading UI, and error isolation
loading.tsx creates a Suspense boundary for streaming fallbacks; error.tsx isolates runtime failures and provides reset().
Practice route skeletons, granular Suspense around slow analytics, global-error.tsx, and not-found.tsx.
Weekly review
What happens when server-only database code is imported into a Client Component?
Why does a layout retain state during sibling navigation?
Does 'use client' automatically make every child component client code?
How does loading.tsx enable streaming?
Why must error.tsx be a Client Component?
Graduation project · Product Inventory Catalog
Build a Tailwind dashboard with a root layout, a dashboard sidebar, parallel analytics and metrics routes, a Suspense-streamed slow widget, and an isolated mock database error boundary. Evaluation: architecture 40%, routing 30%, error handling 30%.
Weeks 4–6 · Level 2
Data fetching, caching & Server Actions
Learn the difference between request memoization and persistent Data Cache behavior, then build type-safe mutations with secure invalidation.
Module 2.1 · Fetching and cache strategy
Use next.revalidate for time-based freshness, next.tags for targeted invalidation, and cache: 'no-store' for live stock or other request-time data.
Use React cache() to deduplicate a database read within one render pass; use segment exports such as revalidate = 300 and dynamic = 'force-dynamic' intentionally.
export async function getProductById(id: string) {
const res = await fetch(`/api/products/${id}`, {
next: { tags: [`product-${id}`, 'products'] },
});
if (!res.ok) throw new Error('Failed to fetch product');
return res.json();
}
Module 2.2 · Server Actions and form mutations
Server Actions are secure server-side functions invoked by forms or client transitions, but their inputs still require authentication, authorization, and schema validation.
Practice Zod validation with useActionState, optimistic todo updates with useOptimistic, revalidatePath, and pending states with useTransition.
'use server';
import { revalidateTag } from 'next/cache';
import { z } from 'zod';
const Product = z.object({ title: z.string().min(3), price: z.number().positive() });
export async function createProductAction(_: unknown, formData: FormData) {
const result = Product.safeParse({
title: formData.get('title'),
price: Number(formData.get('price')),
});
if (!result.success) return { error: result.error.flatten().fieldErrors };
// Authenticate, authorize, then insert into the database.
revalidateTag('products');
return { success: true };
}
Weekly review
How do Request Memoization and Data Caching differ?
How does revalidateTag('products') affect tagged fetches?
What security checks belong inside every exported Server Action?
What does useActionState contribute to a form?
What becomes stale after revalidatePath('/dashboard')?
Build tagged data fetches, a Zod-validated inventory mutation, optimistic item addition, and tag revalidation. Evaluation: data integrity 40%, caching strategy 30%, user experience 30%.
Weeks 7–9 · Level 3
Auth, proxy/middleware & API integration
Protect enterprise routes, propagate tenant context, handle Web Platform requests, and verify incoming webhooks without weakening the boundary.
Module 3.1 · Session guards and security headers
Use proxy/middleware before route resolution to inspect sessions, redirect unauthenticated dashboard requests, inject tenant headers, and apply security response headers.
Read and set cookies with cookies(); use httpOnly, secure, sameSite, an explicit path, expiry, and server-side session validation.
Practice typed GET query handling, Zod-validated POST bodies, raw-body HMAC signature verification, CORS response headers, and a streaming ReadableStream.
Webhook verification must consume the exact raw request text before parsing; byte-for-byte fidelity is required for the signature check.
Weekly review
What runtime constraints apply to middleware?
Why must a webhook verify the raw body?
How do headers injected by middleware reach a Route Handler?
How does a middleware redirect differ from a Server Action redirect?
How does httpOnly protect a session cookie from XSS access?
Protect dashboard and admin routes, inject tenant context, validate payment webhooks, implement an HttpOnly session flow, and enforce role-based permissions. Evaluation: security 40%, middleware precision 30%, API standards 30%.
Weeks 10–12 · Level 4
Performance, testing & enterprise deployment
Finish with measurable Core Web Vitals, lean production images, dependable end-to-end coverage, and a modern development toolchain.
Module 4.1 · Web Vitals and built-in optimizations
Use next/image with dimensions or fill and correct sizes to reduce CLS; use next/font for optimized fonts and next/script strategies for third-party code.
Use next/dynamic with ssr: false for browser-only heavy charts and choose static or dynamic segment configuration deliberately.
Configure output: 'standalone' and use a multi-stage Node 20 Alpine container: install, build, copy .next/standalone and .next/static, then run node server.js.
Write Playwright E2E assertions for dashboard rendering and streamed widgets, Vitest tests for Server Action validation, and a Turbopack dev script.
Combine every level into a high-throughput enterprise system with strict boundaries, secure multi-region routing, resilient data mutations, and an observable deployment.
ArchitectureApp Router with clean Server/Client separation and zero server-secret leakage.