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
Dr. Tommie Stoltenberg PhD's avatar

Dr. Tommie Stoltenberg PhD

Direct Mobility Supervisor

Lester Labadie's avatar

Lester Labadie

Principal Data Engineer

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
Jesse Kshlerin's avatar

Jesse Kshlerin

Forward Creative Strategist

Christian Murray's avatar

Christian Murray

Direct Directives Assistant

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
Dave Kovacek's avatar

Dave Kovacek

National Assurance Agent

Samuel Hills's avatar

Samuel Hills

National Interactions Technician

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
Katrina Yost III's avatar

Katrina Yost III

Direct Directives Associate

Dr. Joan Raynor's avatar

Dr. Joan Raynor

Human Program Designer

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.