Question about caching on API route vs. server component vs. page
Answered
Russian Blue posted this in #help-forum
Russian BlueOP
Hi, i have an Route Handler that is fetching data from the DB. It is using
I then have a Server Component that is calling this API Route with
In production, the page/Server Component is displaying yesterday's data. If I refresh the page, it shows today's data. But then if I log out and back in, it's back to yesterday's, so the page seems to be cached.
I thought that
It seems that adding
export const dynamic = "force-dynamic"I then have a Server Component that is calling this API Route with
fetch. This component is then displayed on a page.In production, the page/Server Component is displaying yesterday's data. If I refresh the page, it shows today's data. But then if I log out and back in, it's back to yesterday's, so the page seems to be cached.
I thought that
export const dynamic = "force-dynamic" on the API Route would then make any fetch calls for this route dynamic? But is the fetch call instead still expected to be cached ?It seems that adding
cache: no store on the fetch fixed it, but I am still trying to get clarity on the logic of how this works. Any help is appreciated.Answered by joulev
there are two things being potentially cached here:
* the page
* the route
in the case of the OP, the route is not cached, but the page is cached. so when you visit the page, you see the same thing all the time.
adding
if you absolutely want to fetch your own route handlers and want it to be dynamic, you need to disable cache in both places. well, just don't fetch your own route handlers
* the page
* the route
in the case of the OP, the route is not cached, but the page is cached. so when you visit the page, you see the same thing all the time.
adding
cache: "no-store" remove the cache from the page so that made it work.if you absolutely want to fetch your own route handlers and want it to be dynamic, you need to disable cache in both places. well, just don't fetch your own route handlers
26 Replies
@Russian Blue Hi, i have an Route Handler that is fetching data from the DB. It is using `export const dynamic = "force-dynamic"`
I then have a Server Component that is calling this API Route with `fetch`. This component is then displayed on a page.
In production, the page/Server Component is displaying yesterday's data. If I refresh the page, it shows today's data. But then if I log out and back in, it's back to yesterday's, so the page seems to be cached.
I thought that `export const dynamic = "force-dynamic"` on the API Route would then make any `fetch` calls for this route dynamic? But is the `fetch` call instead still expected to be cached ?
It seems that adding `cache: no store` on the `fetch` fixed it, but I am still trying to get clarity on the logic of how this works. Any help is appreciated.
you should have a read of the caching section of docs as there are lots of quirks with it: https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating and also https://nextjs.org/docs/app/building-your-application/caching (and easier for you to read then explain whats nicely there)
Russian BlueOP
@riský , I read the docs, it is not clear to me. That's why I asked here.
Russian BlueOP
So I need to use const dynamic = 'force-dynamic' in the Server Component
fetch for it not to be cached? As mentioned, I'm already using export const dynamic = "force-dynamic" on the Route Handler for this fetch callRussian BlueOP
Yes, that seems to be right
so it think whats happening is it must be caching with lifespan of nothing, and then nextjs cache alwasys works by server stale then refetch in background
and in this case its either not clear, or bugged 😭
@Russian Blue Hi, i have an Route Handler that is fetching data from the DB. It is using `export const dynamic = "force-dynamic"`
I then have a Server Component that is calling this API Route with `fetch`. This component is then displayed on a page.
In production, the page/Server Component is displaying yesterday's data. If I refresh the page, it shows today's data. But then if I log out and back in, it's back to yesterday's, so the page seems to be cached.
I thought that `export const dynamic = "force-dynamic"` on the API Route would then make any `fetch` calls for this route dynamic? But is the `fetch` call instead still expected to be cached ?
It seems that adding `cache: no store` on the `fetch` fixed it, but I am still trying to get clarity on the logic of how this works. Any help is appreciated.
your server component is static, so the fetch only happens once then cached thereafter. this doesn't care about whether that fetch is static or dynamic. adding
see also https://nextjs-faq.com/fetch-api-in-rsc.
cache: "no-store" made the server component dynamic so that made it work.see also https://nextjs-faq.com/fetch-api-in-rsc.
@riský and in this case its either not clear, or bugged 😭
no it's not a bug, just OP's code is buggy
hmm the way i read it was "if you use force-dynamic on route, fetch cache doesnt exist"
Russian BlueOP
^^ Same here
wait i missread your question
your calling your own endpoint on server?
Russian BlueOP
yes
@riský hmm the way i read it was "if you use force-dynamic on route, fetch cache doesnt exist"
there are two things being potentially cached here:
* the page
* the route
in the case of the OP, the route is not cached, but the page is cached. so when you visit the page, you see the same thing all the time.
adding
if you absolutely want to fetch your own route handlers and want it to be dynamic, you need to disable cache in both places. well, just don't fetch your own route handlers
* the page
* the route
in the case of the OP, the route is not cached, but the page is cached. so when you visit the page, you see the same thing all the time.
adding
cache: "no-store" remove the cache from the page so that made it work.if you absolutely want to fetch your own route handlers and want it to be dynamic, you need to disable cache in both places. well, just don't fetch your own route handlers
Answer
yeah i understand the issue now
i missed the part of fetching itself, i thought it was only the one route being bugged
Russian BlueOP
>well, just don't fetch your own route handlers
What is the better way to do it?
What is the better way to do it?
sorry for the confusion
Russian BlueOP
Got it, thanks both for your help
i mean im glad joulev was here to clear up my lack of reading skills