Query Ownership and Caching
Understand where query results live and when to share state instead of copying it.
“Cache” can refer to several different owners in one Nuxt page. Distinguishing them prevents duplicate state.
Where state lives
| State | Owner | Lifetime |
|---|---|---|
| Convex query result and wire deduplication | Current Convex client | Client lifetime and identity generation |
| SSR result | Nuxt payload/async data | Request and hydrated payload |
data, error, status, transform | Composable instance | Vue effect scope |
| Shared Vue query state | One defineSharedConvexQuery closure | Nuxt app instance |
| Optimistic overlay | Convex client plus helper update | Until server confirmation or rollback |
| UI-only state | Component or application store | Application-defined |
There is no separate Better Convex Nuxt entity cache.
Identical subscriptions
Two mounted components may request the same Convex query and arguments. Convex owns wire-level subscription deduplication. The module does not maintain a parallel subscription registry.
Each composable still has its own Vue-visible state. That is useful when components apply different transforms or loading presentation.
Share Vue state deliberately
Use defineSharedConvexQuery when multiple components must consume the same transformed state and lifecycle:
// app/composables/useCurrentTeam.ts
import { api } from '#convex/api'
export const useCurrentTeam = defineSharedConvexQuery({
key: 'current-team',
query: api.teams.current,
args: {},
options: { auth: 'required' },
})const { data: team, status } = useCurrentTeam()The returned closure is the definition identity. It creates one shared state per Nuxt app. The string key is for diagnostics; it is not a global registry key.
Reactive argument identity
A query is identified by its function reference, normalized arguments, auth boundary, and current identity generation. Changing arguments creates a new requested result.
keepPreviousData: true may retain the previous result while new arguments load. It never carries data across an identity boundary.
Convex data versus Pinia
Keep server-backed entities in Convex queries. Use Pinia or local refs for UI state such as:
- open panels and dialogs;
- unsaved local drafts;
- wizard progress;
- client preferences that are not server data.
Copying query entities into Pinia creates synchronization work: refresh, optimistic rollback, sign-out clearing, and live update reconciliation all gain a second implementation.
No cross-request cache promise
A shared query definition does not cache results between SSR requests. Each server request has its own Nuxt app and identity context.
If a deployment adds HTTP or page caching, its privacy and invalidation rules belong to that deployment layer. Read performance before caching authenticated pages.