Skip to main content

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
nextjs#nextjs#react#ssr#csr+3 more

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

December 5, 2024
4 min read
~800 words

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:

ApproachAnalogy
Server-SideSend an envelope with the complete message. They open it and find the content ready. โœ…
Client-SideSend 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?

ScenarioWhy Client-Side?
User-specific data (after login)Data varies per user
Rapidly changing contentReal-time updates needed
Not important for SEOSearch engines don't need it
Interactive contentFiltering, 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?

ScenarioWhy Server-Side?
Ready data on first loadBetter perceived performance
SEO-important contentSearch engines see full content
Faster first visitNo loading spinners
Shareable pagesEveryone 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 CaseRecommendation
๐Ÿ›๏ธ Public products pageSSR or SSG
๐Ÿ’ฌ Comments after loginClient
๐Ÿ“Š User dashboard (no SEO)Client
๐Ÿ’ฐ Pricing page (updates hourly)SSG + ISR
๐Ÿ“ Blog postsSSG
๐Ÿ” Search resultsClient (with URL params)
๐Ÿ›’ Shopping cartClient

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

  1. SEO matters? โ†’ Server-Side
  2. User-specific? โ†’ Client-Side
  3. First impression matters? โ†’ Server-Side
  4. Real-time updates? โ†’ Client-Side
  5. 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

#nextjs#react#ssr#csr#data-fetching#seo#performance

Found this article helpful?

Share it with your network and help others learn too!

Mohammad Alhabil

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.