Confused about Next.js 15 caching
Unanswered
Mozzy posted this in #help-forum
MozzyOP
I understand that in 15, the default cache is
The following code are server actions.
I am able to use
Any pointers would be helpful
no-store
, but now I cannot opt into caching at all in some cases.The following code are server actions.
getTopTracks
is called from a server page.tsxconst getAccessToken = async () => {
const response = await fetch(TOKEN_ENDPOINT, {
method: "POST",
headers: {
Authorization: `Basic ${basic}`,
"Content-Type": "application/x-www-form-urlencoded",
},
body: querystring.stringify({
grant_type: "refresh_token",
refresh_token,
}),
});
return response.json();
};
export const getTopTracks = async (range: string) => {
const { access_token } = await getAccessToken();
const url = new URL("https://api.spotify.com/v1/me/top/tracks");
// Excluding medium_term as it's the default
const validRange = ["short_term", "long_term"].includes(range);
if (validRange) url.searchParams.append("time_range", range);
const res = await fetch(url, {
headers: {
Authorization: `Bearer ${access_token}`,
},
// next: { revalidate: 86_400 },
// With the above or with the below, this is never cached
cache: "force-cache",
});
return res.ok
? ((await res.json()) as SpotifyApi.UsersTopTracksResponse)
: null;
};
I am able to use
cache: "force-cache"
on getAccessToken
, but adding it to getTopTracks
leads to it always skipping cache when the page is navigated to │ GET https://api.spotify.com/v1/me/top/tracks 200 in 288ms (cache skip)
│ │ Cache skipped reason: (cache-control: no-cache (hard refresh))
Any pointers would be helpful
11 Replies
MozzyOP
Where is
cache-control: no-cache (hard refresh)
coming from and why does the cache property not override this?MozzyOP
I read that staleTimes have been set to 0 as the default. I assume that's where "hard refresh" comes from. But why would the
cache: "force-cache"
on the fetch() not be followed?You are setting the
Authorization
header on the fetch call. This will never be cached.MozzyOP
Would this be correct then?
export const getTopTracks = unstable_cache(
async (range: string) => {
console.log("Fetching top tracks");
const { access_token } = await getAccessToken();
const url = new URL("https://api.spotify.com/v1/me/top/tracks");
// Excluding medium_term as it's the default
const validRange = ["short_term", "long_term"].includes(range);
if (validRange) url.searchParams.append("time_range", range);
const res = await fetch(url, {
headers: {
Authorization: `Bearer ${access_token}`,
},
});
return res.ok
? ((await res.json()) as SpotifyApi.UsersTopTracksResponse)
: null;
},
[],
// 3 seconds as a test. Seems to work
{ revalidate: 3 },
);
It seems to work, but I'm unsure if that's how to do it
What I meant was, any
If you want to cache that fetch call you will need to look into using
fetch
call that sets the Authorization
header is not cacheable via the options object.If you want to cache that fetch call you will need to look into using
unstable_cache
to wrap that fetch call.Oh nvm you are using that
didn't see it up there lol
Yeah that will work
Just keep in mind that you are caching the entire response there, which is fine if your application uses the entire response, otherwise you should filter it down to the parts you need and only return those.
Only the data that is returned from the function is cached.
Only the data that is returned from the function is cached.
MozzyOP
True, thanks