Composables

useConvexQuery

Subscribe to reactive Convex queries with SSR support and automatic real-time updates.

Subscribe to a Convex query with SSR enabled by default. Data is fetched on the server for SEO and fast initial load, then subscribes for real-time updates on the client.

Usage

app/pages/tasks.vue
<script setup lang="ts">
import { api } from '#convex/api'

// SSR + real-time (default)
const { data: tasks, pending, error } = await useConvexQuery(api.tasks.list, { userId: 'user_123' })
</script>

<template>
  <div v-if="pending">
    Loading...
  </div>
  <div v-else-if="error">
    Error: {{ error.message }}
  </div>
  <ul v-else>
    <li v-for="task in tasks" :key="task._id">
      {{ task.title }}
    </li>
  </ul>
</template>

How it Works

PhaseBehavior
ServerMakes HTTP request to Convex (one-shot query)
HydrationClient receives pre-rendered HTML with data
ClientSubscribes to real-time updates via WebSocket

Parameters

ParameterTypeDescription
queryFunctionReferenceThe Convex query to subscribe
argsMaybeRefOrGetter<object>Arguments to pass to the query
optionsUseConvexQueryOptionsOptional configuration

Options

Extends Nuxt's AsyncDataOptions. Key options:

interface UseConvexQueryOptions {
  ssr?: boolean // Enable SSR fetch (default: true)
  lazy?: boolean // Don't block navigation (default: false)
  immediate?: boolean // Fetch immediately (default: true)
}

Return Values

Same as Nuxt's useAsyncData:

PropertyTypeDescription
dataRef<T | null>Query result
pendingRef<boolean>True while loading
errorRef<Error | null>Error if failed
refresh() => Promise<void>Re-fetch data
statusRef<string>Fetch status

Client-only Mode

Disable SSR for private data or when SEO isn't needed:

app/pages/dashboard.vue
<script setup lang="ts">
import { api } from '#convex/api'

// Client-only, no server fetch
const { data: tasks } = await useConvexQuery(api.tasks.list, { userId: 'user_123' }, { ssr: false })
</script>

When to Use SSR

ScenarioRecommended
Public pages (SEO important)SSR (default)
Private dashboards{ ssr: false }
Marketing/content pagesSSR (default)
Real-time chat/collaboration{ ssr: false }

Reactive Arguments

Pass reactive arguments to re-run the query when they change.

app/pages/tasks.vue
<script setup lang="ts">
import { api } from '#convex/api'

const userId = ref('user_123') // auto-imported
const { data: tasks } = await useConvexQuery(
  api.tasks.list,
  computed(() => ({ userId: userId.value }))
)

function switchUser(newUserId: string) {
  userId.value = newUserId // Query re-subscribes automatically
}
</script>

Limitations

Public queries only for SSR. Auth tokens are not passed to server-side queries. For authenticated data, use { ssr: false }.
Server-rendered data may be slightly outdated by the time the client hydrates. The real-time subscription automatically syncs the latest data after hydration.

SSG Support

Works with nuxi generate for static site generation:

nuxi generate

Data is fetched at build time and embedded in static HTML.