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
5 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