This library is in early development. Expect breaking changes.
Core Concepts

Sessions

Access reactive session state with SSR support using `useUserSession()`.
pages/dashboard.vue
const {
  user,
  session,
  loggedIn,
  ready,
  signIn,
  signUp,
  signOut,
  fetchSession,
} = useUserSession()

SSR behavior

During server-side rendering (SSR), the module attempts to fetch the session using the incoming request cookies and populates state before rendering. A client plugin then keeps the state in sync after hydration.

  • Server render: user and session are set when a valid session cookie exists, ready is true
  • After hydration: state stays in sync with client-side updates

For prerendered or cached pages, the client plugin fetches the session after mount. Use ready or <BetterAuthState> to avoid flashes in those cases.

Database sessions (default): stored in DB, revocable, visible in admin JWE sessions (database-less): encrypted cookie, no server storage

Handling Loading State

pages/protected.vue
<script setup lang="ts">
const { user, loggedIn, ready } = useUserSession()
</script>

<template>
  <div v-if="!ready">Loading...</div>
  <div v-else-if="loggedIn">Welcome, {{ user?.name }}</div>
  <div v-else>Please log in</div>
</template>

Server-Side Session Access

For server handlers and API routes, use the server utilities:

server/api/profile.get.ts
export default defineEventHandler(async (event) => {
  const { user } = await requireUserSession(event)
  return { id: user.id, email: user.email }
})

Session Refresh

Force refresh the session data:

<script setup lang="ts">
const { fetchSession, ready } = useUserSession()
</script>

<template>
  <button :disabled="!ready" @click="fetchSession({ force: true })">
    Refresh session
  </button>
</template>

Session Lifetime

Configure session duration in your auth config:

server/auth.config.ts
import { defineServerAuth } from '@onmax/nuxt-better-auth/config'

export default defineServerAuth({
  session: {
    expiresIn: 60 * 60 * 24 * 7, // 7 days
    cookieCache: {
      enabled: true,
      maxAge: 5 * 60, // 5 minutes
    },
  },
})