← Next.js tutorial

Next.js

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.

Example
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>
  );
}
Output
Renders a bulleted list of post titles, fetched fresh on the server before the page is sent to the browser.