Home
NextJS
Next.js: Data Fetching
December 09, 2025
3 min

Table Of Contents

01
Client-Side Fetching (CSR): The Traditional Way
02
Server-Side Fetching With Server Components (SSR)
03
HMR Cache: Why Your Data Doesn’t Update in Dev Mode
04
Why Server-Side Fetching Is Better
05
But You Can Still Use Client-Side Fetching
06
Test It Yourself
07
Conclusion

Data fetching in Next.js is one of the most important and exciting concepts developers encounter when building modern React applications. In Next.js, you can fetch content in multiple ways—but not all strategies are equal in performance, simplicity, or SEO value.

This article breaks down the difference between client-side data fetching (CSR) and server-side data fetching (SSR), shows code examples, explains how Next.js optimizes server fetching, and highlights why server components have become the new standard.


Client-Side Fetching (CSR): The Traditional Way

If you’re coming from plain React, you’re familiar with this pattern:

  1. Create state to store your data
  2. Use useEffect to fetch the data
  3. Update the state
  4. Render the UI based on that state

Here’s what it typically looks like:

"use client";
import { useEffect, useState } from "react";
export default function Home() {
const [albums, setAlbums] = useState([]);
useEffect(() => {
async function fetchAlbums() {
const res = await fetch("https://jsonplaceholder.typicode.com/albums");
const data = await res.json();
setAlbums(data);
}
fetchAlbums();
}, []);
return (
<div>
{albums.map((album) => (
<p key={album.id}>{album.title}</p>
))}
</div>
);
}

This works—but it’s not optimal.

Why client-side fetching falls short

  • The page loads blank until data arrives
  • It adds extra JavaScript bundle weight
  • Poor for SEO—crawlers may not “see” the data
  • Requires more boilerplate (useState, useEffect)
  • Prone to network waterfalls
  • Exposes API keys or sensitive client-facing logic

There’s a better way.


Server-Side Fetching With Server Components (SSR)

Next.js lets you fetch data directly inside server components—no useEffect, no state, and no client-side logic required.

Here’s the cleaner version:

export default async function Home() {
const res = await fetch("https://jsonplaceholder.typicode.com/albums");
if (!res.ok) throw new Error("Failed to fetch");
const albums = await res.json();
return (
<div>
{albums.map((album) => (
<p key={album.id}>{album.title}</p>
))}
</div>
);
}

Notice the difference?

  • No useEffect
  • No useState
  • No client-side JavaScript needed
  • Cleaner code
  • Faster initial load
  • Fully SEO-friendly HTML

HMR Cache: Why Your Data Doesn’t Update in Dev Mode

If you test server-side fetching locally, you might notice something odd: You need to refresh the browser to see new results.

This isn’t a bug.

Next.js now includes Server Components HMR Cache:

  • It caches server fetch results during development
  • Faster hot reloads
  • Fewer API calls
  • Smoother DX (Developer Experience)

So if you update your fetch URL or API, refresh manually.


Why Server-Side Fetching Is Better

Here are the biggest benefits of choosing server-side data fetching:


1. Faster Initial Load (Improved FCP)

SSR allows the page to load with the data already baked into the HTML. Users see content immediately. No waiting for JavaScript to run.


2. Better SEO

Search engines can read server-rendered HTML. Client-side fetching often means crawlers see… nothing.

If SEO matters, avoid CSR whenever possible.


3. Cleaner Logic + Fewer Hooks

No state. No effects. No unnecessary re-renders.

Server components keep data logic closer to the backend.


4. Automatic Request Deduplication

Next.js automatically ensures that:

If multiple components request the same data at the same time, only one API request is made.

Huge performance win.


5. Better Security

API keys, private tokens, or sensitive logic stay on the server. Nothing leaks to the browser or user.


6. Reduced Network Waterfall

CSR often triggers multiple sequential requests. SSR can fetch everything in parallel before rendering.

You’ll learn parallel fetching later in the course—but trust me, it’s powerful.


7. Direct Database Calls

Since server components run on the server:

  • Prisma
  • Mongoose
  • MongoDB
  • SQL queries
  • External API calls
  • Internal microservices

…can be called directly, with no API routes in between.

Example:

import prisma from "@/lib/prisma";
export default async function Posts() {
const posts = await prisma.post.findMany();
return <pre>{JSON.stringify(posts, null, 2)}</pre>;
}

No API layer needed.


But You Can Still Use Client-Side Fetching

Just add:

"use client";

…and you’re back to traditional React.

CSR is still useful for:

  • User interactions
  • Search bars
  • Filters
  • Dashboards
  • Real-time updates

…but it should NOT be your default for static or SEO-sensitive pages.


Test It Yourself

Try building both versions:

  1. CSR with useEffect
  2. SSR with a server component

Then compare:

  • Initial page render

  • View page source (CSR will show nothing)

  • Disable JavaScript and reload

    • CSR breaks
    • SSR continues to show your data

You’ll immediately understand why server components are the future of React + Next.js.


Conclusion

Next.js encourages a new mindset:

The server is your friend. Fetch there. Render there.

It’s cleaner, faster, more secure, and far better for SEO.

Client-side fetching still has its place—but it should no longer be your default.

If you’re new to these concepts or transitioning from React, don’t worry: everyone used CSR at first. With practice, server components and server-side data fetching will feel natural.


If you’d like, I can also turn this blog into:

✅ Prezi content slides ✅ A 4-section concise slide version ✅ Infographics ✅ Real-world examples comparing CSR and SSR ✅ Graphics or illustrations

Just tell me!


Tags

#tailwindcss

Share

Related Posts

Crash Course
Next.js: Build Adapters API
December 13, 2025
2 min
© 2025, All Rights Reserved.
Powered By

Social Media

githublinkedinyoutube