Fetching Data on the Server

Load data directly inside an async Server Component with await fetch — no useEffect, no loading flash, and your API keys stay safe.

Step 1 of 2

Server Components can fetch data directly

In the Data Fetching module you fetched data in the browser with useEffect and managed loading and error states by hand. In Next.js, a Server Component can be async and simply await the data before it renders.

Because this runs on the server, the page arrives at the browser already filled with data — no spinner flash, and search engines see the real content. And since the fetch code never reaches the browser, you can use secret API keys safely.

export default async function Page() {
  const res = await fetch("https://api.vercel.app/blog");
  const posts = await res.json();
  // ...render posts
}

That's the whole pattern: mark the component async, await your data, render it. No hooks required.

Think of it this way: Client-side fetching (the old way) is like getting an empty plate, then waiting at the table while the kitchen cooks. Server fetching is like the meal arriving fully plated — the work happened in the kitchen (server) before it ever reached you.
Web Standard

Only Server Components can be async and await data this way. A Client Component ("use client") can't — it still fetches in the browser, using useEffect or a library. So put your data fetching in Server Components whenever you can.

Tip — caching changed in Next.js 16

In Next.js 16, fetch results are not cached by default — each request gets fresh data. When you want to store a result and reuse it, you opt in with the use cache directive. For now, the default (always fresh) is the simplest thing to learn.

Learn more on MDN
TYPESCRIPTREAD ONLY