How to fetch data

This page will walk you through how you can fetch data in Server Components and Client Components. As well as how to stream content that depends on data.

Here is a tutorial on how to fetch data. This entire documentation is referenced from Nextjs, so for a better overview, please check this tutorial from Nextjs - https://nextjs.org/docs/app/getting-started/fetching-data

You can fetch data in Server Components using:

With the fetch API

To fetch data with the fetch API, turn your component into an asynchronous function, and await the fetch call.

For example:

app/blog/page.tsx

export default async function Page() {
  const data = await fetch('https://api.vercel.app/blog')
  const posts = await data.json()
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

With an ORM or database

Since Server Components are rendered on the server, you can safely make database queries using an ORM or database client. Turn your component into an asynchronous function, and await the call:

app/blog/page.tsx

import { db, posts } from '@/lib/db'
 
export default async function Page() {
  const allPosts = await db.select().from(posts)
  return (
    <ul>
      {allPosts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

There are two ways to fetch data in Client Components, using:

  1. React's use hook

  2. A community library like SWR or React Query

With the use hook

You can use React's use hook to stream data from the server to client. Start by fetching data in your Server component, and pass the promise to your Client Component as prop:

app/blog/page.tsx

import Posts from '@/app/ui/posts
import { Suspense } from 'react'
 
export default function Page() {
  // Don't await the data fetching function
  const posts = getPosts()
 
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <Posts posts={posts} />
    </Suspense>
  )
}

Then, in your Client Component, use the use hook to read the promise:

app/ui/posts.tsx

'use client'
import { use } from 'react'
 
export default function Posts({
  posts,
}: {
  posts: Promise<{ id: string; title: string }[]>
}) {
  const allPosts = use(posts)
 
  return (
    <ul>
      {allPosts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

In the example above, you need to wrap the <Posts /> component in a <Suspense> boundary. This means the fallback will be shown while the promise is being resolved. Learn more about streaming.

Community libraries

You can use a community library like SWR or React Query to fetch data in Client Components. These libraries have their own semantics for caching, streaming, and other features. For example, with SWR:

app/blog/page.tsx

Last updated

Was this helpful?