Course outline · 0% complete

0/29 lessons0%

Course overview →

Two kinds of components

lesson 3-1 · ~9 min · 7/29

The previous lesson, Layouts and navigating with Link, explained why Link beats a plain anchor for internal navigation, and that idea carries straight into this unit.

Link swaps only the changing page content and can prefetch the target ahead of the click. A plain anchor reloads the whole document and remounts every layout, destroying whatever state those layouts held. Link performs client-side navigation instead, keeping layouts and their state alive.

Notice what that implies: some of your code is running in the browser after the first load, and some of it is not. This unit is about drawing that line deliberately.

The split

In Unit 1 you saw that Next.js runs components on the server first. Unit 3 makes that precise, and precision is worth it here. This split decides how much JavaScript your users download, which is the main thing that makes web apps feel slow, and it decides which of your code is allowed near secrets and databases. It is the distinction Next.js code reviews argue about most.

In the app directory there are two kinds of React components:

  • Server components (the default). They run only on the server. Their JavaScript is never sent to the browser, only the HTML they produce.
  • Client components. They render on the server for the initial HTML, then hydrate and keep running in the browser. Anything interactive from the React course, useState, useEffect, onClick, lives here.

Every component in app/ is a server component until you say otherwise. You opt a file into the client world by putting the directive "use client" on its first line.

What each side can do

CapabilityServer componentClient component
useState, useEffect, onClick
async/await data directly in the body
Read secrets, env vars, databases
Ships its JS to the browser✗ (HTML only)

Read the last row twice. A page built mostly from server components sends almost no JavaScript, which is the performance win. And because server component code never leaves the server, it can safely hold API keys and query a database, like your Express handlers did in Backend with Node.js.

ServerServer componentsClient componentsBrowserHTML (readable)JS + hydrationHTMLJSServer components send HTML only · client components also send their JS
The mental model: server components render to HTML that travels once. Client components additionally ship JavaScript so they can stay alive in the browser.

Counting the JavaScript in a real bundle

Take a page built from 20 server components and 1 client component. The only component code that reaches the browser is that single client component, plus React itself and the framework runtime.

The 20 server components contribute finished HTML and zero bundle JavaScript. Their source never leaves the server, so the browser has nothing to download, parse, or execute for them. The one client component's code does get downloaded and hydrated, because it needs to keep running to handle clicks and state.

This ratio is exactly why defaulting to server components keeps pages fast. A page can be visually rich and still ship almost nothing, as long as the interactive surface is small.