Client Components

Understand Client Components in Next.js — when to use them, how they interact with Server Components, and how to keep your client bundle lean.

Last reviewed: January 2025

·Next.js 13.4+Next.js 14Next.js 15
✅
Quick Understanding: Client Components are React components that run in the browser. They are identical to components in traditional React apps — they can use hooks, handle events, and access browser APIs. Add "use client" at the top of the file to mark a component as a Client Component.

🔍 What Is It?

Client Components in Next.js are components that:

  • →Run in the browser (and also on the server during SSR for the initial HTML)
  • →Can use React hooks — useState, useEffect, useContext, custom hooks
  • →Can handle events — onClick, onChange, onSubmit
  • →Can access browser APIs — window, document, localStorage, navigator
  • →Are marked with 'use client' — a directive at the top of the file

'use client' marks a boundary in the component tree. The component and everything it imports becomes part of the client bundle.

🎯 Why Do We Need It?

Server Components cannot handle interactivity. Anything that requires:

  • →User input (typing, clicking, selecting)
  • →State that changes over time (open/closed, count, form values)
  • →Browser-specific APIs (geolocation, clipboard, localStorage)
  • →Real-time updates (WebSocket, polling)
  • →Third-party client libraries (charts, maps, rich text editors)

...must be a Client Component. The goal is to use Client Components for the minimum interactive surface area of your UI, keeping everything else as Server Components.

🏗️ What Happens in Real Projects?

Typical Client Components in a production app:

  • →SearchBar — controlled input with state
  • →AddToCartButton — onClick handler + optimistic UI
  • →MobileNav — open/close toggle state
  • →ThemeToggle — localStorage + state
  • →DataTable — sorting, filtering, pagination state
  • →RealtimeFeed — WebSocket subscription
  • →DatePicker — complex UI state

The pattern: Server Components fetch data and pass it as props to Client Components. Client Components handle the interactive layer on top of that data.

⚙️ How It Works

Client Component rendering:

  1. SSR phase — Client Components also render on the server for the initial page load, producing HTML. This is why you see content immediately even for interactive components.
  2. Hydration — the browser downloads the JS bundle, React 'hydrates' the server-rendered HTML (attaches event listeners, initialises state)
  3. Client-side rendering — subsequent re-renders happen entirely in the browser

The `'use client'` directive:

  • →Must be at the very top of the file, before any imports
  • →Marks the file and all its imports as client-side
  • →Creates a serialisation boundary — props must be serialisable

💻 Example

Client Component Patterns — Real patterns for keeping Client Components lean and composing them with Server Components.

tsx
'use client'; // Must be first line

import { useState } from 'react';

export function AddToCartButton({ productId }: { productId: string }) {
  const [loading, setLoading] = useState(false);
  const [added, setAdded] = useState(false);

  const handleClick = async () => {
    setLoading(true);
    await fetch('/api/cart', {
      method: 'POST',
      body: JSON.stringify({ productId }),
    });
    setLoading(false);
    setAdded(true);
  };

  return (
    <button onClick={handleClick} disabled={loading}>
      {added ? '✓ Added' : loading ? 'Adding...' : 'Add to Cart'}
    </button>
  );
}

🤔 Common Confusions

❓ Do Client Components only run in the browser?

No — Client Components also run on the server during SSR to generate the initial HTML. "Client Component" means it CAN run in the browser (and ships JS to do so). The distinction is: Server Components ONLY run on the server and never ship JS. Client Components run on both.

❓ Can a Client Component import a Server Component?

No — this would break the server-only guarantee. If a Client Component imports a Server Component, Next.js automatically converts it to a Client Component. The only way to use a Server Component inside a Client Component is to pass it as children or props from a Server Component parent.

❓ Does "use client" mean the component is not server-rendered?

No. "use client" means the component ships JavaScript to the browser and can be interactive. It still server-renders on the first request for fast initial HTML. The difference from Server Components: it also hydrates and re-renders in the browser.

🚨 Common Production Issues

Bundle bloat from large Client Component imports — importing a heavy library (e.g., a chart library) in a Client Component ships it to all users. Use dynamic import with { ssr: false } to lazy-load heavy Client Components.

Hydration mismatches — if a Client Component renders differently on server vs client (e.g., using Math.random() or Date.now() without care), React throws a hydration error. Always ensure server and client render the same initial HTML.

Context providers inflating the client boundary — wrapping the entire app in a Client Component context provider unnecessarily pulls everything into the client bundle. Create thin provider wrapper components.

✅ Best Practices

Push "use client" as far down the component tree as possible — keep the interactive surface minimal

Use dynamic import for heavy Client Components that are not needed on initial load

Pass Server Components as children to Client Components — they still render on the server

Keep Client Components focused on interactivity — extract static parts into Server Component children

Avoid putting data fetching logic in Client Components when a Server Component parent can fetch and pass the data

🏛️ Architect's Note

Senior Architect's Perspective

The Server/Client split is the most important architectural decision in every Next.js App Router project. A useful mental model: Server Components are your read layer, Client Components are your interaction layer.

The goal is to minimise the client bundle. Every kilobyte of JavaScript has a cost: download time, parse time, execution time. On mobile networks, a 500KB JS bundle can delay interactivity by 3–5 seconds. By keeping most of your UI in Server Components, you ship only the JS that is genuinely needed for interactivity.

💬 Frequently Asked Questions

How do I use a third-party library that requires "use client"?

Create a wrapper component with "use client" at the top, import the library there, and export a clean interface. This contains the client boundary to just the wrapper. Example: wrap a date picker library in a DatePicker.tsx with "use client", then use DatePicker in Server Components.

Can I use useEffect in a Client Component for data fetching?

You can, but it is not recommended in Next.js. useEffect data fetching causes a waterfall (render → mount → fetch → re-render) and misses SSR. Use Server Components for data fetching instead. If you need client-side fetching, use SWR or TanStack Query which handle caching and revalidation properly.

What is the maximum size a client bundle should be?

Aim for under 200KB (gzipped) for the initial bundle. Next.js automatically code-splits per route, so this is per-page, not the entire app. Use next build --analyze (with @next/bundle-analyzer) to visualise what is in your bundle.

🎯 Key Takeaways

1"use client" marks the boundary — the file and all its imports become part of the client bundle
2Client Components run on both server (SSR) and browser — they are not browser-only
3Use Client Components only for interactivity — state, events, browser APIs
4Pass Server Components as children to Client Components to keep server rendering benefits
5Push the "use client" boundary as deep as possible to minimise bundle size
6Hydration mismatches happen when server and client render different HTML — avoid non-deterministic values

🎯 Practice this topic in interviews

↗ Where this topic fits

Sources

Sources / References

Use these Next.js references to verify the concept in official docs and continue into the most relevant SplashRide pages.

Related SplashRide pages

SplashRide Next.js learning path

Browse the full Next.js topic collection and learning order on SplashRide.

Next.js Interview Prep

Practice Next.js interview questions and scenario-based answers.

Frontend Engineer Career Path

A beginner-friendly journey through web foundations, React, production frontend engineering, and interview preparation.

Full Stack Java Developer Career Path

A guided route through frontend foundations, Java backend engineering, delivery workflows, and interview readiness.

Server Components

Master React Server Components in Next.js — the paradigm that lets components run exclusively on the server, fetch data directly, and ship zero JavaScript to the browser.

Next.js App Router Explained: Server Components, Layouts, and Routing

Learn the Next.js App Router with Server Components, nested layouts, streaming, Route Handlers, data fetching, and Pages Router migration guidance.