Skip to main content
The App Router lets you fetch data directly inside components using async/await. Server Components run on the server, so you can safely query databases and external APIs without exposing credentials to the client.

Server Components

With the fetch API

Turn a component into an async function and await the fetch call:
Identical fetch requests in a React component tree are memoized by default, so you can fetch data in the component that needs it instead of drilling props. fetch results are not cached unless you use the use cache directive.

With an ORM or database

Since Server Components run on the server, credentials and query logic are never included in the client bundle:

Client Components

With the use API

Start a fetch in your Server Component and pass the unawaited promise to a Client Component:

With community libraries

Use SWR or React Query for client-side data fetching with caching and revalidation semantics:

Parallel data fetching

Multiple sequential await calls inside a component will run one after another. To fetch data in parallel, initiate requests before awaiting them:
If one request fails with Promise.all, the entire operation fails. Use Promise.allSettled to handle partial failures gracefully.

Sequential data fetching with Suspense

When one request depends on the result of another, use Suspense to stream the dependent component while showing a fallback:

Sharing data with React.cache

Use React.cache to deduplicate identical requests across a component tree, and share the result between Server Components and context-based Client Components:
Create a context provider that stores the promise:
In a layout, pass the unawaited promise to the provider:
Client Components resolve the promise from context using use():
Server Components can call getUser() directly — React.cache ensures the result is memoized and not fetched twice:
React.cache is scoped to the current request only. Each request gets its own memoization scope with no sharing between requests.