Composables
useXAuth
Provider-agnostic authentication composable — unified interface for Stack Auth, Better Auth, Neon Auth, and Local JWT backends.
useXAuth
The core composable of nuxt-x-auth. Reads appConfig.xAuth.provider at call time and delegates every method to the matching provider adapter (useStackAuthProvider, useBetterAuthProvider, useNeonAuthProvider, or useLocalAuthProvider). All adapters implement the same AuthProvider interface — your components and pages work identically regardless of the configured backend. Swapping providers requires only changing the provider value in app.config.ts.
Usage
const {
// State
user,
isLoading,
isAuthenticated,
emailSent,
codeSent,
// Core
login,
signup,
logout,
// Password
forgotPassword,
resetPassword,
// OAuth
loginWithProvider,
// OTP
sendOtp,
verifyOtp,
// Magic Link
sendMagicLink,
handleMagicLinkCallback,
// Utilities
getCurrentUser,
getToken,
getAuthHeaders,
resetState,
// Info
providerType,
config,
} = useXAuth()
Returns
State
| Key | Type | Description |
|---|---|---|
user | Ref<AuthUser | null> | The currently authenticated user, or null if not signed in. |
isLoading | Ref<boolean> | true while any auth operation is in progress. |
isAuthenticated | ComputedRef<boolean> | true when user is not null. |
emailSent | Ref<boolean> | true after forgotPassword or sendMagicLink succeeds. |
codeSent | Ref<boolean> | true after sendOtp succeeds. |
Auth Methods
| Key | Type | Description |
|---|---|---|
login | (email: string, password: string) => Promise<AuthUser | null> | Signs in with email and password. Returns the user on success or null on failure. |
signup | (email: string, password: string) => Promise<AuthUser | null> | Creates a new account. Returns the user on success or null on failure. |
logout | () => Promise<boolean> | Signs out the current user. Clears state and redirects to redirects.afterLogout. |
forgotPassword | (email: string) => Promise<boolean> | Sends a password reset email. Sets emailSent to true on success. |
resetPassword | (code: string, newPassword: string) => Promise<true | { error: string }> | Applies a new password using the reset code from the email link. |
loginWithProvider | (providerName: string, options?: object) => Promise<boolean> | Initiates an OAuth flow with the named provider (e.g. 'google', 'github'). |
sendOtp | (email: string) => Promise<boolean> | Sends an OTP code to the email. Sets codeSent to true on success. |
verifyOtp | (code: string) => Promise<AuthUser | null> | Verifies the OTP code and signs the user in. |
sendMagicLink | (email: string, options?: object) => Promise<boolean> | Sends a magic link email. Sets emailSent to true on success. |
handleMagicLinkCallback | (code: string) => Promise<true | { error: string }> | Completes the magic link sign-in from the callback URL. |
Utilities
| Key | Type | Description |
|---|---|---|
getCurrentUser | () => Promise<AuthUser | null> | Re-fetches the current user from the provider and updates user. |
getToken | () => Promise<string | null> | Returns the current access token, or null if not authenticated. |
getAuthHeaders | () => Promise<Record<string, string>> | Returns { Authorization: 'Bearer <token>' } for use in API calls. |
resetState | () => void | Resets emailSent and codeSent to false. |
Info
| Key | Type | Description |
|---|---|---|
providerType | AuthProviderType | The active provider identifier ('stack', 'better-auth', 'neon-auth', or 'local'). |
config | ComputedRef<AuthConfig> | Reactive reference to the full xAuth app config. |
AuthUser Shape
All providers normalize their user data to this shared structure:
{
id: string
email: string
name: string
avatar?: string
emailVerified: boolean
metadata?: Record<string, any>
}
AuthProvider Interface
Every provider adapter implements this interface, which useXAuth delegates to:
interface AuthProvider {
user: Ref<AuthUser | null>
isLoading: Ref<boolean>
isAuthenticated: ComputedRef<boolean>
emailSent: Ref<boolean>
codeSent: Ref<boolean>
login(email: string, password: string): Promise<AuthUser | null>
signup(email: string, password: string): Promise<AuthUser | null>
logout(): Promise<boolean>
forgotPassword(email: string): Promise<boolean>
resetPassword(code: string, newPassword: string): Promise<true | { error: string }>
loginWithProvider(providerName: string, options?: object): Promise<boolean>
sendOtp(email: string): Promise<boolean>
verifyOtp(code: string): Promise<AuthUser | null>
sendMagicLink(email: string, options?: object): Promise<boolean>
handleMagicLinkCallback(code: string): Promise<true | { error: string }>
getCurrentUser(): Promise<AuthUser | null>
getToken(): Promise<string | null>
getAuthHeaders(): Promise<Record<string, string>>
resetState(): void
}
Examples
// Email/password login
const user = await login('user@example.com', 'password')
// OAuth sign-in
await loginWithProvider('google')
// OTP flow
await sendOtp('user@example.com') // sends code, sets codeSent = true
await verifyOtp('123456') // signs in, returns user
// Magic link flow
await sendMagicLink('user@example.com')
// User clicks link → lands on /auth/handler/magic-link-callback
// That page calls:
await handleMagicLinkCallback(route.query.code)
// Make an authenticated API call
const headers = await getAuthHeaders()
// { Authorization: 'Bearer eyJ...' }
// Check provider at runtime
if (providerType === 'local') {
// local-only logic
}
<script setup>
const { user, isAuthenticated, logout } = useXAuth()
</script>
<template>
<div v-if="isAuthenticated">
Welcome, {{ user?.name }}
<UButton @click="logout">Sign Out</UButton>
</div>
<XAuthLogin v-else />
</template>
AI Context
composable: useXAuth
package: "@xenterprises/nuxt-x-auth"
use-when: >
All authentication operations in a Nuxt app using the nuxt-x-auth layer:
login, signup, logout, OAuth, OTP, magic links, password reset, fetching
the current user, and retrieving auth tokens for API calls. Provider is
configured once in app.config.ts — no code changes needed to switch backends.
The AuthProvider interface documents every method the composable exposes.
