guideEdit this page

Client components

When you need interactivity on the client side, you can use client components. Client components will be also rendered on the server side, but the client component will be hydrated on the client side.

All client components will be loaded asynchronously, so they will not block the rendering of the page. All client component will be compiled into an ES module and get lazy loaded only when needed.

To create a client component, add the "use client"; pragma at the top of the file.

"use client";

export default function MyClientComponent() {
  return <p>This is a client component</p>;
}

Client components can use any React hooks, like the useState hook and can attach event handlers to elements like onClick. The client components are rendered both on the server side and on the client side.

"use client";

import { useState } from "react";

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

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

Client components can receive props from server components. The props will get serialized and passed to the client. All props passed to a client component must be serializable. You can pass any primitive values, arrays and objects, but functions are not allowed.

"use client";

export default function MyClientComponent({ name }) {
  return <p>Hello {name}</p>;
}

Using the above client component from a server component:

import MyClientComponent from "./MyClientComponent";

export default function MyServerComponent() {
  return <MyClientComponent name="John" />;
}

You can also wrap server components into client components. This is very useful when you want to use a server component inside a client component, like a React Context provider. The context will be available in all child client components. As the context is created only on the client, server components will not have access to the context.

"use client";

import { createContext } from "react";

const MyContext = createContext("unknown");

export default function MyProvider({ name, children }) {
  return <MyContext.Provider value={name}>{children}</MyContext.Provider>;
}
import MyProvider from "./MyProvider";

export default async function MyServerComponent() {
  const name = await getUserName();
  return (
    <MyProvider name={name}>
      <p>Hello {name}</p>
    </MyProvider>
  );
}

You can make a component client-only by wrapping the component into a ClientOnly component. Children of the ClientOnly component will be rendered only on the client side.

import { ClientOnly } from "@lazarv/react-server/client";

export default function MyServerComponent() {
  return (
    <div>
      <p>This is rendered on the server side</p>
      <ClientOnly>
        <p>This is rendered on the client side</p>
        <MyClientComponent />
      </ClientOnly>
    </div>
  );
}