▲ Next.js Tutorial

Data Fetching in Next.js

Fetch data on the server with async components.

Data Fetching in Next.js

In the App Router, components can be async by default when they run on the server — so you can fetch data directly, without useEffect or extra libraries.

// app/posts/page.js
async function getPosts() {
  const res = await fetch("https://api.example.com/posts");
  return res.json();
}

export default async function PostsPage() {
  const posts = await getPosts();

  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

Caching

By default, fetch requests are cached. Opt out when you need fresh data every request:

fetch(url, { cache: "no-store" });

Reading Local Files

This site does the same thing with markdown — reading files from disk on the server before rendering:

import fs from "fs";
const raw = fs.readFileSync("content/example.md", "utf8");

Common Errors & Troubleshooting

  • fs module errors like "Module not found: Can't resolve 'fs'" — this happens when fs is imported into a Client Component (marked with "use client"). fs only works on the server — make sure the component reading files stays a plain Server Component.
  • Data looks stale even after the source changed — remember fetch is cached by default in the App Router; add { cache: "no-store" } (or a revalidate option) if you need every request to hit the live source.
  • await used outside an async function — a Server Component must itself be declared async function before you can await a fetch() or file read inside it; forgetting the async keyword on the component causes a syntax error.