The mental model
Next.js gets easier once you stop treating it as a list of APIs and start following where work runs, what crosses the network, and what becomes interactive in the browser.
React describes the UI. Next.js coordinates the application.
React gives you components and a model for describing interfaces. Next.js adds the application around them: routing, server rendering, Server Components, data access, caching, request handling, asset optimisation, metadata, and build output.
The App Router is server-first. That does not mean every request renders the whole page on a server. It means code stays on the server unless the browser has a reason to own it.
Follow one request
A visitor opens /projects. The router matches the URL to folders inside app, then combines the matching layouts and page into a component tree. Server Components can load data while that tree is rendered.
For the first visit, the browser receives HTML it can display plus React Server Component data that React uses to understand the server-rendered tree. Client Component JavaScript is loaded for the parts that actually need browser behaviour.
After that initial response, navigation can happen without replacing the whole document. Shared layouts stay mounted while the router fetches what the next route needs.
- The URL chooses route segments.
- Layouts compose the persistent shell.
- Server Components do server-side work.
- HTML gives the browser something useful to display immediately.
- The RSC payload describes the server-rendered result and client references.
- Client JavaScript hydrates the interactive boundaries.
A request from URL to interaction
Three questions solve most architecture choices
Before reaching for a directive or configuration option, decide what the feature actually needs. Most App Router decisions become much less mysterious after that.
- Where must this code run: server, browser, or either?
- How fresh must the result be: build-time, reusable for a while, or request-specific?
- Does the user need to interact with it after the initial render?
A Next.js app does not need one rendering mode
Do not label an entire application as static or dynamic too early. A mostly static page can contain a dynamic region. A dynamic route can reuse cached work. A slow section can stream without delaying the rest of the page.
Think about the smallest useful boundary: route, component, query, or mutation.
Can you explain “The mental model” without reaching for the API reference?
Describe the main trade-off, one failure mode, and the decision you would make in a real project.