How do I make server components re-fetch data every time they are loaded?
Unanswered
Belgian Shepherd posted this in #help-forum
Belgian ShepherdOP
I have learned that server components cache data they fetch. This means that every time I load a page using a back/forward button or a Link component, the data is old and not up to date if it had been changed since the first load. I have worked around this by creating a special DynamicLink component to run router.refresh() on click to force the next page to refresh the data. But I have no solution for back and forward buttons. For reference, here is a simple server component that I would like to have refetch the data each time it is loaded:
The
Does anyone have a solution for this? I have done a lot of research but have found nothing promising. I would prefer not to switch to client components if I do not have to. Thank you!
import { createClient } from '@/utils/supabase/server'
import { redirect } from 'next/navigation'
import { Navbar } from '@/components/Navbar/Navbar'
import RealmsMenu from './RealmsMenu/RealmsMenu'
export const dynamic = 'force-dynamic'
export default async function App() {
const supabase = createClient()
const { data: { user } } = await supabase.auth.getUser()
if (!user) {
return redirect('/signin')
}
const { data, error } = await supabase.from('realms').select('id, name').eq('owner_id', user.id)
const realms = data || []
const errorMessage = error?.message || ''
return (
<div>
<Navbar />
<h1 className='text-3xl pl-4 pt-4'>Your Realms</h1>
<RealmsMenu realms={realms} errorMessage={errorMessage}/>
</div>
)
}The
export const dynamic = 'force-dynamic' line only seems to make the server component re-fetch data after 30 seconds have passed, and it does nothing if you use back/forward arrows.Does anyone have a solution for this? I have done a lot of research but have found nothing promising. I would prefer not to switch to client components if I do not have to. Thank you!
6 Replies
Golden paper wasp
export const revalidate = 0;
export const dynamic = "force-dynamic";
give this a try...
export const dynamic = "force-dynamic";
give this a try...
@Belgian Shepherd what you are mentioning, the 30s thing is the client side router cache
https://nextjs.org/docs/app/building-your-application/caching#opting-out-3
https://nextjs.org/docs/app/building-your-application/caching#opting-out-3
so to fix it, in the place where you actually update your data.. make it revalidate the path
so that router cache gets purged when new data is added + you still have instant back and forward navigations
Belgian ShepherdOP
I added the revlidatePath call to the place where i update data:
does this look correct? i get this error when i run it:
Error: Invariant: static generation store missing in revalidatePath /app
this is running in a client component, does it need to be a server component?
if (data) {
revalidatePath('/app')
setModal('None')
toast.success('Your new realm has been created!')
router.push(`/editor/${data[0].id}`)
}does this look correct? i get this error when i run it:
Error: Invariant: static generation store missing in revalidatePath /app
this is running in a client component, does it need to be a server component?
call it from a server action @Belgian Shepherd