Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
The App Router  ›  Lesson

Server Components

Rendering Pages 14 minIn the App Router components are server components by default: they run only on the server, can be async and read data directly, and send no component code to the browser.

Server Components

Trailhead's trail page reads from a database using a connection string that must never leak. In a classic React app, anything a component touches ends up in the browser bundle, so you would have to build a separate API just to hide it. In the App Router the component itself can stay on the server.

The rule

In app, components run on the server unless you say otherwise.

Every component in the App Router is a React Server Component by default. That means:

  • It runs only on the server: at build time for static routes, or per request for dynamic ones.
  • It can be async and await data directly: a database query, a file read, a fetch with a secret key.
  • Its code is not sent to the browser. The browser receives the rendered HTML plus a compact description of the output (the RSC payload), not the component's JavaScript.
// app/trails/[slug]/page.tsx (a server component: no directive needed)
import { db } from "@/lib/db";          // uses process.env.DATABASE_URL
import { marked } from "marked";        // a Markdown library

export default async function TrailPage({ params }) {
  const { slug } = await params;
  const trail = await db.trail.findUnique({ where: { slug } });
  return (
    <article>
      <h1>{trail.name}</h1>
      <div dangerouslySetInnerHTML={{ __html: marked(trail.notes) }} />
    </article>
  );
}

Neither the database client, the connection string nor the Markdown library reaches the visitor. (Here trail.notes is written by Trailhead's own editors; never render untrusted HTML this way.)

The price: because a server component never runs in the browser, it cannot:

  • hold state or run effects (useState, useEffect, useReducer),
  • attach event handlers (onClick, onChange),
  • use browser-only objects (window, document, localStorage),
  • use React context as a provider or consumer.

Those jobs belong to client components, the next lesson.

The shortcut

For each component, ask "Does it need to react to the visitor in the browser?" Clicks, typing, state, animations, browser storage: it must be a client component. Only showing data, even data loaded with secrets: keep it a server component.

Sorting Trailhead's trail pageStep 1 of 4
  1. TrailHeader (name, distance, photo)

    Only shows data. Server component.

The trap is adding useState to a server component and being puzzled by the error. The error is right: state needs the browser. Move that piece into a client component.

Drills

Answer fast — trust the rule.

quick drill

In the App Router, what is a component with no directive?

quick drill

Which can a server component do?

quick drill

What does the browser receive from a server component?

quick drill

Why is a heavy Markdown library cheaper inside a server component?

Remember

  • In app, components run on the server unless you say otherwise; they can be async and use secrets.
  • Shortcut: "does it react to the visitor in the browser?" If not, keep it on the server.
  • Trap: state, effects, event handlers and browser objects do not work in server components.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainWhat stays on the server

Trailhead's trail page queries the database using a secret connection string and shows the result. Explain why a server component is the right home for this, and name two things this component is not allowed to do.