Is there any way to persist data from server to client in SSR apart from using "store" in SSRContext? The docs mostly mention Vuex, even though Vuex is deprecated. I'm using @tanstack/vue-query, which saves a lot of headaches when managing async or server state. It manages deduping requests, retries, query caching and invalidation, gabarge collection, query refetching, infinite queries, and so much more. In the docs, the guidelines for integrating with Vite SSR are:
// main.js (entry point)
import App from './App.vue'
import viteSSR from 'vite-ssr/vue'
import {
QueryClient,
VueQueryPlugin,
hydrate,
dehydrate,
} from '@tanstack/vue-query'
export default viteSSR(App, { routes: [] }, ({ app, initialState }) => {
// -- This is Vite SSR main hook, which is called once per request
// Create a fresh VueQuery client
const queryClient = new QueryClient()
// Sync initialState with the client state
if (import.meta.env.SSR) {
// Indicate how to access and serialize VueQuery state during SSR
initialState.vueQueryState = { toJSON: () => dehydrate(queryClient) }
} else {
// Reuse the existing state in the browser
hydrate(queryClient, initialState.vueQueryState)
}
// Mount and provide the client to the app components
app.use(VueQueryPlugin, { queryClient })
})
Then in the Vue component:
<!-- MyComponent.vue -->
<template>
<div>
<button @click="refetch">Refetch</button>
<p>{{ data }}</p>
</div>
</template>
<script setup>
import { useQuery } from '@tanstack/vue-query'
import { onServerPrefetch } from 'vue'
// This will be prefetched and sent from the server
const { refetch, data, suspense } = useQuery({
queryKey: ['todos'],
queryFn: getTodos,
})
onServerPrefetch(suspense)
</script>
I tried the same with boot files Quasar SSR, replacing initialState with ssrContext but it reads as undefined on the client.
Here is what I tried:
import { boot } from 'quasar/wrappers'
import { QueryClient, VueQueryPlugin, dehydrate, keepPreviousData } from '@tanstack/vue-query'
import { hydrate } from 'vue'
export default boot(({ app, ssrContext }) => {
const globalQueryClient = new QueryClient({
defaultOptions: {
queries: {
networkMode: 'always',
placeholderData: keepPreviousData,
retry: false,
staleTime: 1000 * 60 * 5 // 5 minutes
}
}
})
if (process.env.SERVER) {
// Indicate how to access and serialize VueQuery state during SSR
ssrContext.vueQueryState = { toJSON: () => dehydrate(globalQueryClient) }
} else {
// Reuse the existing state in the browser
hydrate(globalQueryClient, ssrContext.vueQueryState)
}
app.use(VueQueryPlugin, { queryClient: globalQueryClient })
})
vueQueryState was undefined on the client.