/layout.js @ 1732206458609 [Home]

Server Components as Children of Client Components

This is a Client-Side Component and this is its {children}:
Server Component content
JSX
<ClientComponent> <ServerComponent/> </ClientComponent>
ClientComponent.js
'use client'
export const ClientComponent = ({children}) => {
  return <div className={"box client-component"}>
    This is a Client-Side Component and this is its {"{children}"}:
    {children}
  </div>
}
ServerComponent.js
export const ServerComponent = ()=><div className={"box"}>Server Component content</div>;

But how can a client component contain a server component?

This might be confusing at first, so let's clarify exactly what's happening:

  1. The server runs ServerComponent at request-time, on the server
  2. The ClientComponent is inserted into the Virtual DOM as a client component with its code split into its own js file
  3. In the Virtual DOM, the ClientComponent's {children} property is set to the static generated content of the ServerComponent output
  4. When the ClientComponent runs in the browser, it simply inserts its {children} content.
  5. The ClientComponent doesn't care whether its {children} began as static content or was generated by RSC!

Mental Model

ClientComponent doesn't need to run ServerComponent!

ClientComponent doesn't know anything about what's inside of it. It just gets passed a {children} property and can insert the content into its output. It knows nothing about its {children}.

To render itself, ClientComponent doesn't need to run or render its {children}!

ClientComponent constructs a box, and is handed what to put in the box via {children}. The creation of the box itself can happen regardless of what's being put in it. The two are independent.

What if ClientComponent wants to control a ServerComponent at run-time?

Maybe ClientComponent wants to use state, and depending on that state render ServerComponent differently.

This is not possible! Here's why...

Importing Server Components into Client Components