Data Fetching
Server Components can be async functions — you can
await a database call or an API request directly inside the
component.
Example: fetching and rendering a list
export default async function PostsPage() {
const res = await fetch("https://api.example.com/posts");
const posts = await res.json();
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
Because this component runs on the server, not in the browser, the
fetch call — and the credentials or private URLs it might
need — never has to be exposed to the client at all. Compare this to
plain React, where you'd typically need a separate useEffect
plus useState just to load the same data after the
component first renders; here, the data is already resolved by the time
the HTML reaches the browser at all, which also means there's no
"loading..." flash for this particular content.
export default async function PostsPage() {
const res = await fetch("https://api.example.com/posts");
const posts = await res.json();
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
Renders a bulleted list of post titles, fetched fresh on the server before the page is sent to the browser.