Skip to content

The Children Pattern

The children prop is deceptively simple — it's just "whatever was nested inside this component's JSX tag" — but it is the mechanism that makes layouts, templates, and Server/Client composition all work. This lesson focuses on it directly.

children Is How Layouts Render Pages

Every layout component receives a children prop, and Next.js is responsible for deciding what that value actually is: for a route's immediate layout.tsx, children is either the next nested layout or, at the innermost level, the matching page.tsx. You never pass children to a layout explicitly — Next.js wires it up automatically based on the current route.

This is exactly the same children prop you'd use in plain React when writing <Card><p>Hello</p></Card> — Next.js just supplies the value for you at the routing level instead of you writing it in JSX yourself.

// app/layout.tsx
export default function RootLayout({
  children, // Next.js supplies this automatically based on the current route
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

Visiting any route in the app renders that route's page (and any layouts in between) as this layout's children.

children in Plain React vs. Next.js Layouts

// Plain React — you control children explicitly
<Card>
  <p>Hello</p>
</Card>

// Next.js layout.tsx — Next.js supplies children based on routing
export default function Layout({ children }) {
  return <div>{children}</div>;
}
  • children is a standard React prop, not a Next.js-specific API.
  • In JSX, whatever is nested between a component's opening and closing tags becomes its children.
  • For layouts, Next.js decides the value of children based on the current route, automatically.
  • children can be any valid React node: an element, a string, an array of elements, or null.

children Pattern Cheat Sheet

Where children comes from in different contexts.

Context What children Is
Plain React component Whatever JSX was nested inside its tag
Root layout.tsx The next matching layout or page for the route
Nested layout.tsx The next deeper layout, template, or page
Custom Client shell (e.g. <Modal>) Whatever Server or Client content was passed in

children vs. Named Slots (Parallel Routes)

children is the default, unnamed slot every layout receives. Next.js also supports named "slots" via parallel routes (folders prefixed with @, like @analytics), letting a layout receive multiple independent content areas beyond just children. This advanced pattern is covered fully in the Parallel Routes lesson later in the course.

Using children in Your Own Components

Beyond layouts, children is the standard way to write flexible, composable components throughout your Next.js app — the same technique you'd use in any React project.

// components/Panel.tsx
export default function Panel({
  title,
  children,
}: {
  title: string;
  children: React.ReactNode;
}) {
  return (
    <section>
      <h2>{title}</h2>
      {children}
    </section>
  );
}

// usage
<Panel title="Details | PHPKINGDOM">
  <p>Some server-rendered content here.</p>
</Panel>

Common Mistakes

  • Forgetting to render {children} in a custom layout, silently hiding every nested route.
  • Assuming children is a Next.js-specific concept rather than standard React.
  • Trying to pass multiple distinct content areas through a single children prop instead of using parallel routes.
  • Not typing children as React.ReactNode in TypeScript, causing type errors when passing arrays or fragments.

Key Takeaways

  • children is a standard React prop representing nested JSX content.
  • Next.js automatically supplies children to layouts based on the current route.
  • The same prop enables Client Components to receive server-rendered content for composition.
  • Named "slots" beyond children are possible via parallel routes for more advanced layouts.
  • Understanding children deeply clarifies almost every composition pattern in the App Router.

Pro Tip

Whenever a layout, template, or custom wrapper component isn't rendering what you expect, check first whether it's actually rendering {children} somewhere in its JSX — a missing {children} reference is one of the most common (and easiest to miss) bugs in App Router layouts.