We can overcome boundaries by interweaving client and server components. Interweaving means we also pass components around rather than just importing them.

Remember, network boundaries are created based on imports, not based on ancestors. This means that any component type can be the parent or child of any other component type.

server
node.js

I am a server component

Async Data
server
node.js
Jennifer Herman's avatar

Jennifer Herman

District Applications Technician

Faye Howe PhD's avatar

Faye Howe PhD

Forward Brand Liaison

shared
node.js

Hi, shared component here. Take note of my environment.

We can pass Server Components "through" child Client Components without creating a network boundary:

client
node.js

I can do client things: 0

Import
shared
node.js

Hi, shared component here. Take note of my environment.

Children
shared
node.js

Hi, shared component here. Take note of my environment.

Async Data
server
node.js
Amos Hills's avatar

Amos Hills

Direct Operations Facilitator

Manuel Kozey's avatar

Manuel Kozey

Legacy Communications Associate

A more complex example, passing a Server Component as a prop and deeply nesting:

client
node.js

I can do client things: 0

Prop
Async Data
server
node.js
Mr. Rudy Hickle's avatar

Mr. Rudy Hickle

Chief Identity Administrator

Jeff Cummerata III's avatar

Jeff Cummerata III

Product Functionality Liaison

Import
shared
node.js

Hi, shared component here. Take note of my environment.

Children
shared
node.js

Hi, shared component here. Take note of my environment.

Nested Client
client
node.js

I can do client things: 0

Import
shared
node.js

Hi, shared component here. Take note of my environment.

Children
Async Data
server
node.js
Jody Jakubowski's avatar

Jody Jakubowski

Direct Mobility Producer

Mrs. Freda Cole's avatar

Mrs. Freda Cole

Regional Factors Director

Interweaving Server Components
// default server network boundary

// because these are IMPORTED here...
import ServerAsync from "./serverAsync";
import Shared from "./shared";

import Client from "./client";

export default function Page() {
return (
<div>
<p>I am a server component</p>
<ServerAsync />
<Shared />
{/* despite being children */}
{/* of a Client Component */}
<Client>
{/* they remain in the current */}
{/* server network boundary */}
<ServerAsync />
<Shared />
</Client>
{/* we can pass also components as props */}
{/* just like they are children */}
<Client header={<ServerAsync />} />
</div>
);
}
Interweaving Client Component
"use client"; // client network boundary

// because the shared component is imported here...
import Shared from "./shared";

export default function Client({
children,
header,
}: {
children?: React.ReactNode;
header?: React.ReactNode;
}) {
return (
<div>
{/* it is turned into a client component */}
<Shared />
{/* but the same component passed as a prop */}
{/* will remain a server component */}
{header && <h2>{header}</h2>}
{children}
</div>
);
}
Next, let's find out how to share context between server and client components.