Guides
External Auth Backend
Use nuxt-better-auth with a separate Better Auth server.
When your Better Auth server runs on a separate backend (e.g., standalone h3/Nitro project, Express, or any other server), use clientOnly mode.
When to Use
- Microservices architecture: Auth service is a separate deployment
- Shared auth: Multiple frontends share one auth backend
- Existing backend: You already have a Better Auth server running elsewhere
Configuration
1. Enable Client-Only Mode
nuxt.config.ts
export default defineNuxtConfig({
modules: ['@onmax/nuxt-better-auth'],
auth: {
clientOnly: true,
},
})
2. Point the Client to the External Server
defineClientAuth is wrapped by the module at runtime, so baseURL here is overridden.
To target an external auth server, set the site URL:
.env
NUXT_PUBLIC_SITE_URL="https://auth.example.com"
This value becomes the Better Auth client base URL in client-only mode.
3. Configure Route Redirect Targets (Optional)
Control redirect paths directly in route auth rules:
nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
'/app/**': { auth: { only: 'user', redirectTo: '/login' } },
'/login': { auth: { only: 'guest', redirectTo: '/app' } },
},
})
What Changes in Client-Only Mode
| Feature | Full Mode | Client-Only |
|---|---|---|
server/auth.config.ts | Required | Not needed |
/api/auth/** handlers | Auto-registered | Skipped |
NUXT_BETTER_AUTH_SECRET | Required | Not needed |
| Server middleware | Enabled | Skipped |
| Schema generation | Enabled | Skipped |
| Devtools | Enabled | Skipped |
| SSR session hydration | Server-side | Client-side only |
useUserSession() | Works | Works |
| Route protection | Works | Works (client-side) |
<BetterAuthState> | Works | Works |
Important Notes
In client-only mode, all auth requests go directly to your external server. Ensure:
- CORS is configured on your auth server to allow requests from your frontend (with
credentials: true) - Cookies use
SameSite=None; Securefor cross-origin requests (HTTPS required) - Your auth server's
trustedOriginsincludes your frontend URL
In client-only mode,
NUXT_PUBLIC_SITE_URL is used as the auth client base URL.
Use routeRules.auth.redirectTo (or page meta auth.redirectTo) to control frontend navigation paths.Server utilities like
serverAuth(), getUserSession() and requireUserSession() are not available in client-only mode since there's no local auth server.SSR Considerations
In client-only mode, session data is fetched client-side only. This means:
- Server-rendered pages won't have access to session data during SSR
- Pages will initially render as "unauthenticated" and hydrate with session data on the client
- Use
<BetterAuthState>component to handle loading states gracefully
<template>
<BetterAuthState>
<template #default="{ user }">
<div v-if="user">Welcome, {{ user.name }}</div>
<div v-else>Please log in</div>
</template>
<template #placeholder>
<div>Loading...</div>
</template>
</BetterAuthState>
</template>
If you need SSR session hydration, consider using full mode with a local auth server instead.
Example Architecture
┌─────────────────┐ ┌─────────────────┐
│ Nuxt App │────▶│ Auth Server │
│ (clientOnly) │ │ (Better Auth) │
│ │◀────│ │
└─────────────────┘ └────────┬────────┘
│
┌────────▼────────┐
│ Database │
└─────────────────┘
Related
- Configuration - Module options reference
- Database-Less Mode - JWE sessions without database