refreshNuxtData does not update server-side data – stale SSR content after page reload #32813
-
I'm using However, when I reload the page (F5), the server still sends old data — even though
What I expect:Calling What I observe:Server returns previously cached data, even though I refreshed it on the client before reload. Question:
Thanks in advance! P.S. the code: import type { FetchError } from 'ofetch'
import type { AsyncDataRequestStatus } from '#app'
import type { ConceptDto, CreateConceptDto, ExtendedConceptDto, UpdateConceptDto } from '#shared/schemas/types/concept'
const key = 'concepts'
export const useConcepts = createSharedComposable(() => {
const { data: entities } = useNuxtData<ExtendedConceptDto[]>(key)
const status = ref<AsyncDataRequestStatus>('idle')
const pending = ref(false)
const error = ref<FetchError>()
const actions = {
async load() {
const result = await useLazyFetch('/api/concepts', { key, default: () => [] })
syncRefs(result.status, status)
syncRefs(result.pending, pending)
syncRefs(result.error, error)
return result
},
async create(data: CreateConceptDto) {
const entity = await $fetch('/api/concepts', { method: 'POST', body: data })
await refreshNuxtData(key)
return entity
},
async update(id: string, data: UpdateConceptDto) {
const entity = await $fetch<ConceptDto>(`/api/concepts/${id}`, { method: 'PUT', body: data })
await refreshNuxtData(key)
return entity
},
async delete(id: string) {
await $fetch<ConceptDto>(`/api/concepts/${id}`, { method: 'DELETE' })
await refreshNuxtData(key)
},
}
return reactive({ ...actions, entities, status, pending, error })
}) // app.vue
const concepts = useConcepts()
await concepts.load() |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 7 replies
-
refreshNuxtData(key) only invalidates the client-side cache, not the server-side cached response used in SSR. option 1: Option 2: Invalidate SSR cache using a manual version or timestamp const cacheBuster = useState('concepts-version', () => Date.now()) const { data: entities } = await useLazyFetch('/api/concepts', { const refreshConcepts = () => { Then after mutation, do this: await $fetch('/api/concepts', { method: 'POST', body: data }) |
Beta Was this translation helpful? Give feedback.
-
I’m not sure how I fixed it, but I no longer get hydration warnings, and the data is consistently in sync now. The updated code is mostly the same — the only thing I did was delete node_modules and reinstall everything from scratch. import type { FetchError } from 'ofetch'
import type { AsyncDataRequestStatus } from '#app'
import type { ConceptDto, CreateConceptDto, ExtendedConceptDto, UpdateConceptDto } from '#shared/schemas/types/concept'
const key = 'concepts'
export const useConcepts = defineStore(key, () => {
const { data } = useNuxtData<ExtendedConceptDto[]>(key)
const entities = computed(() => data.value ?? [])
const status = ref<AsyncDataRequestStatus>('idle')
const pending = ref(false)
const error = shallowRef<FetchError>()
const actions = {
async init() {
const result = useLazyFetch('/api/concepts', { key, default: () => [] })
syncRefs(result.status, status)
syncRefs(result.pending, pending)
syncRefs(result.error, error)
return result
},
async refresh() {
await refreshNuxtData(key)
},
clear() {
clearNuxtData(key)
},
async create(data: CreateConceptDto) {
const entity = await $fetch('/api/concepts', { method: 'POST', body: data })
void actions.refresh()
return entity
},
async update(id: string, data: UpdateConceptDto) {
const entity = await $fetch<ConceptDto>(`/api/concepts/${id}`, { method: 'PUT', body: data })
void actions.refresh()
return entity
},
async delete(id: string) {
await $fetch<ConceptDto>(`/api/concepts/${id}`, { method: 'DELETE' })
void actions.refresh()
},
}
return { ...actions, entities, status, pending, error }
}) |
Beta Was this translation helpful? Give feedback.
Another thing I did was replace the shared composable with a Pinia store — that seems to have done the trick.