This library is in early development. Expect breaking changes.
Guides

Role‑Based Access

Protect routes using generic field matching on AuthUser.

With Admin Plugin

server/auth.config.ts
import { admin } from 'better-auth/plugins'
import { defineServerAuth } from '@onmax/nuxt-better-auth/config'
export default defineServerAuth({ plugins: [admin()] })

// nuxt.config.ts - role is now typed!
routeRules: {
  '/admin/**': { auth: { user: { role: 'admin' } } },
  '/staff/**': { auth: { user: { role: ['admin', 'moderator'] } } },
}

With Organization Plugin

nuxt.config.ts
// Works the same way with any plugin fields
routeRules: {
  '/team/**': { auth: { user: { teamRole: 'owner' } } },
}

With Custom Fields

nuxt.config.ts
// Any field on AuthUser works
routeRules: {
  '/premium/**': { auth: { user: { isPremium: true } } },
  '/verified/**': { auth: { user: { emailVerified: true } } },
}

Matching Logic

  • Single value: exact match required
  • Array: OR logic (user field must be one of the values)
  • Multiple fields: AND logic (all must match)
// Must be admin AND verified
{ auth: { user: { role: 'admin', emailVerified: true } } }

// Must be admin OR moderator
{ auth: { user: { role: ['admin', 'moderator'] } } }

Complex Logic

For complex authorization, use custom middleware or requireUserSession with a rule callback.

Complex Authorization with Rule Callbacks

For authorization logic that can't be expressed with field matching:

nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    '/admin/**': {
      auth: {
        rule: (session) => {
          // User must be admin AND have verified email
          return session.user.role === 'admin' && session.user.emailVerified
        }
      }
    }
  }
})
server/api/reports.ts
export default defineEventHandler(async (event) => {
  await requireUserSession(event, {
    rule: (session) => {
      // User must have 'reports:read' permission
      return session.user.permissions?.includes('reports:read')
    }
  })

  return getReports()
})