Skip to main content

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

ts
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.

vue
<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

DataSource
Name/email needed immediately during SSRuseConvexAuth().user session seed
Canonical Better Auth user fieldsBetter Auth component query through useConvexUser
Product profile, preferences, searchable display dataExplicit application projection
Small identity fields needed in every Convex functionJWT claims

Do not put frequently changing permissions only in JWT claims. Their value can remain stale until token refresh.

Upgrade the session seed

ts
const currentUser = useConvexUser(
  api.users.getCurrent,
  {},
  {
    source: 'projection',
    seedFromSession: true,
  },
)

The returned state is discriminated:

ts
{ 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.