Skip to content
isam.chajia
Frontend

Next.js App Router data fetching: choosing the right tool

Server Components, Server Actions, route handlers and client fetching — a practical guide to picking the simplest option that fits each case.

Isam Chajia7 min read
Laptop showing a code editor with a React component tree

The App Router gives you several ways to load data. The trick is not to memorise every API, but to reach for the simplest one that keeps your components readable and your pages fast.

Start on the server

By default, fetch data where you render it. A Server Component can await a database call or an API directly, which keeps secrets on the server and removes loading spinners from the initial paint.

export default async function Page() {
  const posts = await getPosts();
  return <PostList posts={posts} />;
}

When to reach for the client

  • Interactive filters, search-as-you-type and infinite scroll.
  • Data that must refresh without a full navigation.
  • Small widgets that depend on browser-only APIs.

Client fetching is not wrong — it is just heavier. Use it where the interaction genuinely needs it, and keep it out of the critical path.

Caching and revalidation

Decide how fresh each piece of data needs to be, then say so explicitly. Static content can be cached for a long time; a dashboard probably needs to revalidate every few seconds.

  • Revalidate on a timer for slowly changing content.
  • Revalidate by tag or path after a write.
  • Opt out of caching only when correctness demands it.
The best data-fetching strategy is the one a new teammate can follow by reading the component.
  • Next.js
  • React
  • Data Fetching
Available for new work

Enjoying the writing?

If an article sparked an idea for your product or team, I'd be glad to hear about it.

Replies within 2 working daysMarrakech, Morocco