Reactive arguments
Re-run a Convex query when filters, route parameters, or selected records change.
Query arguments can be a plain object, a ref, a computed value, or a getter. Each argument can also be a ref. Refs inside the object are unwrapped before execution.
Use props as arguments
const props = defineProps<{ projectId: Id<'projects'> }>()
const { projectId } = toRefs(props)
const { data: project } = useConvexQuery(api.projects.get, { projectId })When props.projectId changes, the composable requests the new project. Do not pass props.projectId directly: it is read once, and the query does not follow later changes.
Filter a list
const search = ref('')
const includeArchived = ref(false)
const args = computed(() => ({
search: search.value.trim(),
includeArchived: includeArchived.value,
}))
const projects = useConvexQuery(api.projects.search, args, {
keepPreviousData: true,
})When either input changes, the composable requests the new argument set.
Keep the previous result deliberately
With keepPreviousData: true:
- The previous successful
dataremains visible for the same identity. pendingbecomes true for the new arguments.isStalebecomes true.- The new successful result replaces the previous value.
<template>
<ProjectList :projects="projects.data.value ?? []" :dimmed="projects.isStale.value" />
</template>The default is false, which clears the old result for an explicit loading transition. When the signed-in user changes, the old data is always cleared, whatever this option says.
Skip incomplete arguments
Do not send placeholder IDs:
const args = computed(() => {
const id = route.params.projectId
return typeof id === 'string' ? { projectId: id } : 'skip'
})
const project = useConvexQuery(api.projects.get, args)Use only the literal 'skip'. null is valid Convex data, and undefined represents absent query data; neither is a public skip sentinel.
Auth-dependent execution
Prefer auth: 'required' over reading auth state only to skip a private query:
const projects = useConvexQuery(api.projects.mine, {}, { auth: 'required' })Use a computed 'skip' when another application condition also determines whether the query is meaningful.
Keep getters pure
Vue may evaluate a computed value more than once. Argument getters should only derive data. Do not navigate, mutate state, or perform network work inside them.