Share Query State
Share one Vue query state across components without adding a second entity cache.
Identical normal queries already benefit from Convex wire deduplication. Use defineSharedConvexQuery when components must also share the same Vue state, transform, and refresh lifecycle.
Define the shared query once
import { api } from '#convex/api'
export const useCurrentOrganization = defineSharedConvexQuery({
key: 'current-organization',
query: api.organizations.current,
args: {},
options: {
auth: 'required',
transform: (organization) =>
organization ? { id: organization._id, name: organization.name } : null,
},
})Consume it in any setup scope:
const { data: organization, status, refresh } = useCurrentOrganization()Reactive shared arguments
import { api } from '#convex/api'
const selectedProjectId = ref<string | null>(null)
export const useSelectedProject = defineSharedConvexQuery({
key: 'selected-project',
query: api.projects.get,
args: () => (selectedProjectId.value ? { projectId: selectedProjectId.value } : 'skip'),
options: { auth: 'required' },
})The closure returned by defineSharedConvexQuery is the real definition identity. The diagnostic key does not merge unrelated definitions.
Lifetime
One shared state is created per Nuxt app instance. On the browser it lives until app teardown. During SSR it remains request-scoped.
Identity isolation is unchanged. A shared private result clears when the stable identity changes.
When not to share
Use separate normal queries when:
- components need different transforms;
- their error or loading state should be independent;
- the query is mounted in only one place;
- Convex wire deduplication already solves the actual concern.
Do not create one global shared query registry. Each exported definition is explicit, typed, and independently owned.