In React client apps, you've probably written fetch inside useEffect and managed a separate loading state. In a Server Component, you can just make the component async, await the data, and ship ready-made HTML straight away.
The mental model
A Server Component runs on the server before anything reaches the browser, so it's safe to use API keys and database connections there. fetch doesn't automatically throw for a 404 or 500, so you need to check response.ok yourself. And calling your data source directly — instead of your own Server Component making an HTTP call back to your own Route Handler — is faster and plays nicer at build time.
Let's build it together
type Note = { id: string; title: string };
async function getNotes(): Promise<Note[]> {
const response = await fetch("https://api.example.com/notes");
if (!response.ok) throw new Error("မှတ်စုများ ယူမရပါ");
return response.json();
}
export default async function NotesPage() {
const notes = await getNotes();
return (
<ul>
{notes.map((note) => <li key={note.id}>{note.title}</li>)}
</ul>
);
}How the code works
getNotes types the response and checks for errors. The page only renders the list once the data comes back. Keeping the API URL in one function makes it easy to swap the source later.
Note titles fetched on the server show up as an HTML list.5-Minute Try-It
Fetch data from a public API, check response.ok, and show at least two fields as a card.
Next.js — Fetching Data — Next.js