Data Fetching Fundamentals

Next.js 13 introduced a new way to fetch and manage data in your application. The API has been simplified to align with React and the Web Platform. This means previous Next.js APIs such as getServerSideProps, getStaticProps, and getInitialProps are not supported in the new app directory. Instead, there is a more flexible way to fetch, cache, and revalidate data at the component level.

This page will go through the fundamental concepts and recommended best practices to help you manage your application's data lifecycle.

Fetching Data with Server Components

Inside the app directory, we recommend fetching data inside the Server Component that directly needs the data. Server Components always fetch data on the server.

Fetching data directly in Server Components comes with many benefits, as this fetching pattern allows you to:

  • Have direct access to backend data resources (e.g. databases, APIs) since they never run on the client.
  • Easily keep your application secure by keeping sensitive information, such as access tokens and API keys, on the server.
  • Fetch data and render the component in the same environment. This reduces both the back and forth communication between client and server, as well as the work on the main thread client-side.
  • Perform multiple data fetches as a single round-trip instead of multiple individual requests on the client. Depending on your region, data fetching can also happen closer to your data source, reducing latency and improving performance.
  • Reduce client-server waterfalls.
  • Send less JavaScript to the client as Server Components don't send a JavaScript bundle.

Learn more about Client and Server Components.

Good to know: It's still possible to fetch data in Client Components. We recommend using a third-party library such as SWR or React Query. In the future, it'll also be possible to fetch data in Client Components using React's use() hook.

Component-level Data Fetching

In this new model, you can fetch data inside layouts, pages, and components. Data fetching is also compatible with Streaming and Suspense.

For layouts, it's not possible to pass data between a parent layout and its children. We recommend fetching data directly inside the layout that needs it, even if you're requesting the same data multiple times in a route. Behind the scenes, React and Next.js will cache and dedupe requests to avoid the same data being fetched more than once.

Parallel and Sequential Data Fetching

When fetching data in components, you need to be aware of two data fetching patterns: Parallel and Sequential.

With parallel data fetching, requests in a route are eagerly initiated and will load data at the same time. This reduces client-server waterfalls and the total time it takes to load data.

With sequential data fetching, requests in a route are dependent on each other and will load data in a waterfall pattern. There may be cases where you want this pattern because one fetch depends on the result of the other, or you want a condition to be satisfied before the next fetch to save resources. However, sequential data fetching can be unintentional and lead to longer loading times.

To learn how to implement these patterns in Next.js, see the Data Fetching Patterns section.

The fetch() API

The new data fetching system is built on top of the native fetch() Web API and makes use of async/await within Server Components. Read more about async components in the Support for Promises RFC.

fetch() is a Web API used to fetch remote resources and returns a promise. React extends fetch to provide automatic request deduping, and Next.js extends the fetch options object to allow each request to set its own caching and revalidating rules.

To see how fetch and async components work together, see the Data Fetching page.

Automatic fetch() Request Deduping

React will automatically cache fetch requests with the same input in a temporary cache. This is an optimization to avoid the same data being fetched more than once during a rendering pass - and is especially useful when multiple components need to fetch the same data.

For example, you might fetch the current user in multiple components in a tree that spans across nested layouts. This optimization ensures that it's not only safe but encouraged to fetch data in the component where it's used.

  • On the server, the cache lasts the lifetime of a server request until the rendering process completes.
  • On the client, the cache lasts the duration of a session (which could include multiple client-side re-renders) before a full page reload.

In cases where you're not able to use fetch, React provides a cache function to allow you to manually cache data for the duration of the request. Learn more about cache.

Static and Dynamic Data Fetches

In Next.js, there are two types of data: Static and Dynamic.

  • Static Data is data that doesn't change often. For example, a blog post which is rarely updated.
  • Dynamic Data is data that changes often or can be specific to users. For example, a list of products in a shopping cart.

By default, Next.js automatically does static fetches. This means that the data will be fetched at build time, cached, and reused on each request. As a developer, you have control over how the static data is cached and revalidated.

There are two benefits to using static data:

  1. It reduces the load on your database by minimizing the number of requests made.
  2. The data is automatically cached for improved loading performance.

However, there are some cases where you want to fetch the latest data. Next.js supports this by allowing you to mark requests as dynamic. This means that the data will be fetched at request time and not cached.

To learn more about the static and dynamic data fetches, see the Data Fetching page.

Caching Data

Caching is the process of storing data in a location (e.g. Content Delivery Network) so it doesn't need to be re-fetched from the original source on each request and be served up faster.

The Next.js Cache is a persistent HTTP cache that can be globally distributed. This means the cache can scale automatically and be shared across multiple regions depending on your platform (e.g. Vercel).

Next.js extends the options object of the fetch() function to allow each request on the server to set its own persistent caching behavior. Together with component-level data fetching, this allows you to configure caching within your application code directly where the data is being used.

During server rendering, when Next.js comes across a fetch, it will check the cache to see if the data is already available. If it is, it will return the cached data. If not, it will fetch and store data for future requests.

Revalidating Data

Revalidation is the process of purging the cache and re-fetching the latest data. This is useful when your data changes and you want to ensure your application shows the latest version.

Next.js provides two types of revalidation:

  • Background: Revalidates the data at a specific time interval.
  • On-demand: Revalidates the data whenever there is an update.

Streaming and Suspense

Streaming and Suspense are new React features that allow you to progressively render and incrementally stream rendered units of the UI to the client.

With Server Components and nested layouts in Next.js, you're able to instantly render parts of the page that do not specifically require data, and show a loading state for parts of the page that are fetching data. This means the user does not have to wait for the entire page to load before they can start interacting with it.

Server Rendering with Streaming

To learn more about Streaming and Suspense, see the Loading UI and Streaming and Suspense page.

Next Steps