Server Fetching
Overview
Next.js extends the native fetch API to allow you to configure caching and revalidation directly on the server. Because Server Components support async/await, fetching data is incredibly straightforward without needing custom hooks or lifecycle methods.
Syntax
export default async function Page() {
// 1. Force Cache (SSG equivalent - default behavior)
const staticData = await fetch('https://api.com/data', { cache: 'force-cache' });
// 2. No Store (SSR equivalent - dynamic)
const dynamicData = await fetch('https://api.com/data', { cache: 'no-store' });
// 3. Revalidate (ISR equivalent)
const isrData = await fetch('https://api.com/data', { next: { revalidate: 3600 } });
return <div>{/* Render data */}</div>;
}Common Pitfalls
Using
useEffectfor data fetching when you could just make the Server Componentasync.Forgetting that multiple
fetchcalls to the same endpoint in different components are automatically deduped by Next.js.
Interview Questions
How does Next.js 14+ handle deduplication of fetch requests on the server?
Next.js automatically memoizes fetch requests that have the same URL and options within a single render pass. If three components fetch the same API, the network request is only made once.
Real-World Example
Fetching blog posts and caching them for 1 hour to handle high traffic efficiently.
export default async function Blog() {
const res = await fetch('https://my-cms.com/api/posts', {
next: { revalidate: 3600 } // Revalidates every hour
});
const posts = await res.json();
return (
<ul>
{posts.map(post => <li key={post.id}>{post.title}</li>)}
</ul>
);
}Check Your Knowledge
Test your understanding of Server Fetching with these quick questions.