This library is in early development. Expect breaking changes.
API Reference

Server Utilities

API reference for server-side helpers available in Nitro event handlers.
These utilities are only available in full mode. In clientOnly mode, there is no local auth server, so these utilities are not registered.

serverAuth

Returns the initialized Better Auth instance (module-level singleton). Pass the event for accurate URL detection on first initialization.

server/api/admin/users.get.ts
export default defineEventHandler(async (event) => {
  const auth = serverAuth(event)
  const session = await auth.api.getSession({ headers: event.headers })

  if (!session) {
    throw createError({ statusCode: 401 })
  }

  return { user: session.user }
})

You can also pass query options to bypass cookie cache / refresh behavior:

await auth.api.getSession({
  headers: event.headers,
  query: { disableCookieCache: true },
})
Use serverAuth(event) in request handlers to access advanced Better Auth features not exposed by the helper wrappers. In non-request contexts, you can call serverAuth() without an event.

getUserSession

Retrieves the current session from the request context without throwing an error if unauthenticated.

server/api/example.ts
export default defineEventHandler(async (event) => {
  const session = await getUserSession(event)
  
  if (session) {
    // ...
  }
})

getUserSession does not create request-cache entries by itself. Use getRequestSession(event) when you need request-lifetime caching across middleware/handlers.

Returns:

  • { user: AuthUser, session: AuthSession } if authenticated.
  • null if unauthenticated.

getRequestSession

Retrieves the current session and memoizes it for the lifetime of the current request. In Nuxt and Nitro handlers, the helper stores the memoized value on event.context.requestSession.

server/api/example.ts
export default defineEventHandler(async (event) => {
  const requestSession = await getRequestSession(event)
  const sameRequestSession = await getRequestSession(event) // cached
})

Use this helper when multiple handlers/middleware in the same request need session access without repeating auth.api.getSession() calls.

getRequestSession stays type-compatible in projects that use narrowed h3 typings where H3Event does not explicitly declare context.

Session Enrichment with custom-session

Use Better Auth's custom-session plugin when your app needs computed fields in the session payload returned by server helpers. Define the enrichment in server/auth.config.ts, and getUserSession or getRequestSession will return the enriched shape.

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

export default defineServerAuth({
  plugins: [
    customSession(async ({ user, session }) => {
      return {
        user: {
          ...user,
          role: user.email?.endsWith('@company.com') ? 'member' : 'guest',
        },
        session: {
          ...session,
        },
      }
    }),
  ],
})
This uses Better Auth's plugin API and does not require a module-specific option.

requireUserSession

Ensures the user is authenticated and optionally matches specific criteria. Throws a 401 Unauthorized or 403 Forbidden error if checks fail.

const { user, session } = await requireUserSession(event, options?)
requireUserSession uses AuthUser and AuthSession from #nuxt-better-auth for both the returned value and option callbacks (user match + rule).

Options

user
UserMatch
Object matching user properties (see Route Protection).
rule
(ctx) => boolean | Promise<boolean>
Custom validation callback.

Examples

Role Check:

server/api/admin/dashboard.ts
await requireUserSession(event, {
  user: { role: 'admin' }
})

Custom Rule:

server/api/admin/dashboard.ts
await requireUserSession(event, {
  rule: ({ user }) => {
    return user.points > 100
  }
})

Combining User Matching with Rules

server/api/team/[teamId]/settings.ts
export default defineEventHandler(async (event) => {
  const { teamId } = getRouterParams(event)

  // Require admin role AND membership in the specific team
  await requireUserSession(event, {
    user: { role: 'admin' },
    rule: async (session) => {
      const membership = await getTeamMembership(session.user.id, teamId)
      return membership?.role === 'owner'
    }
  })

  return getTeamSettings(teamId)
})