Tanstack Query use with Nuxt ISR payload extraction #11232
|
The docs describe integrating Tanstack Query via a plugin like this: https://tanstack.com/query/latest/docs/framework/vue/guides/ssr#nuxt-3 We have tried to integrate Vercel ISR in our project and ran into the issue that this only works on initial hydration. We do not benefit from the feature introduced in Nuxt 3.21.0 where navigation does hydrate the payload of the target site, as the Tanstack Query client state does only get dehydrated into the So instead, we are now putting the dehydrated state directly into the nuxt payload like this: import type { DehydratedState, VueQueryPluginOptions } from '@tanstack/vue-query'
import { VueQueryPlugin, QueryClient, hydrate, dehydrate } from '@tanstack/vue-query'
const payloadKey = 'vue-query-statamic'
export default defineNuxtPlugin((nuxt) => {
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: Infinity, // queries should never be stale until manually invalidated
},
},
})
const options: VueQueryPluginOptions = { queryClient }
nuxt.vueApp.use(VueQueryPlugin, options)
if (import.meta.server) {
nuxt.hooks.hook('app:rendered', () => {
nuxt.payload.data[payloadKey] = dehydrate(queryClient)
})
}
if (import.meta.client) {
let hydratedState = nuxt.payload.data[payloadKey] as DehydratedState | undefined
hydrate(queryClient, hydratedState)
useRouter().beforeResolve(() => {
const state = nuxt.static.data[payloadKey] as DehydratedState | undefined
if (state && state !== hydratedState) {
hydrate(queryClient, state)
hydratedState = state
}
})
}
return {
provide: {
queryClient,
},
}
})Works like a charm but the question is: are we missing some downside with this approach? |
Replies: 2 comments 1 reply
This comment was marked as spam.
This comment was marked as spam.
|
In Nuxt 3 with ISR and payload extraction, Putting the dehydrated state into import { VueQueryPlugin, QueryClient, hydrate, dehydrate } from '@tanstack/vue-query'
import type { DehydratedState } from '@tanstack/vue-query'
export default defineNuxtPlugin((nuxtApp) => {
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60 * 5, // 5 mins
},
},
})
nuxtApp.vueApp.use(VueQueryPlugin, { queryClient })
const payloadKey = 'vueQueryState'
if (import.meta.server) {
nuxtApp.hooks.hook('app:rendered', () => {
nuxtApp.payload[payloadKey] = dehydrate(queryClient)
})
}
if (import.meta.client) {
nuxtApp.hooks.hook('app:created', () => {
const state = nuxtApp.payload[payloadKey] as DehydratedState | undefined
if (state) {
hydrate(queryClient, state)
}
})
}
})Using the |
In Nuxt 3 with ISR and payload extraction,
useNuxtApp().payloadneeds to preserve dehydrated state across navigation boundaries (stored in_payload.json).Putting the dehydrated state into
useNuxtApp().payload[payloadKey]inside your plugin is the correct approach for Nuxt 3.21+ payload extraction. To ensure smooth client hydration on both initial load and soft navigation: