Day 7 overview
Take your Reading List to production with Next.js, Server Components, Server Functions, an accessibility pass, and a real deploy.
For six days your React code has run in one place: the browser. That is a great way to learn, but real apps also need a server. Something has to store data, keep secrets out of the browser, send fast HTML on the first load, and put the app on the internet.
Today you hand those jobs to a framework. The React team recommends starting new apps with one, and the most widely used is Next.js. You will port the Reading List to the Next.js App Router, so some components run on the server and read data directly. A form will call a function that runs on the server. Then you will make sure everyone can use the app, deploy it to a public URL, and plan what to build next.
Next.js apps need a real server and a file system, so they can't run inside the in-page sandboxes. Today most code appears as static, highlighted files that you type into a project on your own computer. Where a concept is plain React (a Client Component, a form, an accessibility fix), you still get a live sandbox.
Time plan
| Lesson | Time | What you'll do |
|---|---|---|
| Next.js and the App Router | 50 min | Create a Next.js app, learn file-based routing, layouts, links and dynamic routes |
| Server and Client Components | 60 min | Read data on the server, decide where 'use client' goes, stream with Suspense |
| Server Functions | 50 min | Add books with 'use server', useActionState and revalidatePath |
| Data and caching | 40 min | Understand static vs dynamic, try 'use cache', turn on the React Compiler |
| Accessibility | 50 min | Labels, real buttons, alt text, focus, aria-live, and lint rules |
| Deploy to Vercel | 30 min | Build for production and ship it from GitHub or the CLI |
| What's next | 20 min | Recap the week, pick a capstone, and choose what to read next |
That is about five hours. If you run short on time, deploy first and do the accessibility pass afterwards. A deployed app you can share is a great motivator.
What you'll build today
By the end of today the Reading List will:
- run as a Next.js app, with
app/page.tsxas a Server Component that reads books fromlib/books.ts; - have a detail page at
/books/[id], built byapp/books/[id]/page.tsx; - add books through a Server Function called
addBookinapp/actions.ts, called from a Client Component form; - refresh the list after each change with
revalidatePath('/'); - pass an accessibility review: labelled inputs, real buttons, visible focus, a skip link and announced status messages;
- live at a public
vercel.appURL.
Today's lessons
Next.js and the App Router
Folders become URLs. Layouts, links, and dynamic routes.
Server and Client Components
Which code runs where, and how to draw the line.
Server Functions
Call server code from a form, then refresh the page.
Data and caching
Static shells, streaming, 'use cache', and the React Compiler.
Accessibility
Make the app work for keyboards and screen readers.
Deploy to Vercel
From your laptop to a public URL.
What's next
Recap, capstone ideas, and the best resources to keep going.
Port the Reading List to Next.js
This is the full Day 7 version of the project. Each lesson builds one part of it and explains the decisions, so if something here looks new, that lesson is where it is explained. You can also come back to this section at the end of the day and check your files against it.
Create the project
Open a terminal in the folder where you keep your projects and run:
npx create-next-app@latest reading-list-next --yes
cd reading-list-nextThe --yes flag accepts the recommended defaults: TypeScript, ESLint, Tailwind CSS, the App Router, and Cache Components. You need Node.js 20.9 or newer.
Turn on the React Compiler
You turned the compiler on for the Vite app on Day 6. Next.js has a built-in switch for it, but it needs the Babel plugin installed:
npm install -D babel-plugin-react-compilerThen edit next.config.ts to match the file in the tabs below.
Add the files
Create or replace each file in the tabs below. Delete anything else the starter put in app/page.tsx, and replace the whole of app/globals.css, including the Tailwind import, with the version here. Create the lib and components folders at the project root, next to app.
Run it
npm run devOpen http://localhost:3000. Add a book, change a status, open a book's detail page, then press Tab from the top of the page and check that you can reach and use everything with the keyboard.
export type Status = 'want' | 'reading' | 'done';
export interface Book {
id: string;
title: string;
author: string;
status: Status;
rating?: number;
}
export const statusLabels: Record<Status, string> = {
want: 'Want to read',
reading: 'Reading',
done: 'Done',
};
// What the addBook Server Function sends back to the form.
export type FormState = {
error: string | null;
message: string | null;
};When everything works, commit the project to GitHub and follow the Deploy to Vercel lesson to put it online.
Day 7 progress