Skip to content

Nuxt SSR ​

Framework

Vue · Nuxt 3 / 4 · tanstack-fetch/vue · @tanstack/vue-query

On the server, ssr-forward attaches Cookie / Authorization from the incoming request. In the browser the plugin skips.

Plugin ​

ts
// plugins/tanstack-fetch.ts
import { createFetch } from 'tanstack-fetch'
import { createFetchPlugin } from 'tanstack-fetch/vue'

export default defineNuxtPlugin((nuxtApp) => {
  const config = useRuntimeConfig()

  const api = createFetch({
    baseUrl: config.public.apiBase as string,
    source: import.meta.server ? 'ssr' : 'client',
    plugins: ['ssr-forward', 'trace', 'retry-idempotent'],
    incoming: () => {
      if (!import.meta.server) return undefined
      const headers = useRequestHeaders(['cookie', 'authorization', 'x-request-id'])
      return {
        cookie: headers.cookie,
        authorization: headers.authorization,
        requestId: headers['x-request-id'],
      }
    },
  })

  nuxtApp.vueApp.use(createFetchPlugin({ client: api }))
  return { provide: { api } }
})

Page with Vue Query ​

vue
<script setup lang="ts">
import { useQuery } from '@tanstack/vue-query'
import { useFetch as useFetchClient } from 'tanstack-fetch/vue'

type User = { id: string; name: string }

const api = useFetchClient()

const { data, isPending, error } = useQuery({
  queryKey: ['users'],
  queryFn: ({ signal }) => api.get<User[]>('/users', { signal }),
})
</script>

<template>
  <p v-if="isPending">Loading…</p>
  <ul v-else>
    <li v-for="user in data" :key="user.id">{{ user.name }}</li>
  </ul>
</template>

Vue Query hydrate (optional) ​

ts
// plugins/vue-query.ts
import { VueQueryPlugin, QueryClient, dehydrate, hydrate } from '@tanstack/vue-query'

export default defineNuxtPlugin((nuxtApp) => {
  const queryClient = new QueryClient()

  if (import.meta.server) {
    nuxtApp.hooks.hook('app:rendered', () => {
      nuxtApp.payload.vueQueryState = dehydrate(queryClient)
    })
  }

  if (import.meta.client) {
    hydrate(queryClient, nuxtApp.payload.vueQueryState)
  }

  nuxtApp.vueApp.use(VueQueryPlugin, { queryClient })
})

Guide: SSR · Vue & Nuxt · compare: Next.js SSR

MIT Licensed · Created by Mohammad Garmabi · Not an official TanStack package