Client Components in Next.js are rendered in the browser and enable interactive, stateful UI behavior.
- Executed on the client using JavaScript.
- Support state management and user interactions.
- Differ from server components, which render on the server.
In Next.js, adding the "use client" directive at the top of a file marks the component for client-side rendering, enabling browser-based interactivity.
'use client'
import { useState } from 'react';
export default function Counter() {
const [active, setActive] = useState(false);
return (
<>
// Your code here
</>
);
}
Features of Client Components
- State Management: Use React hooks like useState and useEffect to manage state and side effects.
- Event Handling: Handle user interactions such as clicks, form submissions, and other events directly within the component.
- Client-Side Data Fetching: Fetch data from client-side APIs or other sources that are not available on the server.
- Dynamic Imports: Use dynamic imports to load Client Components only when needed, optimizing performance.
Rendering of Client components
Client Components in Next.js render differently on initial page load versus client-side navigation to optimize performance.
- On initial load or refresh, the full component is rendered.
- On internal navigation, only changed parts are updated.
- Avoids full page reloads for better performance.
Full Page Load
To improve initial load performance, Next.js pre-renders both Client and Server Components on the server, delivering fully rendered HTML to users immediately and reducing wait time.
On the Server:
- Rendering: React creates an RSC payload from Server Components with Client Component references.
- HTML Generation: Next.js uses the payload to generate the final HTML on the server.
On the Client:
- Initial Display: Server-rendered HTML shows a fast, non-interactive preview.
- Page Update: RSC payload helps React sync Server and Client Components.
- Interactivity: Client Components are hydrated with JavaScript to enable interactions.
Subsequent Navigations
This approach allows for smooth, seamless transitions between pages without the need for a full page reload. Once the initial page has loaded, Next.js manages any further navigations directly on the client:
- Client-Side Rendering: After the initial load, page updates are handled entirely in the browser using Client Components
- JavaScript Execution: The browser downloads and runs the required JavaScript for dynamic rendering
- Reconciliation: React uses the RSC Payload to keep Client and Server Component trees in sync and update the DOM correctly
Going back to the Server Environment
Even within Client Components, Next.js allows switching back to the server for specific tasks to optimize performance and reduce client-side overhead.
- Mix Client and Server Components within the same application.
- Use Server Components for data fetching and server-only APIs.
- Reduce client bundle size and improve performance.
- Maintain a responsive UI using Client Components and Server Actions.
Steps to Implement Client Components
Here are the steps to implement client components:
Step 1: Create a new Next.js project
npx create-next-app next-js-client-demo
cd next-js-script-demo
Step 2: Install dependencies (if not already installed)
npm install next react react-domFolder Structure

Dependencies
"dependencies": {
"next": "latest",
"react": "latest",
"react-dom": "latest"
}
Example: We have created a counter component to demonstrate how client components in Next.js can manage state and handle user interactions directly in the browser.
// page.js
"use client";
import ClientComponent from "./ClientComponent";
export default function Home() {
return (
<div>
<h1>Welcome to Next.js Client Components</h1>
<ClientComponent />
</div>
);
}
// ClientComponent.js
import { useState } from 'react';
export default function ClientComponent() {
const [count, setCount] = useState(0);
return (
<div>
<h1>Client Component</h1>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
To start the application run the following command.
npm run devOutput
