Client-side Component

Framework Next.js 13 Client-side Component

Create the client-side component

The component is always be the server-side component by default. If you want a client-side component then you have to add "use client" directive on the top of the component file.

The "use client" directive must be defined at the top of a file before any imports.

// app/ClientSideComponent.js
'use client';

import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

"use client" does not need to be defined in every file. The Client module boundary only needs to be defined once, at the “entry point”, for all modules imported into it to be considered a Client component.

Client side js bundle file

All other modules imported into it, including child components, are considered part of the client bundle.

Client side js bundle file

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.

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

// Layout is a Server Component by default
export default function Layout({ children }) {
  return (
    <>
      <nav>
        <LogoServerComponent />
        <SearchBarClientComponent />
      </nav>
      <main>{children}</main>
    </>
  );
}

Move the interactive logic to a Client Component (e.g. <SearchBar />) 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.

Component-level Client and Server Rendering

Importing Server Components into Client Components

Treat the server components as a child component

1. Create Client Component

'use client';

export default function ClientComponent({children}) {
  return (
    <>
      {children}
    </>
  );
}

2. Set the server component as the child component

import ClientComponent from "./ClientComponent";
import ServerComponent from "./ServerComponent";

// Pages are Server Components by default
export default function Page() {
  return (
    <ClientComponent>
      <ServerComponent />
    </ClientComponent>
  );
}

Treat the server components as a props

1. Set the server component as the props of the client component

import ClientComponent from "./ClientComponent";
import ServerComponent from "./ServerComponent";

// Pages are Server Components by default
export default function Page() {
  return (
    <ClientComponent ServerComponent={ServerComponent}>
  );
}

2. Disploy Server Component in the Client Component

'use client';

export default function ClientComponent({
  children,
  ServerComponent,
}) {
  return (
    <>
      {ServerComponent}
    </>
  );
}

Keeping Server-Only Code out of Client Components

The environment variable API_KEY is not prefixed with NEXT_PUBLIC, it’s a private variable that can only be accessed on the server.

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

  return res.json();
}

Protect your server only code

To use server-only, first install the package:

npm install server-only

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

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();
}

Data Fetching

Although it’s possible to fetch data in Client Components, we recommend fetching data in Server Components unless you have a specific reason for fetching data on the client. Moving data fetching to the server leads to better performance and user experience.

Reference