Request Lifecycle
Follow one query from immediate state through Nuxt SSR, live updates, and cleanup.
A Nuxt query exposes its Vue refs immediately while the transport changes underneath them.
const projects = useConvexQuery(api.projects.list)1. Nuxt creates the request context
During SSR, Nuxt creates a request-scoped application instance. Module runtime configuration and, when enabled, the Better Auth session belong to this request. No browser client is reused on the server.
2. Authentication settles
The default query auth mode is optional. It waits for initial auth settlement, then runs with the signed-in identity or anonymously.
required waits and remains idle if the request is anonymous. none ignores auth state and always runs through anonymous transport.
3. The server executes the query
Unless the call sets server: false, the module executes the Convex query over HTTP. The returned value or normalized error becomes Nuxt async data.
data.value === undefined means no value exists yet. A successful query may return null; that remains data and produces status.value === 'success'.
4. Nuxt renders and serializes
Vue renders with the query result. Nuxt serializes the value into the payload sent with the page. A public serialized ConvexCallError never retains a raw upstream cause.
5. Vue hydrates the existing result
The browser reads the Nuxt payload before mounting the component. The initial result is reused instead of replaced by a fresh loading state.
Hydration requires compatible server and client markup. Branch on explicit status and provide stable fallback structures when needed.
6. Live observation starts
The browser listens through the current Convex client. Later Convex updates replace data. Derive presentation shapes with Vue computed values so the query remains the raw server result.
Convex owns wire-level deduplication. Each composable owns only its Vue-visible state and listener lifecycle.
7. Arguments or identity may change
Reactive arguments start the next execution. With keepPreviousData: true, the last successful value can remain visible for the same identity and isStale becomes true while the new result is pending.
An identity change is stricter. Identity-owned data retires synchronously and cannot become stale data for another user.
8. The scope ends
When the owning Vue scope ends, its listener stops. The per-app runtime closes owned clients during app teardown.
Optional settlement barrier
The return value is also a native Promise. await projects produces a separate non-Promise view of the same refs after initial settlement. Success, query error, skip, and server: false resolve; inspect state for the result.
See SSR, hydration, and real-time for the rendering decision.