Data Fetching
Data fetching is a core part of any application. This page goes through how you can fetch, cache, and revalidate data in React and Next.js.
There are four ways to fetch data :
Data Fetching on the Server with Fetch
You can use fetch
with async/await in Server Components, in Route Handlers, and in Server Actions.
Example
1async function getData() {
2 const res = await fetch('https://api.example.com/...')
3 // The return value is *not* serialized
4 // You can return Date, Map, Set, etc.
5
6 if (!res.ok) {
7 // This will activate the closest `error.js` Error Boundary
8 throw new Error('Failed to fetch data')
9 }
10
11 return res.json()
12}
13
14export default async function Page() {
15 const data = await getData()
16
17 return <main></main>
18}
Tip : To use async/await in a Server Component with TypeScript, you'll need to use TypeScript 5.1.3 or higher and @types/react 18.2.8 or higher.
Data Caching
Caching stores data so it doesn't need to be re-fetched from your data source on every request.
By default, Next.js automatically caches the returned values of fetch in the Data Cache on the server. This means that the data can be fetched at build time or request time, cached, and reused on each data request.
1// 'force-cache' is the default, and can be omitted
2fetch('https://...', { cache: 'force-cache' })
fetch
requests that use the POST
method are also automatically cached. Unless it's inside a Route Handler that uses the POST
method, then it will not be cached.
Revalidating Data
Revalidation is the process of purging the Data Cache and re-fetching the latest data. This is useful when your data changes and you want to ensure you show the latest information.
Cached data can be revalidated in two ways:
- - Time-based revalidation: Automatically revalidate data after a certain amount of time has passed. This is useful for data that changes infrequently and freshness is not as critical.
- - On-demand revalidation: Manually revalidate data based on an event (e.g. form submission). On-demand revalidation can use a tag-based or path-based approach to revalidate groups of data at once.
Time-based Revalidation
To revalidate data at a timed interval, you can use the option of fetch to set the cache lifetime of a resource (in seconds).
1fetch('https://...', { next: { revalidate: 3600 } })
On-Demand Revalidation
Data can be revalidated on-demand by path (revalidatePath) or by cache tag (revalidateTag)
1export default async function Page() {
2 const res = await fetch('https://...', { next: { tags: ['collection'] } })
3 const data = await res.json()
4 // ...
5}
You can then revalidate this fetch call tagged with collection by calling revalidateTag in a Server Action:
1'use server'
2
3import { revalidateTag } from 'next/cache'
4
5export default async function action() {
6 revalidateTag('collection')
7}