Next.js Discord

Discord Forum

How do I make server components re-fetch data every time they are loaded?

Unanswered
Belgian Shepherd posted this in #help-forum
Open in Discord
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:

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...
@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
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:
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