Fetch in Server Components

Read data on the server and pass it to Client Components as props.

From next-best-practices, data-patterns.md.

Time to data

Press Load page, then drag the sliders.

Client fetch on mountBad
/users
  • Ada Lovelace
  • Grace Hopper
  • Alan Turing
–useEffect(() => fetch('/api/users'))
Server ComponentGood
/users
  • Ada Lovelace
  • Grace Hopper
  • Alan Turing
–await db.user.findMany()

// app/users/page.tsx
async function UsersPage() {
  const users = await db.user.findMany();
  return <UserList initialData={users} />;
}

// user-list.tsx
'use client';
function UserList({ initialData }) {
  const [users, setUsers] = useState(initialData);
}

Where the key ends up

Type a key, then switch tabs.

Client calls the APIBad
Server
Browser
NEXT_PUBLIC_WEATHER_KEY
Server calls the APIGood
Server
Browserrendered HTML
process.env.WEATHER_KEY
// app/forecast/page.tsx
async function ForecastPage() {
  const days = await fetch('https://api.weather.dev/v1/forecast?city=Lisbon', {
    headers: { authorization: `Bearer ${process.env.WEATHER_KEY}` },
  }).then(r => r.json());

  return <Forecast initialData={days} />;
}

Which pattern?

Answer the questions.

Who needs the data?
Need to fetch data?
├── From a Server Component?
│   └── Use: Fetch directly (no API needed)
├── From a Client Component?
│   ├── Is it a mutation (POST/PUT/DELETE)?
│   │   └── Use: Server Action
│   └── Is it a read (GET)?
│       └── Use: Route Handler OR pass from Server Component
├── Need external API access (webhooks, third parties)?
│   └── Use: Route Handler
└── Need REST API for mobile app / external clients?
    └── Use: Route Handler

Why it matters, pros and cons

Why it matters

The server sits next to the data, so rows ship in the first HTML.

Pros

  • No API route to maintain.
  • No client-server waterfall.
  • Secrets stay on the server.

Cons

  • Live data (polling, infinite scroll) still needs client fetches.
  • Mobile apps and webhooks need a Route Handler.
  • A slow query blocks the page without <Suspense>.