Do we have a way of disabling RSC Router Cache yet (other than router.refresh()?)
Unanswered
Abyssinian posted this in #help-forum
AbyssinianOP
Is there a way to disable the RSC Router Cache while navigating between pages yet, or something in the works besides
It's crazy that there isn't a more straight forward way of disabling the cache. It makes sense why we would want the cache there (faster navigations between pages), but if i'm navigating to a page that lists (let's say a page of new posts for example), it doesn't make sense why I should be returned cached data.
I'm using
Anyone have any guidance or feedback on my question? 🙂
router.refresh() ? It's crazy that there isn't a more straight forward way of disabling the cache. It makes sense why we would want the cache there (faster navigations between pages), but if i'm navigating to a page that lists (let's say a page of new posts for example), it doesn't make sense why I should be returned cached data.
I'm using
PPR (with Suspense) as it is, so I should be getting returned static pages which is pretty quick.Anyone have any guidance or feedback on my question? 🙂
111 Replies
AbyssinianOP
I've tried like doing the following:
But that doesn't work either.
I just want a way to tell the page to return the cached RSC.. but revalidate the data or something.. idk.
export const revalidate = 0But that doesn't work either.
I just want a way to tell the page to return the cached RSC.. but revalidate the data or something.. idk.
so
if you're mutating data and expect it to change, you'd use
otherwise,
export const revalidate = 0 only effects the fetch cache ([source](https://github.com/vercel/next.js/issues/51788#issuecomment-1909006248))if you're mutating data and expect it to change, you'd use
revalidatePath when that change happensotherwise,
router.refresh() is your only choice ([source](https://nextjs.org/docs/app/building-your-application/caching#opting-out-3))AbyssinianOP
Yeah for a page listing posts for example.. I wouldn't neccesarily know when the posts will change 😄
So yeah it sounds like router.refresh is my only option 😦
uggh
Isn't this like a way bigger issue?
someone in that same thread had this solution: https://github.com/vercel/next.js/issues/51788#issuecomment-1625207979
using
using
startTransition means that it'll show the "stale" data while loading the new stuff, I guess?AbyssinianOP
I mean updating the data after a mutation is the easy part
it's when the data updates in the background..and you need it to show fresh data
yeah i understand you have no idea when the posts would update
i was suggesting you use startTransition when you call router.refresh
AbyssinianOP
I can't do router.refresh on navigation tho... I mean it's an RSC?

I'd have to make it a client component no?
This is my page essentially
export default function Page() {
return (
<div>
<p className='mb-5'>
Go to{' '}
<Link
className='rounded bg-blue-500 px-4 py-2 font-semibold text-white hover:bg-blue-700'
href='/'
>
Home
</Link>{' '}
page.
</p>
<AddTodoForm />
<Suspense fallback={<TodosSkeleton />}>
<ListTodos />
</Suspense>
</div>
)
}
function TodosSkeleton() {
return (
<ul className='animate-pulse space-y-1'>
<li className='h-5 w-full rounded bg-gray-200 dark:bg-neutral-800'></li>
<li className='h-5 w-full rounded bg-gray-200 dark:bg-neutral-800'></li>
<li className='h-5 w-full rounded bg-gray-200 dark:bg-neutral-800'></li>
<li className='h-5 w-full rounded bg-gray-200 dark:bg-neutral-800'></li>
<li className='h-5 w-full rounded bg-gray-200 dark:bg-neutral-800'></li>
</ul>
)
}
async function ListTodos() {
const { session } = await validateAuth()
if (!session) return 'Unauthorized'
const all = await db
.select()
.from(todos)
.where(eq(todos.userId, session.userId))
.orderBy(desc(todos.id))
.limit(5)
if (all.length === 0) return <div>No todos found.</div>
return (
<ul className='space-y-1'>
{all.map((todo) => (
<li className='h-5' key={todo.id}>
{todo.description}
</li>
))}
</ul>
)It's crazy that I have no way to specify that ListTodos should just re-render on the server.. so it can return fresh data (other than
router.refresh())oh i assumed you had a client component further down that consumed the data from ListTodos where you could call router.refresh
i dont have a better answer for you, sorry
@josh i dont have a better answer for you, sorry
AbyssinianOP
All good, appreciate your input 🙂
I figured there's prob no solution for this 

it should revalidate after 30 seconds, right?
AbyssinianOP
I've seen others struggling from this.. so just trying to push my frustrations so we can get a better solution
I mean yeah I think it prob revalidates
but, that's not fast enough
AbyssinianOP
Right.. I mean... I don't want it to be cached at all 😄
imagine going to your bank website
and seeing $500 when you only had $10
I mean I guess that's a bad example
cause it would eventually update.. but idk
I just want fresh data 

I think that's the argument that alot of people fall to.. when they're faced with this question.. "But it just updates in like 30 seconds right?"
"You can't just wait 30 seconds?"

i agree there should be a way to control the router cache more finely
or disable it entirely
AbyssinianOP
I mean... there's gonna be a way to still return the cached RSC component or w/e.. but then just flag that you want it to refetch the data
I don't really know the technical stuff tbh
so prob not saying it correctly.. but yeah
Also...
AbyssinianOP
Yeah i've seen this page
export const dynamic = "force-dynamic";this does not work either
i believe that only effects
fetch, like a page-scoped configuration for itAbyssinianOP

someone with the same problem https://github.com/vercel/next.js/discussions/54075#discussioncomment-8445028
AbyssinianOP
Yup... we need a native solution to the issue
not just some "hacky workaround"
crazy this hasn't been addressed yet
i've seen alot of people complaining about it
Overall we believe the default for this behavior is correct, however we’d like to figure out in what way folks in this issue want to opt-out of the behavior, as there are multiple related features that seem to be confused for this behavior.
sounds like it is on their plate
AbyssinianOP

I mean obviously the default RSC caching was meant for static content
if you're going to different blog pages.. obv you don't need to update the data every time you navigate to a different blog page (this data isn't going to change)
duh
buttttt
when it comes to like more dynamic data.. it shouldn't just be forced upon you that the data is cached on each navigation
I think that's where the disconnect is..
But i'd love to know how developers at larger companies are overcoming this issue.. I mean people must be solving this some how lol?
Is everyone just manually running
router.refresh() lol?They just accept that their data is cached for up to 30 seconds? (and say it's fine?)
i don't think
done with startTransition, there's no loading indicator, just a change from stale data to new data
router.refresh() hacky, it communicates "refetch the data for this page"done with startTransition, there's no loading indicator, just a change from stale data to new data
AbyssinianOP
so is that the official solution then?
I just have to do
router.refresh on each page I need fresh data?It just seems crazy to me that caching is the default
instead of like having to set a parameter to enable caching or something
they definitely set some opinionated defaults
AbyssinianOP
Yeah.. it's crazy 😂
But.. I know that the second a core developer chimes in.. it would be "why would you want to disable caching"
🙄
Sorry for venting to you Josh 😂 Just had to get it off my chest
super frustrating
it's all good
it would be good to hear another opinion in case we're missing something
AbyssinianOP
Yeah for sure
I've been considering just disabling SSR until it's fixed tbh
just doing everything client side for the time being
what about turning the
<ul> bit into a client component with router.refresh() on mount, and passing the RSC data into it?then you keep both
AbyssinianOP
I considered that
BUT
if I call
router.refresh() I noticed.. it seems to disable the cache going forwardso I call it once..and it doesn't cache the RSC on every navigation going forward
so in that case.. if it's not caching.. I'd have 2 requests for the data happening
once on navigation..and then again when I called
router.refresh() againhere lemme show you what happens
sec
i wouldn't expect that
odd
AbyssinianOP
I do have PPR enabled
i'm wondering if that's causing weird things
what is PPR?
AbyssinianOP
Partial PreRendering
oh yeah
i don't know anything about that yet
AbyssinianOP
lemme disable and retest it
ok yeah it is PPR
bug?
AbyssinianOP
could be yep
check this out
You'll notice after I do the
router.refresh() the 1 time.. every time after it refreshesonly with PPR enabled tho
yeah i see
maybe worth reporting
AbyssinianOP
Yeah I will
AbyssinianOP
Also it looks like if I'm calling
router.refresh() every time.. in my client components.. I have to think about component re-renders and such🤢
I wonder if I can figure out where the functionality is in the Next code and just disable it 
