Sign In and Sign Out
Run integrated Better Auth operations and handle their identity lifecycle.
useConvexAuth() exposes the Better Auth client namespaces through the module's identity coordinator.
Email sign-in
const { client, isPending } = useConvexAuth()
if (!client) throw new Error('Authentication client unavailable')
const result = await client.signIn.email({
email: email.value,
password: password.value,
})
if (result.error) {
formError.value = 'Sign in could not be completed'
}Do not display raw credential errors if they reveal whether an account exists.
Sign-up
const { client } = useConvexAuth()
if (!client) throw new Error('Authentication client unavailable')
const result = await client.signUp.email({
name: name.value,
email: email.value,
password: password.value,
})The result depends on the Better Auth server options: email verification and autoSignIn determine the next product step.
Sign-out
const { client } = useConvexAuth()
if (!client) throw new Error('Authentication client unavailable')
await client.signOut()
await navigateTo('/')The application owns navigation. The auth coordinator owns session operation ordering, identity transition, query-state isolation, and client replacement.
Wait for settlement
Use ready() outside normal query gating when an application workflow must await initial auth settlement:
const status = await useConvexAuth().ready({ timeoutMs: 5_000 })Queries already implement their own auth-mode gating. Do not call ready() before every query.
Operation state versus identity state
isPending can be true while status remains authenticated. Keep the current authenticated UI visible during a background refresh unless the product has a specific reason to block it.
Failures across identity changes
An in-flight mutation, action, or imperative call tied to the previous identity rejects with IDENTITY_CHANGED. The UI should stop presenting its result under the new user. Do not automatically retry a write because it may already have committed.