Section 1: Foundations of the App Router
How the App Router thinks
The App Router is built on React Server Components. By default, every component inside the app directory runs on the server. It can read from a database, call internal services and use secret keys, and only the resulting UI is sent to the browser. No JavaScript for that component is shipped to the client.
When a component needs interactivity, such as state, effects or event handlers, you mark the file with "use client" at the top. That file and everything it imports become part of the client bundle. The component still renders on the server first for the initial HTML, then hydrates in the browser.
A mental model that helps
Think of your page as a tree. The upper parts, like layouts and pages, are usually server components that fetch data. The leaves, like a like button or a search box, are client components that handle interaction. Data flows down from server to client as props, and those props must be serialisable: plain objects, arrays, strings, numbers, dates and promises, but not functions or class instances.
Server Components can render Client Components, and pass them server components as children. A Client Component cannot import a Server Component directly, because by then you are already in client code.
Files with special meaning
Inside a route folder, certain file names have a job:
page.tsxis the UI for that URLlayout.tsxwraps pages and stays mounted across navigationloading.tsxshows while the page is streamingerror.tsxcatches errors in that segmentroute.tsdefines an HTTP endpoint instead of a page
Why this matters for Shelf
Our book list page will query PostgreSQL directly inside a server component. There is no API layer to write for it and no loading spinner on first visit, because the HTML arrives with the data already in it. The "save book" button, however, needs to respond to clicks, so it will be a small client component.
In the next lesson we create the project and look at the generated files.