RSC Boundary

Examples

Each pattern below mixes Server Component modules (no "use client") with Client Components. Blue and orange outlines on this page are static illustrations (same colors as the real devtools)—they are not fiber-based detection. Add RscBoundaryProvider to your app and run next dev for the interactive pill, panel, and live highlights.

Server-only block

A small module that renders only on the server, with no client children. The outline mimics an explicit server region; the code uses RscServerBoundaryMarker so development devtools can pick up the same label.

Server (explicit): ExampleServerOnly

Server-only subtree

This card is a separate module with no client components inside. With RscBoundaryProvider in development, this region appears as an explicit server entry in the devtools panel.

components/examples/server-static-block.tsx
// components/examples/server-static-block.tsx
import { RscServerBoundaryMarker } from "rsc-boundary";

export function ServerStaticBlock() {
  return (
    <RscServerBoundaryMarker label="ExampleServerOnly">
      <div className="rounded-xl border ...">{/* server-only content */}</div>
    </RscServerBoundaryMarker>
  );
}

Server shell + counter island

The demo component is defined in a server file: an explicit marker wraps the shell; static copy sits next to a client Counter.

Server (explicit): ExampleServerShellCounter

Server Component shellthis paragraph and the container are from a file without "use client". Only the controls below are a client boundary.

Client: Counter
Count: 0
components/examples/server-counter-demo.tsx
// components/examples/server-counter-demo.tsx
import { RscServerBoundaryMarker } from "rsc-boundary";
import { Counter } from "./counter";

export function ServerCounterDemo() {
  return (
    <RscServerBoundaryMarker label="ExampleServerShellCounter">
      <div className="...">
        <p>Server Component shell — static copy here.</p>
        <Counter />
      </div>
    </RscServerBoundaryMarker>
  );
}

Server data + accordion (client)

FAQ items are authored in the server module; only the accordion UI is client-side for open/close state.

Server (explicit): ExampleServerAccordion

FAQ entries are plain data in this server file and passed as props into Accordion (client). Open/close state is client-side.

Client: Accordion
This route mixes server-rendered copy and structure with several client islands. Toggle the RSC pill to see orange around interactive pieces and blue around static server output.
components/examples/server-accordion-demo.tsx
// components/examples/server-accordion-demo.tsx
import { RscServerBoundaryMarker } from "rsc-boundary";
import { Accordion } from "./accordion";

const FAQ_ITEMS = [/* ... */];

export function ServerAccordionDemo() {
  return (
    <RscServerBoundaryMarker label="ExampleServerAccordion">
      <div className="space-y-3">
        <p className="text-sm text-muted">...</p>
        <Accordion items={FAQ_ITEMS} />
      </div>
    </RscServerBoundaryMarker>
  );
}

Server list + client filter

The searchable list source is defined on the server; filtering runs in the client without a round trip.

Server (explicit): ExampleServerSearch

The array SERVER_RENDERED_ITEMS is defined in this server module. The filter input narrows results on the client without a round trip.

Client: SearchFilter
  • use server — layout shell
  • Static docs paragraph
  • List item: Server Component A
  • List item: Server Component B
  • List item: hydration boundary ahead
components/examples/server-search-demo.tsx
// components/examples/server-search-demo.tsx
import { RscServerBoundaryMarker } from "rsc-boundary";
import { SearchFilter } from "./search-filter";

const SERVER_RENDERED_ITEMS = [/* ... */] as const;

export function ServerSearchDemo() {
  return (
    <RscServerBoundaryMarker label="ExampleServerSearch">
      <div className="space-y-3">
        <p className="text-sm text-muted">...</p>
        <SearchFilter items={SERVER_RENDERED_ITEMS} />
      </div>
    </RscServerBoundaryMarker>
  );
}

Explicit + heuristic regions

The first block uses a marker; the second has no marker so development devtools can show a ~ heuristic region. Below, the static outlines show both styles side by side.

Server (explicit): DocsHero

Explicit markerwrapped with RscServerBoundaryMarker. The devtools panel lists this as explicit in development.

Server (~): Heuristic shell

Heuristic-only shell (~)no marker on this block; devtools infer server regions around static copy in development. Prefer explicit markers when you need a stable label.

Client: Counter
Count: 0
components/examples/server-hybrid-demo.tsx
// components/examples/server-hybrid-demo.tsx
import { RscServerBoundaryMarker } from "rsc-boundary";
import { Counter } from "./counter";

export function ServerHybridDemo() {
  return (
    <div className="space-y-4">
      <RscServerBoundaryMarker label="DocsHero">{/* ... */}</RscServerBoundaryMarker>
      <div className="rounded-xl border ...">
        <p>Heuristic-only shell</p>
        <Counter />
      </div>
    </div>
  );
}