Aug. 8, 2025
4 min read
Ever stared at a component in your Next.js project and asked yourself, “Should this be a client or a server component?” Yeah, we’ve all been there. With the introduction of App Router in Next.js and the big push toward server components, things have changed a lot.
But don’t worry. This post will walk you through what Client and Server Components actually are, when to use each, and how to dodge some common mistakes (hydration errors, anyone?). Let’s break it down.

What is a Server Component?
Server components are the default in Next.js App Router. They run only on the server, never get sent to the browser as JavaScript, and can directly fetch data or talk to your database.
Benefits:
- No JavaScript shipped to the client
- Faster load times
- Built-in data fetching
- Great for SEO
Good use cases:
- Rendering blog posts or product pages
- Pulling data from a CMS or database
- Static content that doesn’t need interaction
// Server component by default
export default function BlogPost({ params }) {
const post = await getPost(params.slug);
return <div>{post.title}</div>;
}
What is a Client Component?
Client components run in the browser, just like you’re used to in React. They’re needed for things that require interactivity or state changes (useState, useEffect, etc.).
To mark a component as a client component, you use the magic line at the top:
"use client"
Good use cases:
- Buttons, modals, sliders
- Form inputs
- Tabs, dropdowns
- useEffect logic (e.g., localStorage, animations)
Real-Life Example
Let’s say you’re building a product page.
- The product description? Server Component. It’s static data.
- The “Add to Cart” button? Client Component. It changes state and maybe interacts with local storage.
- A reviews section? Depends. If it’s just showing reviews → Server. If users can upvote or leave comments → Client.
Common Mistakes to Avoid
1. Too many client components
It’s tempting to sprinkle "use client"
everywhere. Don’t. Client components send JavaScript to the browser, which affects performance.
Think of
"use client"
as adding a little weight to your site.
2. Client inside Server is okay
You can safely import a client component inside a server component. For example, you can render a server-side blog post and include a like button (client component) inside it.
// BlogPost.server.tsx
import LikeButton from './LikeButton' // client component
export default function BlogPost({ post }) {
return (
<article>
<h1>{post.title}</h1>
<LikeButton />
</article>
);
}
3. Server inside Client is wrong
You can’t import a server component into a client one. It’ll throw an error. Server components aren’t meant to run in the browser.
Hydration Nightmares?
You’ll probably see this error at some point:
“Text content did not match. Server: ‘Hello’ Client: ‘Hi’”
This means your Client Component rendered something different on the server vs. the browser. Most times, it’s caused by using useEffect
or useState
wrong, or by accessing browser-only APIs like window
during render.
Fix: Make sure your code behaves the same on the server and the client, or wrap browser-only stuff in useEffect
.
Final Thoughts
Server and Client components in Next.js give you fine control over performance and interactivity. The goal isn’t to choose just one; it’s to mix them wisely.
TL;DR:
- Use Server components by default
- Reach for Client components when you need interactivity
- Avoid overusing
"use client"
- Always wrap client bits inside server components, not the other way around
Once you get used to this pattern, you’ll start writing faster, cleaner apps without shipping unnecessary JavaScript to users. And that’s a win!.