X Enterprises
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

KeyTypeDescription
userRef<AuthUser | null>The currently authenticated user, or null if not signed in.
isLoadingRef<boolean>true while any auth operation is in progress.
isAuthenticatedComputedRef<boolean>true when user is not null.
emailSentRef<boolean>true after forgotPassword or sendMagicLink succeeds.
codeSentRef<boolean>true after sendOtp succeeds.

Auth Methods

KeyTypeDescription
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

KeyTypeDescription
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() => voidResets emailSent and codeSent to false.

Info

KeyTypeDescription
providerTypeAuthProviderTypeThe active provider identifier ('stack', 'better-auth', 'neon-auth', or 'local').
configComputedRef<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.
Copyright © 2026