Auth State and User Data
Read session state and choose the correct source for user fields.
useConvexAuth() answers whether a usable identity exists. useConvexUser() upgrades session user data to a canonical queried source when the product needs it.
Auth state
const { status, isPending, isAuthenticated, user, error, ready } = useConvexAuth()status describes the current usable identity. isPending describes auth work in flight. Keep them separate in UI logic.
Use this app-lifetime observer for route identity. On the pinned Better Auth tuple, do not mount client.useSession() in route components; remounting its auth-query atom can leave session state stale. Reserve client for plugin-specific methods.
<template>
<ConvexAuthLoading>Checking session…</ConvexAuthLoading>
<ConvexAuthenticated>Welcome, {{ user?.name ?? user?.email }}</ConvexAuthenticated>
<ConvexUnauthenticated><SignInLink /></ConvexUnauthenticated>
<ConvexAuthError v-slot="{ error, retry }">
<button @click="retry">{{ error?.message ?? 'Retry authentication' }}</button>
</ConvexAuthError>
</template>Choose a user-data source
| Data | Source |
|---|---|
| Name/email needed immediately during SSR | useConvexAuth().user session seed |
| Canonical Better Auth user fields | Better Auth component query through useConvexUser |
| Product profile, preferences, searchable display data | Explicit application projection |
| Small identity fields needed in every Convex function | JWT claims |
Do not put frequently changing permissions only in JWT claims. Their value can remain stale until token refresh.
Upgrade the session seed
const currentUser = useConvexUser(
api.users.getCurrent,
{},
{
source: 'projection',
seedFromSession: true,
},
)The returned state is discriminated:
{ source: 'none', data: null }
{ source: 'session', data: ConvexUser }
{ source: 'better-auth', data: CanonicalUser }
{ source: 'projection', data: ProjectedUser }The helper skips its query while anonymous, runs client-side after auth, and defaults to a live subscription.
Disabled auth
With auth: false, status is disabled, the user is null, and auth operations reject with an authentication error. ConvexUnauthenticated renders for both anonymous and disabled.