Importing Server Components into Client Components
Server and Client Components can be interleaved in the same component tree. Behind the scenes, React will merge the work of both environments.

However, in React, there's a restriction around importing Server Components inside Client Components because Server Components might have server-only code (e.g. database or filesystem utilities).

For example, importing a Server Component in a Client Component will not work:

app/ClientComponent.js
'use client';

// ❌ This pattern will not work. You cannot import a Server
// Component into a Client Component
import ServerComponent from './ServerComponent';

export default function ClientComponent() {
 return (
 <>
 
 </>
 );
}
Instead, you can pass a Server Component as a child or prop of a Client Component. You can do this by wrapping both components in another Server Component. For example:

app/ClientComponent.js
'use client';

export default function ClientComponent({children}) {
 return (
 <>
 {children}
 </>
 );
}
app/page.js
// ✅ This pattern works. You can pass a Server Component
// as a child or prop of a Client Component.
import ClientComponent from "./ClientComponent";
import ServerComponent from "./ServerComponent";

// Pages are Server Components by default
export default function Page() {
 return (
 
 
 
 );
}
With this pattern, React will know it needs to render on the server before sending the result (which doesn't contain any server-only code) to the client. From the Client Component's perspective, its child will be already rendered.

This pattern is already applied in layouts and pages with the children prop so you don't have to create an additional wrapper component.

Passing props from Server to Client Components (Serialization)
Props passed from the Server Components to Client components need to be serializable. This means that values such as functions, Dates, etc, cannot be passed directly to client components.

Where is the Network Boundary?

In the app directory, the network boundary is between Server Components and Client Components. This is different from the pages directory where the boundary is between getStaticProps/getServerSideProps and Page Components. Data fetched inside Server Components do not need to be serialized as it doesn't cross the network boundary unless it is passed to a Client Component. Learn more about data fetching with Server Components.

Keeping Server-Only Code out of Client Components (Poisoning)
Since JavaScript modules can be shared between both Server and Client Components, it's possible for code that was only ever intended to be run on the server to sneak its way into the client.

For example, take the following data-fetching function:

lib/data.js
export async function getData() {
 let res = await fetch("https://external-service.com/data", {
 headers: {
 authorization: process.env.API\_KEY,
 },
 });

 return res.json();
}
At first glance, it appears that getData works on both the server and the client. But because the environment variable API\_KEY is not prefixed with NEXT\_PUBLIC, it's a private variable that can only be accessed on the server. Next.js replaces private environment variables with the empty string in client code to prevent leaking secure information.

As a result, even though getData() can be imported and executed on the client, it won't work as expected. And while making the variable public would make the function work on the client, it would leak sensitive information.

So, this function was written with the intention that it would only ever be executed on the server.

To prevent this sort of unintended client usage of server code, we can use the server-only package to give other developers a build-time error if they ever accidentally import one of these modules into a Client Component.

To use server-only, first install the package:

npm install server-only
Then import the package into any module that contains server-only code:

lib/data.js
import "server-only";

export async function getData() {
 let resp = await fetch("https://external-service.com/data", {
 headers: {
 authorization: process.env.API\_KEY,
 },
 });

 return resp.json();
}
Now, any Client Component that imports getData() will receive a build-time error explaining that this module can only be used on the server.

The corresponding package client-only can be used to mark modules that contain client-only code – for example, code that accesses the window object.

Moving Client Components to the Leaves
To improve the performance of your application, we recommend moving Client Components to the leaves of your component tree where possible.

For example, you may have a Layout that has static elements (e.g. logo, links, etc) and an interactive search bar that uses state.

Instead of making the whole layout a Client Component, move the interactive logic to a Client Component (e.g. ) and keep your layout as a Server Component. This means you don't have to send all the component Javascript of the layout to the client.

app/layout.js
// SearchBar is a Client Component
import SearchBar from './SearchBar';
// Logo is a Server Component
import Logo from './Logo';

// Layout is a Server Component by default
export default function Layout({ children }) {
 return (
 <>
 

{children}
 </>
 );
}
Third-party packages
The "use client" directive is a new React feature that was introduced as part of Server Components. Since Server Components are so new, third-party packages in the ecosystem are just beginning to add it to components that use client-only features like useState, useEffect and createContext.

Today, many components from npm packages that use client-only features do not yet have the directive. These third-party components will work as expected within your own Client Components, since they themselves have the "use client" directive, but they won't work within Server Components.

For example, let's say you've installed the hypothetical acme-carousel package which has an component. This component uses useState, but it doesn't yet have the "use client" directive.

If you use within a Client Component, it will work as expected:

app/gallery.js
'use client';

import { useState } from 'react';
import { AcmeCarousel } from 'acme-carousel';

export default function Gallery() {
 let [isOpen, setIsOpen] = useState(false);

 return (
 
 setIsOpen(true)}>View pictures

 {/\* 🟢 Works, since AcmeCarousel is used within a Client Component \*/}
 {isOpen && }
 
 );
}
However, if you try to use it directly within a Server Component, you'll see an error:

app/page.js
import { AcmeCarousel } from 'acme-carousel';

export default function Page() {
 return (
 
 View pictures

 {/\* 🔴 Error: `useState` can not be used within Server Components \*/}
 
 
 );
}
This is because Next.js doesn't know is using client-only features.

To fix this, you can wrap third-party components that rely on client-only features in your own Client Components:

app/carousel.js
'use client';

import { AcmeCarousel } from 'acme-carousel';

export default AcmeCarousel;
Now, you can use directly within a Server Component:

app/page.js
import Carousel from './carousel';

export default function Page() {
 return (
 
 View pictures

 {/\* 🟢 Works, since Carousel is a Client Component \*/}
 
 
 );
}
We don't expect you to need to wrap most third-party components since it's likely you'll be using them within Client Components. However, one exception is provider components, since they rely on React state and context, and are typically needed at the root of an application. Learn more about third-party context providers below.
서버 컴포넌트를 클라이언트 컴포넌트로 임포트하기서버 컴포넌트와 클라이언트 컴포넌트는 동일한 컴포넌트 트리에서 인터리빙될 수 있습니다. 백그라운드에서 React는 두 환경의 작업을 병합합니다.하지만 서버 컴포넌트에는 서버 전용 코드(예: 데이터베이스 또는 파일시스템 유틸리티)가 있을 수 있기 때문에 React에서는 클라이언트 컴포넌트 내부에서 서버 컴포넌트를 임포트하는 데 제한이 있습니다.예를 들어, 클라이언트 컴포넌트에서 서버 컴포넌트를 가져오는 것은 작동하지 않습니다:app/ClientComponent.js'사용 클라이언트';// ❌ 이 패턴은 작동하지 않습니다. 서버 컴포넌트를 클라이언트 컴포넌트로 가져올 수 없습니다.// 컴포넌트를 클라이언트 컴포넌트로 임포트할 수 없습니다.'./ServerComponent'에서 ServerComponent를 가져옵니다;export default 함수 ClientComponent() { return ( <>  </> );}대신 서버 컴포넌트를 클라이언트 컴포넌트의 자식이나 프로퍼티로 전달할 수 있습니다. 두 컴포넌트를 다른 서버 컴포넌트로 래핑하면 됩니다. 예를 들어app/ClientComponent.js'클라이언트 사용';내보내기 기본 함수 ClientComponent({children}) { 반환 ( <> {children} </> );}app/page.js// ✅ 이 패턴이 작동합니다. 서버 컴포넌트를 전달할 수 있습니다.//를 클라이언트 컴포넌트의 자식이나 프로퍼티로 전달할 수 있습니다."./ClientComponent"에서 ClientComponent를 임포트합니다;"./ServerComponent"에서 ServerComponent를 임포트합니다;// 페이지는 기본적으로 서버 컴포넌트입니다.export default 함수 Page() { return (    );}이 패턴을 사용하면 React는 서버 전용 코드가 포함되지 않은 결과를 클라이언트에 전송하기 전에 서버에서 렌더링해야 한다는 것을 알 수 있습니다. 클라이언트 컴포넌트의 관점에서 보면 그 자식은 이미 렌더링되어 있을 것입니다.이 패턴은 자식 프로퍼가 있는 레이아웃과 페이지에 이미 적용되어 있으므로 래퍼 컴포넌트를 추가로 만들 필요가 없습니다.서버에서 클라이언트 컴포넌트로 프롭 전달하기(직렬화)서버 컴포넌트에서 클라이언트 컴포넌트로 전달되는 프로퍼티는 직렬화가 가능해야 합니다. 즉, 함수, 날짜 등과 같은 값은 클라이언트 컴포넌트에 직접 전달할 수 없습니다.네트워크 바운더리는 어디에 있나요?앱 디렉토리에서 네트워크 경계는 서버 컴포넌트와 클라이언트 컴포넌트 사이입니다. 이는 페이지 디렉터리에서 getStaticProps/getServerSideProps와 페이지 컴포넌트 사이에 경계가 있는 것과는 다릅니다. 서버 컴포넌트 내부에서 가져온 데이터는 클라이언트 컴포넌트로 전달되지 않는 한 네트워크 경계를 넘지 않으므로 직렬화할 필요가 없습니다. 서버 컴포넌트를 사용한 데이터 불러오기에 대해 자세히 알아보세요.서버 전용 코드를 클라이언트 컴포넌트에서 제외하기(포이즌)자바스크립트 모듈은 서버와 클라이언트 컴포넌트 모두에서 공유할 수 있기 때문에 서버에서만 실행되어야 하는 코드가 클라이언트로 몰래 들어갈 수 있습니다.예를 들어 다음 데이터 불러오기 함수를 살펴보겠습니다:lib/data.jsexport async 함수 getData() { let res = await fetch("https://external-service.com/data", { headers: { authorization: process.env.API\_KEY, }, }); 반환 res.json();}언뜻 보기에 getData는 서버와 클라이언트 모두에서 작동하는 것처럼 보입니다. 하지만 환경 변수 API\_KEY의 접두사 앞에 NEXT\_PUBLIC이 붙지 않기 때문에 서버에서만 액세스할 수 있는 비공개 변수입니다. Next.js는 보안 정보 유출을 방지하기 위해 클라이언트 코드에서 비공개 환경 변수를 빈 문자열로 대체합니다.따라서 클라이언트에서 getData()를 가져와 실행할 수 있지만 예상대로 작동하지 않습니다. 또한 변수를 공개로 설정하면 클라이언트에서 함수가 작동하지만 민감한 정보가 유출될 수 있습니다.따라서 이 함수는 서버에서만 실행되도록 의도적으로 작성되었습니다.클라이언트가 서버 코드를 의도치 않게 사용하는 것을 방지하기 위해 서버 전용 패키지를 사용하면 다른 개발자가 실수로 이러한 모듈 중 하나를 클라이언트 컴포넌트로 임포트하는 경우 빌드 시 오류가 발생할 수 있습니다.서버 전용을 사용하려면 먼저 패키지를 설치합니다:npm 설치 서버 전용그런 다음 서버 전용 코드가 포함된 모듈로 패키지를 임포트합니다:lib/data.jsimport "server-only";export async 함수 getData() { let resp = await fetch("https://external-service.com/data", { headers: { authorization: process.env.API\_KEY, }, }); 반환 resp.json();}이제 getData()를 임포트하는 모든 클라이언트 컴포넌트는 이 모듈이 서버에서만 사용할 수 있음을 설명하는 빌드 타임 오류를 받게 됩니다.해당 패키지 클라이언트 전용을 사용하여 클라이언트 전용 코드(예: 창 객체에 액세스하는 코드)가 포함된 모듈을 표시할 수 있습니다.클라이언트 컴포넌트를 나뭇잎으로 이동애플리케이션의 성능을 개선하려면 가능한 경우 클라이언트 컴포넌트를 컴포넌트 트리의 잎으로 이동하는 것이 좋습니다.예를 들어 정적 요소(예: 로고, 링크 등)가 있는 레이아웃과 상태를 사용하는 대화형 검색창이 있을 수 있습니다.전체 레이아웃을 클라이언트 컴포넌트로 만드는 대신 인터랙티브 로직을 클라이언트 컴포넌트(예: )로 이동하고 레이아웃은 서버 컴포넌트로 유지하세요. 즉, 모든 컴포넌트를 자바스크립트 컴포넌트로 보낼 필요가 없습니다.