Bird
Raised Fist0
NextJSframework~10 mins

Fetch in server components in NextJS - Step-by-Step Execution

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Concept Flow - Fetch in server components
Start Server Component Render
Call fetch() to get data
Await fetch response
Parse JSON data
Render component with data
Send HTML to client
End
The server component starts rendering, fetches data asynchronously, waits for the data, then renders HTML with that data before sending it to the client.
Execution Sample
NextJS
export default async function Page() {
  const res = await fetch('https://api.example.com/data');
  const data = await res.json();
  return <div>{data.message}</div>;
}
This server component fetches data from an API, waits for the JSON response, then renders a div showing the message from the data.
Execution Table
StepActionEvaluationResult
1Start rendering Page componentNo data yetComponent starts
2Call fetch('https://api.example.com/data')Returns PromisePending fetch
3Await fetch responseWaits for networkResponse received
4Call res.json()Returns PromisePending JSON parse
5Await JSON parseWaits for parsing{ message: 'Hello from API' }
6Render <div>{data.message}</div>data.message = 'Hello from API'<div>Hello from API</div>
7Send HTML to clientHTML readyClient receives rendered HTML
💡 Rendering completes after data is fetched and component returns HTML.
Variable Tracker
VariableStartAfter Step 2After Step 3After Step 4After Step 5Final
resundefinedPromise (pending)Response objectResponse objectResponse objectResponse object
dataundefinedundefinedundefinedPromise (pending){ message: 'Hello from API' }{ message: 'Hello from API' }
Key Moments - 2 Insights
Why do we use 'await' before fetch and res.json()?
Because fetch and res.json() return Promises, 'await' pauses execution until the data is ready, as shown in steps 3 and 5 of the execution table.
Does the client see the fetch call or the raw data?
No, the client only receives the final rendered HTML (step 7). The fetch happens on the server during rendering.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is the value of 'data' after step 5?
A{ message: 'Hello from API' }
BPromise (pending)
Cundefined
DResponse object
💡 Hint
Check the 'data' row in variable_tracker after step 5.
At which step does the component start rendering the HTML with the fetched data?
AStep 3
BStep 6
CStep 2
DStep 5
💡 Hint
Look for the step where the JSX with data.message is created in the execution_table.
If we remove 'await' before fetch, what happens in the execution flow?
AThe fetch call is skipped entirely.
BThe component waits longer for data.
CThe component renders before data is fetched, showing a Promise object.
DThe client receives raw JSON instead of HTML.
💡 Hint
Consider how Promises behave without 'await' in the execution_table steps 2 and 3.
Concept Snapshot
Fetch in Server Components (Next.js):
- Use 'await fetch(url)' inside async server components.
- Await response and parse JSON with 'await res.json()'.
- Render JSX with fetched data.
- Data fetching happens on server, client gets ready HTML.
- No client-side loading states needed for server fetch.
Full Transcript
In Next.js server components, fetching data uses the fetch API with async/await. The component starts rendering, calls fetch to get data from an API, and waits for the response. Then it parses the JSON data and uses it to render JSX. Finally, the server sends the fully rendered HTML to the client. This means the client sees the final content immediately without extra loading. The execution table shows each step: starting render, fetching, awaiting response, parsing JSON, rendering JSX, and sending HTML. Variables like 'res' and 'data' change from undefined to promises to actual data objects as the code runs. Beginners often wonder why 'await' is needed and if the client sees the fetch call. The answer is that 'await' pauses execution until data is ready, and the client only gets the rendered HTML, not the fetch process. If 'await' is missing, the component tries to render before data arrives, showing a Promise instead of real content.

Practice

(1/5)
1. In Next.js server components, where should you place the fetch() call to get data before rendering?
easy
A. In a separate API route only
B. Inside a client-side useEffect hook
C. Directly inside the async server component using await fetch()
D. Inside a React state hook like useState

Solution

  1. Step 1: Understand server components run on the server

    Server components execute on the server before sending HTML to the browser, so data fetching happens here.
  2. Step 2: Use await fetch() inside async server components

    Using await fetch() directly inside an async server component fetches data before rendering.
  3. Final Answer:

    Directly inside the async server component using await fetch() -> Option C
  4. Quick Check:

    Fetch in async server component = Directly inside the async server component using await fetch() [OK]
Hint: Fetch data inside async server components with await fetch() [OK]
Common Mistakes:
  • Trying to fetch data inside client hooks like useEffect
  • Fetching data in React state hooks which run on client
  • Assuming API routes are mandatory for server component fetch
2. Which of the following is the correct syntax to fetch data inside a Next.js server component?
easy
A. const data = await fetch('https://api.example.com/data').then(res => res.json())
B. const data = fetch('https://api.example.com/data')
C. const data = await fetch('https://api.example.com/data').json()
D. const data = fetch('https://api.example.com/data').json()

Solution

  1. Step 1: Use await with fetch to wait for response

    Fetch returns a promise, so use await to wait for it to resolve.
  2. Step 2: Call res.json() on the response to parse JSON

    After fetch resolves, call res.json() to get the parsed data, also awaited or chained with then.
  3. Final Answer:

    const data = await fetch('https://api.example.com/data').then(res => res.json()) -> Option A
  4. Quick Check:

    Await fetch then parse JSON = const data = await fetch('https://api.example.com/data').then(res => res.json()) [OK]
Hint: Always await fetch and then parse JSON with res.json() [OK]
Common Mistakes:
  • Forgetting to await fetch causing unresolved promises
  • Calling .json() directly on fetch without awaiting response
  • Using fetch without handling the response parsing
3. What will be the output of this Next.js server component code?
export default async function Page() {
  const res = await fetch('https://jsonplaceholder.typicode.com/todos/1');
  const todo = await res.json();
  return 
{JSON.stringify(todo)}
; }
medium
A.
{"userId":1,"id":1,"title":"delectus aut autem","completed":false}
B. SyntaxError because fetch cannot be used in server components
C. Empty output because data is not awaited
D. Loading spinner indefinitely because fetch is async

Solution

  1. Step 1: Await fetch and parse JSON in server component

    The code correctly awaits fetch and then awaits res.json() to get the todo object.
  2. Step 2: Return JSON stringified todo inside <pre> tag

    The component returns a <pre> element with the stringified todo data, so it renders the JSON text.
  3. Final Answer:

    <pre>{"userId":1,"id":1,"title":"delectus aut autem","completed":false}</pre> -> Option A
  4. Quick Check:

    Await fetch + JSON.stringify output =
    {"userId":1,"id":1,"title":"delectus aut autem","completed":false}
    [OK]
Hint: Await fetch and JSON parse before returning JSX [OK]
Common Mistakes:
  • Expecting fetch to fail in server components
  • Not awaiting fetch causing unresolved promises
  • Returning raw object instead of stringified JSON
4. Identify the error in this Next.js server component fetching code:
export default function Page() {
  const res = await fetch('https://api.example.com/data');
  const data = await res.json();
  return <div>{data.title}</div>;
}
medium
A. res.json() does not return a promise
B. Missing async keyword on the component function
C. fetch cannot be used in server components
D. JSX syntax error in return statement

Solution

  1. Step 1: Check async usage in server component

    The component uses await but is not declared async, which causes a syntax error.
  2. Step 2: Confirm fetch is allowed in server components

    Fetch is allowed in server components, so no error there. Also, res.json() returns a promise, so awaiting is correct.
  3. Final Answer:

    Missing async keyword on the component function -> Option B
  4. Quick Check:

    Await requires async function = Missing async keyword on the component function [OK]
Hint: Add async to function using await fetch [OK]
Common Mistakes:
  • Forgetting async on function using await
  • Thinking fetch is disallowed in server components
  • Misunderstanding res.json() returns a promise
5. You want to fetch user data and posts in a Next.js server component and display the user's name with their post titles. Which approach correctly fetches both and renders them efficiently?
hard
A. Fetch posts first, then fetch user data inside a nested fetch call
B. Fetch user data in server component and posts in client component using useEffect
C. Fetch user and posts sequentially with two awaits, then render after both complete
D. Fetch user and posts in parallel using Promise.all inside the server component

Solution

  1. Step 1: Understand parallel fetching improves performance

    Fetching user and posts in parallel with Promise.all reduces total wait time compared to sequential awaits.
  2. Step 2: Use Promise.all inside async server component to fetch both

    Inside the async server component, use const [user, posts] = await Promise.all([fetchUser(), fetchPosts()]) to fetch simultaneously.
  3. Step 3: Render user name and post titles after both fetches complete

    After both promises resolve, render the data together efficiently in the server component.
  4. Final Answer:

    Fetch user and posts in parallel using Promise.all inside the server component -> Option D
  5. Quick Check:

    Parallel fetch with Promise.all = Fetch user and posts in parallel using Promise.all inside the server component [OK]
Hint: Use Promise.all to fetch multiple data in server components [OK]
Common Mistakes:
  • Fetching data sequentially causing slower load
  • Mixing client and server fetching unnecessarily
  • Nesting fetch calls causing callback delays