I am having an endpoint /api/data
, which returns a following response:
{
"data": "[]",
"revalidationTimestamp": "2024-12-31T22:00:00.000Z"
}
The data which this endpoint returns can be stale for either couple of hours or couple of days; that’s not predictable, so any time based revalidation constant doesn’t work here. The data are being updated either from an external source on the timestamp, or by my app on user action.
In a Next.js application, I am fetching data from this endpoint in a server action and caching the response:
'use server'
export async function getData() {
const response = await fetch('/api/data', { next: { tags: ['data'] } })
return response.data
}
I can now manually revalidate the data by data
tag when a user action happens, however, if no user action happens before the timestamp, I need to revalidate the cache on the timestamp:
'use server'
export async function getData() {
const response = await fetch('/api/data', { next: { tags: ['data'] } })
// revalidate the cache on response.revalidationTimestamp
return response.data
}
I am currently having a custom cache wrapper for this, which triggers tag based revalidation whenever this function is called after the timestamp. That has been working fine in Next.js 14, however, it has started throwing an error in Next.js 15, because the function is called during a render. I understand the reasoning behind this change and why it is a bad practice, however, I couldn’t find any other solution for the desired behaviour.
Solutions I’ve considered:
- Using time based revalidation doesn’t work, because I cannot specify
revalidate
in seconds until I know what the timestamp is based on the response - Disabling the fetch cache and replacing it by
unstable_cache
. The problems are the same, i.e. tag based revalidation with a wrapper throws an error, time based revalidation is not possible to be defined based on the timestamp from the response - Disabling the fetch cache and replacing it by
use cache
. The problems are the same, i.e. tag based revalidation with a wrapper throws an error, time based revalidation is not possible to be defined based on the timestamp from the response
I don’t want to give up on caching, because I want to save costs by preventing calling the endpoint more often than what is necessary.
Is there any solution for achieving timestamp based data/fetch cache revalidation in Next.js 15? I can use canaries and experimental features.