Client-Side vs Server-Side Fetching: When to Use Each in Next.js

Client-Side vs Server-Side Fetching: When to Use Each in Next.js
Should you fetch data from the client or the server? The decision isn't simple, but it's not complicated if you understand the full picture.
Mohammad Alhabil
Author
Client-Side vs Server-Side Fetching: When to Use Each in Next.js
In every React or Next.js project, you face the same dilemma:
Should I fetch data from the client? Or from the server?
The decision isn't simple... but it's not complicated if you understand the full picture.
Let's clarify it in the simplest way, with logic that makes the decision clear in any situation.
The Two Options
Every time a user visits a page, you have two choices:
1. Client-Side Fetching (CSR)
Fetch data from the browser using useEffect, useSWR, or React Query.
// The page appears first, then data arrives
useEffect(() => {
fetch('/api/products')
.then(res => res.json())
.then(setProducts);
}, []);
2. Server-Side Fetching (SSR)
Fetch data on the server using getServerSideProps or fetch inside a Server Component.
// Next.js App Router - Server Component
async function ProductsPage() {
const products = await fetch('https://api.example.com/products');
return <ProductList products={products} />;
}
The page reaches the user ready with the data.
A Real-World Analogy ๐ฌ
Imagine you want to send a message to your friend:
| Approach | Analogy |
|---|---|
| Server-Side | Send an envelope with the complete message. They open it and find the content ready. โ |
| Client-Side | Send an empty envelope with a note: "Wait, we'll send the content later." โณ |
With server-side, the content is there immediately. With client-side, they sit and wait... and maybe the message is delayed, or the internet cuts out.
When to Use Client-Side Fetching?
| Scenario | Why Client-Side? |
|---|---|
| User-specific data (after login) | Data varies per user |
| Rapidly changing content | Real-time updates needed |
| Not important for SEO | Search engines don't need it |
| Interactive content | Filtering, infinite scroll, live search |
Example: User Dashboard
'use client';
function Dashboard() {
const { data, isLoading } = useQuery({
queryKey: ['user-stats'],
queryFn: () => fetch('/api/user/stats').then(r => r.json())
});
if (isLoading) return <Skeleton />;
return <StatsDisplay data={data} />;
}
When to Use Server-Side Fetching?
| Scenario | Why Server-Side? |
|---|---|
| Ready data on first load | Better perceived performance |
| SEO-important content | Search engines see full content |
| Faster first visit | No loading spinners |
| Shareable pages | Everyone sees the same content |
Example: Products Page
// Server Component - No 'use client'
async function ProductsPage() {
const products = await fetch('https://api.example.com/products', {
next: { revalidate: 3600 } // ISR: Revalidate every hour
});
return (
<div>
{products.map(product => (
<ProductCard key={product.id} product={product} />
))}
</div>
);
}
Practical Decision Guide
| Use Case | Recommendation |
|---|---|
| ๐๏ธ Public products page | SSR or SSG |
| ๐ฌ Comments after login | Client |
| ๐ User dashboard (no SEO) | Client |
| ๐ฐ Pricing page (updates hourly) | SSG + ISR |
| ๐ Blog posts | SSG |
| ๐ Search results | Client (with URL params) |
| ๐ Shopping cart | Client |
Common Misconception โ ๏ธ
Many people think:
"I'm fetching data from an API" = "I must use Client Fetch"
Wrong!
With Next.js App Router, you can fetch inside a Server Component:
// This runs on the SERVER, not the client!
async function Page() {
const data = await fetch('https://api.example.com/data');
return <Component data={data} />;
}
This gives you:
- โก Speed โ Data ready on first paint
- ๐ SEO โ Search engines see content
- ๐ฆ Smaller JS โ Less client-side code
The Hybrid Approach
Often, the best solution is combining both:
// Server Component - Initial data
async function ProductsPage({ searchParams }) {
const initialProducts = await fetch(`/api/products?page=1`);
return (
<div>
{/* Client Component for interactivity */}
<ProductFilters />
{/* Server-rendered initial data */}
<ProductList initialData={initialProducts} />
</div>
);
}
Key Takeaways
- SEO matters? โ Server-Side
- User-specific? โ Client-Side
- First impression matters? โ Server-Side
- Real-time updates? โ Client-Side
- Shareable URL? โ Server-Side
The user experience starts from the first byte from the server.
Start understanding the UI, not just building it.
Interfaces you love, code you understand. ๐ก
Topics covered
Found this article helpful?
Share it with your network and help others learn too!

Written by Mohammad Alhabil
Frontend Developer & Software Engineer passionate about building beautiful and functional web experiences. I write about React, Next.js, and modern web development.
