Skip to the solution
MediumFrontend6 min read

How do you fetch data in Next.js Server Components?

207 views

The problem

Question presented to candidate: "You have a product page that needs the product, its reviews and the current user. Show me how you would load that data in the App Router, and tell me what you would watch out for."

What a strong answer should cover:

  • A Server Component can be async and simply await data: fetch, an ORM, a file read, an SDK call.
  • No useEffect, no API route in between, and no loading state for the initial HTML.
  • Independent requests should run in parallel with Promise.all, or be split into separate components under Suspense so they stream.
  • Identical fetch GET calls in one render are memoized, and React.cache does the same for non-fetch functions, so you can load data where it is used.
  • Whether the result is cached across requests is a separate decision (fetch options, 'use cache'), and request-time data makes the route dynamic.

Clarifying questions expected:

  • "Do the three requests depend on each other?" β€” only dependent ones should be sequential.
  • "Is any of this data per user?" β€” it decides between caching and rendering per request.

Code / implementation expected: Yes β€” an async Server Component with parallel requests and a streamed part.

  • nextjs
  • data-fetching
  • server-components
  • fetch

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

6 min read Β· 8 sections

Read the code

Parallel requests plus a streamed section
// app/product/[id]/page.tsx
import { Suspense } from "react";
import { getProduct, getUser, getReviews } from "@/lib/data";

async function Reviews({ id }: { id: string }) {
  const reviews = await getReviews(id);            // slow: streamed later
  return <ul>{reviews.map((r) => <li key={r.id}>{r.text}</li>)}</ul>;
}

export default async function ProductPage({ params }: { params: Promise<{ id: string }> }) {
  const { id } = await params;
  const [product, user] = await Promise.all([getProduct(id), getUser()]); // start both, then wait
  return (
    <main>
      <h1>{product.name}</h1>
      <p>Hi {user.name}</p>
      <Suspense fallback={<p>Loading reviews...</p>}>
        <Reviews id={id} />
      </Suspense>
    </main>
  );
}

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 86 of 129 in Next.js

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All Next.js questions
Up nextMedium

How do you use a database like Prisma in Next.js without exhausting connections?

Continue