diff --git a/README.md b/README.md
index 1dfb804b..c068da7f 100644
--- a/README.md
+++ b/README.md
@@ -1,27 +1,70 @@
-
-
-
- Designed by HugoRCD
-
+# `@onmax/nuxt-better-auth`
-@onmax/nuxt-better-auth
+Nuxt module for [Better Auth](https://better-auth.com) with Nuxt-native route protection, SSR-safe session access, auto-imported helpers, and optional NuxtHub-backed schema generation.
-Nuxt module for Better Auth
+> [!WARNING]
+> This package is still in alpha. Expect API and behavior changes before a stable release.
-
-
-
-
-
-
+## Who this is for
-> [!WARNING]
-> This library is a work in progress and not ready for production use.
+Use this module if you want Better Auth in a Nuxt 4 app and you want the Nuxt-specific pieces handled for you:
+
+- `useUserSession()` for reactive auth state
+- `requireUserSession(event)` and related server helpers
+- route protection through `routeRules` and `definePageMeta({ auth })`
+- generated `server/auth.config.ts` and `app/auth.config.ts`
+- optional NuxtHub database integration and schema generation
+
+## Install the module
+
+For the fastest path in a Nuxt 4 app:
+
+```bash
+npx nuxi module add @onmax/nuxt-better-auth@alpha
+```
+
+Then create or confirm these files:
+
+- `server/auth.config.ts`
+- `app/auth.config.ts`
+- `.env` with `NUXT_BETTER_AUTH_SECRET`
+
+For the full setup flow, follow the [installation guide](https://better-auth.nuxt.dev/getting-started/installation).
+
+## Choose your setup path
+
+- Use [NuxtHub integration](https://better-auth.nuxt.dev/integrations/nuxthub) if you want the shortest path to database-backed auth.
+- Use [custom database setup](https://better-auth.nuxt.dev/guides/custom-database) if you already have your own database stack.
+- Use [external auth backend](https://better-auth.nuxt.dev/guides/external-auth-backend) if Better Auth runs in a separate service.
+- Use [database-less mode](https://better-auth.nuxt.dev/guides/database-less-mode) for stateless or OAuth-first setups with clear tradeoffs.
## Documentation
-**[better-auth.nuxt.dev](https://better-auth.nuxt.dev/)**
+The documentation site is at [better-auth.nuxt.dev](https://better-auth.nuxt.dev).
+
+Recommended reading order:
+
+1. [Quickstart](https://better-auth.nuxt.dev/getting-started)
+2. [Installation](https://better-auth.nuxt.dev/getting-started/installation)
+3. [Configuration](https://better-auth.nuxt.dev/getting-started/configuration)
+4. [Client setup](https://better-auth.nuxt.dev/getting-started/client-setup)
+5. [Route protection](https://better-auth.nuxt.dev/core-concepts/route-protection)
+
+## Development
+
+```bash
+pnpm install
+pnpm dev:docs
+```
+
+Useful commands:
+
+- `pnpm dev` to run the playground
+- `pnpm dev:docs` to run the docs site
+- `pnpm lint` to lint the repo
+- `pnpm test` to run the test suite
+- `pnpm build:docs` to build the docs site
## License
-MIT
+[MIT](https://github.com/nuxt-modules/better-auth/blob/main/LICENSE)
diff --git a/docs/content/1.getting-started/0.index.md b/docs/content/1.getting-started/0.index.md
index a891cddf..60e8fbaf 100644
--- a/docs/content/1.getting-started/0.index.md
+++ b/docs/content/1.getting-started/0.index.md
@@ -4,112 +4,93 @@ description: Nuxt Better Auth integrates Better Auth with Nuxt for route protect
navigation.icon: i-lucide-sparkles
---
-Nuxt Better Auth integrates **Nuxt** and **Better Auth**, the TypeScript-first authentication library. You get route protection, session management, and schema generation with minimal setup. The plugin ecosystem adds features like 2FA, organizations, and passkeys.
+Use this page when you want the fastest path to a working Nuxt 4 setup.
-::card{to="https://demo-nuxt-better-auth.onmax.me" target="_blank" icon="i-lucide-external-link"}
-**Live Demo** – Try the authentication flow in action.
-::
+This quickstart assumes:
-## Features
+- you want the default full-mode setup
+- you are using `pnpm`
+- you want a local login flow working before you customize providers or plugins
-This module brings Nuxt-specific enhancements on top of Better Auth:
+If you already know you need a different architecture, jump to [NuxtHub](/integrations/nuxthub), [custom database](/guides/custom-database), or [external auth backend](/guides/external-auth-backend).
-::docs-features
----
-features:
- - title: Auto Configuration
- description: Auto-wires API routes, middleware, and schema with sensible defaults
- - title: Route Protection
- description: Declarative page and API route guards
- - title: Schema Generation
- description: Auto-generate Drizzle schemas
- - title: Reactive Sessions
- description: "`useUserSession()` with SSR support"
- - title: Database Flexibility
- description: Works standalone or with NuxtHub
- - title: Type Safety
- description: Full TypeScript inference
- - title: Auto Imports
- description: Composables and utils ready to use
- - title: Server Utilities
- description: Auth helpers for your API routes
- - title: Powered by Better Auth
- description: 2FA, OAuth, SSO, organizations, and more
- href: https://www.better-auth.com
----
-::
+## What you will end up with
-## Why Nuxt Better Auth?
+After this guide you should have:
-Building authentication from scratch is hard. Wiring up Better Auth with Nuxt manually involves:
-- Setting up API handlers
-- Syncing client/server state
-- Handling redirects
-- Managing database schemas (if using a database)
+- `server/auth.config.ts` and `app/auth.config.ts`
+- Better Auth handlers mounted at `/api/auth/*`
+- a valid `NUXT_BETTER_AUTH_SECRET`
+- a reactive `useUserSession()` composable in your app
-This module does all of that for you. Just configure your auth providers and the module handles the rest.
+## Before you begin
-## Quick Start
+- Nuxt `4.x`
+- a local `.env` file
+- a development server you can start with `pnpm dev`
-Get a working login in 5 minutes with NuxtHub (SQLite).
+## Quickstart
::steps
-### Install
+### Install the module
```bash
-npx nuxi module add @onmax/nuxt-better-auth@alpha @nuxthub/core
+npx nuxi module add @onmax/nuxt-better-auth@alpha
```
-### Configure
+### Add your secret
-```ts [nuxt.config.ts]
-export default defineNuxtConfig({
- hub: { db: 'sqlite' },
-})
-```
+Create or update `.env`:
```ini [.env]
-NUXT_BETTER_AUTH_SECRET="generate-a-32-char-secret"
+NUXT_BETTER_AUTH_SECRET="replace-with-a-random-32-character-secret"
```
-### Create Config Files
+Use a high-entropy value. The module also accepts `BETTER_AUTH_SECRET` as a fallback, but `NUXT_BETTER_AUTH_SECRET` is the recommended variable.
+
+### Create the server config
```ts [server/auth.config.ts]
import { defineServerAuth } from '@onmax/nuxt-better-auth/config'
export default defineServerAuth({
- emailAndPassword: { enabled: true },
+ emailAndPassword: {
+ enabled: true,
+ },
})
```
+### Create the client config
+
```ts [app/auth.config.ts]
import { defineClientAuth } from '@onmax/nuxt-better-auth/config'
export default defineClientAuth({})
```
-### Run
+### Start Nuxt
-::code-group{sync="pm"}
-```bash [pnpm]
+```bash
pnpm dev
```
-```bash [npm]
-npm run dev
-```
-::
::
-You now have API routes at `/api/auth/*`, a reactive `useUserSession()` composable, and route protection via `definePageMeta`.
+## Verify the result
+
+Check these success signals:
+
+- your app starts without auth-related module errors
+- `/api/auth/*` routes are registered
+- `useUserSession()` is available in a page or component
+- the generated config files match your project structure
-## Recommended Path for Beginners
+If you use a custom `srcDir`, the client config lives there instead of `app/`.
-If this is your first setup, follow this order:
+## Next steps
-1. [Installation](/getting-started/installation)
-2. [Configuration](/getting-started/configuration)
-3. [Client Setup](/getting-started/client-setup)
-4. [Route Protection](/core-concepts/route-protection)
-5. [API Reference](/api/composables)
+1. Follow [installation](/getting-started/installation) for the complete setup checklist.
+2. Read [configuration](/getting-started/configuration) before adding providers or plugins.
+3. Set up [client usage](/getting-started/client-setup) in your pages and forms.
+4. Add [route protection](/core-concepts/route-protection) once the login flow works.
diff --git a/docs/content/1.getting-started/1.installation.md b/docs/content/1.getting-started/1.installation.md
index c13b96c5..98904524 100644
--- a/docs/content/1.getting-started/1.installation.md
+++ b/docs/content/1.getting-started/1.installation.md
@@ -15,16 +15,17 @@ Install @onmax/nuxt-better-auth in my Nuxt 4 app.
- Create `server/auth.config.ts` using `defineServerAuth` from `@onmax/nuxt-better-auth/config`
- Create `app/auth.config.ts` using `defineClientAuth` from `@onmax/nuxt-better-auth/config`
- The module auto-injects `secret` and `baseURL` — do not configure them manually
-
-Read more: https://better-auth.nuxt.dev/raw/getting-started/installation.md
-Source: https://github.com/nuxt-modules/better-auth
```
::
+Use this page when you want the full install checklist rather than the shorter quickstart.
+
## Prerequisites
- Nuxt v4.0+
+- a package manager configured for your app
+- a local `.env` file or deployment environment variable system
## Add to project
@@ -36,7 +37,7 @@ Source: https://github.com/nuxt-modules/better-auth
npx nuxi module add @onmax/nuxt-better-auth@alpha
```
-### Set Environment Variables
+### Set environment variables
::tip{icon="i-lucide-sparkles"}
When you install the module with `nuxi module add`, it prompts you to generate `NUXT_BETTER_AUTH_SECRET` and can append it to your `.env`. `BETTER_AUTH_SECRET` still works as a compatibility fallback. In CI/test environments it auto-generates the secret.
@@ -73,7 +74,7 @@ The module auto-detects the URL on Vercel, Cloudflare Pages, and Netlify. Set ma
NUXT_PUBLIC_SITE_URL=https://your-domain.com
```
-### Create Configuration Files
+### Create configuration files
::tip{icon="i-lucide-sparkles"}
During module install, `server/auth.config.ts` and `/auth.config.ts` are scaffolded if missing. The client config is placed in your `srcDir` (e.g., `app/` or project root).
@@ -102,6 +103,21 @@ export default defineClientAuth({})
::
+## Verify the installation
+
+Confirm all of the following:
+
+- Nuxt starts without missing-config errors
+- `server/auth.config.ts` exists
+- `app/auth.config.ts` or your `srcDir` equivalent exists
+- `NUXT_BETTER_AUTH_SECRET` is available at runtime
+
+## Next steps
+
+- Continue with [configuration](/getting-started/configuration) to set module options and route protection.
+- Continue with [client setup](/getting-started/client-setup) to wire sign-in and sign-out flows.
+- If you need durable persistence, pick either [NuxtHub integration](/integrations/nuxthub) or [custom database](/guides/custom-database).
+
::callout{icon="i-lucide-database" to="/integrations/nuxthub"}
**Need database persistence?** See [NuxtHub Integration](/integrations/nuxthub) for auto-generated schemas and full database support.
::
diff --git a/docs/content/1.getting-started/2.configuration.md b/docs/content/1.getting-started/2.configuration.md
index 129aa409..0e7e5b19 100644
--- a/docs/content/1.getting-started/2.configuration.md
+++ b/docs/content/1.getting-started/2.configuration.md
@@ -16,13 +16,12 @@ Configure @onmax/nuxt-better-auth module options and server auth.
- The module auto-injects `secret` and `baseURL` — do not set them in defineServerAuth
- Base URL priority: runtimeConfig > request URL > platform env vars > localhost
- Set `NUXT_PUBLIC_SITE_URL` for custom domains or deterministic OAuth callbacks
-
-Read more: https://better-auth.nuxt.dev/raw/getting-started/configuration.md
-Source: https://github.com/nuxt-modules/better-auth
```
::
+Use this page when the module is installed and you want to control runtime behavior in `nuxt.config.ts`, `server/auth.config.ts`, and `app/auth.config.ts`.
+
## Module Configuration
```ts [nuxt.config.ts]
@@ -266,6 +265,21 @@ Use `NUXT_BETTER_AUTH_SECRET` as the primary secret variable. `BETTER_AUTH_SECRE
## For Module Authors
+## Recommended order
+
+1. Configure the module in `nuxt.config.ts`.
+2. Configure Better Auth behavior in `server/auth.config.ts`.
+3. Configure client plugins in `app/auth.config.ts`.
+4. Add route protection with `routeRules` or `definePageMeta({ auth })`.
+
+## Verify the result
+
+After configuration changes:
+
+- restart the Nuxt dev server if you changed schema- or plugin-related settings
+- confirm your app boots without missing-config errors
+- confirm route protection works on at least one protected page and one protected API route
+
Other Nuxt modules can extend the authentication configuration:
```ts
diff --git a/docs/content/1.getting-started/3.client-setup.md b/docs/content/1.getting-started/3.client-setup.md
index 306eabbc..cc7cffa7 100644
--- a/docs/content/1.getting-started/3.client-setup.md
+++ b/docs/content/1.getting-started/3.client-setup.md
@@ -14,13 +14,12 @@ Set up the client auth config for @onmax/nuxt-better-auth.
- Add client plugin equivalents for every server plugin (e.g. `adminClient()` from `better-auth/client/plugins`)
- The module calls the factory with the correct `baseURL` at runtime
- `useUserSession()` is auto-imported and provides `user`, `session`, `loggedIn`, `ready`, `signIn`, `signUp`, `signOut`
-
-Read more: https://better-auth.nuxt.dev/raw/getting-started/client-setup.md
-Source: https://github.com/nuxt-modules/better-auth
```
::
+Use this page when the server config exists and you want to wire the Better Auth client into your Nuxt app.
+
## Create the Client Config
Create `app/auth.config.ts` with a default export using `defineClientAuth`.
@@ -72,3 +71,31 @@ export default defineClientAuth({
```
:read-more{to="https://www.better-auth.com/docs/plugins" title="All Better Auth plugins"}
+
+## Use the client in your app
+
+`useUserSession()` is auto-imported in pages and components.
+
+```vue [pages/login.vue]
+
+```
+
+## Verify the result
+
+Confirm all of the following:
+
+- `useUserSession()` is available without a manual import
+- `client` is available on the browser after hydration
+- client plugins are registered on both server and client when required by Better Auth
+- sign-in and sign-out update `user`, `session`, and `loggedIn`
diff --git a/docs/content/1.getting-started/4.type-augmentation.md b/docs/content/1.getting-started/4.type-augmentation.md
index 61773d45..1bf7541f 100644
--- a/docs/content/1.getting-started/4.type-augmentation.md
+++ b/docs/content/1.getting-started/4.type-augmentation.md
@@ -14,13 +14,12 @@ Set up type augmentation for @onmax/nuxt-better-auth plugins.
- Import `#nuxt-better-auth` and declare module to extend `AuthUser` or `AuthSession` interfaces
- If types don't update: restart TS server, run `npx nuxi prepare`, check config for syntax errors
- Ensure `.d.ts` files are included by TypeScript (`tsconfig.json` include or `/// `)
-
-Read more: https://better-auth.nuxt.dev/raw/getting-started/type-augmentation.md
-Source: https://github.com/nuxt-modules/better-auth
```
::
+Use this page when Better Auth plugins or custom fields add properties such as `role`, `plan`, or `teamRole` and you want those fields available everywhere the module exposes auth types.
+
When you add Better Auth plugins that extend the user or session objects, TypeScript needs to know about these new fields. The module automatically infers types from your configuration, but you can also augment types manually.
## Automatic Type Inference
@@ -87,6 +86,15 @@ Otherwise, Nuxt/TypeScript may not pick them up and your augmentation will have
## Troubleshooting
+If your custom fields are missing:
+
+- restart the Nuxt dev server
+- restart the TypeScript server in your editor
+- confirm `server/auth.config.ts` exports `defineServerAuth(...)`
+- confirm your plugin or custom field actually changes the Better Auth user or session shape
+
+For the public type surface, see [API types](/api/types).
+
**Types not updating?**
1. Restart your IDE's TypeScript server
2. Run `npx nuxi prepare` to regenerate types
diff --git a/docs/content/1.getting-started/5.schema-generation.md b/docs/content/1.getting-started/5.schema-generation.md
index f4bffc7e..1cbf75bb 100644
--- a/docs/content/1.getting-started/5.schema-generation.md
+++ b/docs/content/1.getting-started/5.schema-generation.md
@@ -16,13 +16,12 @@ Set up auto schema generation for @onmax/nuxt-better-auth with NuxtHub.
- After adding/removing plugins: restart the dev server to regenerate schemas
- For production (Cloudflare D1): run `npx nuxt db migrate`
- No manual Drizzle schema writing needed for auth tables
-
-Read more: https://better-auth.nuxt.dev/raw/getting-started/schema-generation.md
-Source: https://github.com/nuxt-modules/better-auth
```
::
+Use this page when you are using NuxtHub and want the module to generate auth tables from your Better Auth configuration.
+
::note
This feature requires **NuxtHub**. See [NuxtHub Integration](/integrations/nuxthub) for setup.
::
@@ -78,6 +77,16 @@ When you add a new plugin that requires database tables (e.g., adding `twoFactor
npx nuxt db migrate
```
+## When not to use this
+
+Do not rely on this flow if:
+
+- you are not using NuxtHub
+- you are in `clientOnly` mode
+- you manage Better Auth tables with a separate adapter and migration pipeline
+
+In those cases, use [custom database setup](/guides/custom-database).
+
::callout{to="https://hub.nuxt.com/docs/getting-started/deploy" external}
See NuxtHub deployment documentation.
::
diff --git a/docs/content/1.getting-started/6.how-it-works.md b/docs/content/1.getting-started/6.how-it-works.md
index 94984534..8611eb9d 100644
--- a/docs/content/1.getting-started/6.how-it-works.md
+++ b/docs/content/1.getting-started/6.how-it-works.md
@@ -4,6 +4,8 @@ description: Understand the architecture after completing setup.
navigation.icon: i-lucide-workflow
---
+Use this page after installation. It explains how the module connects Nuxt runtime behavior to Better Auth rather than walking through setup again.
+
## Architecture
::steps
@@ -36,3 +38,10 @@ On the client side, `useUserSession` initializes the Better Auth client. It esta
5. Better Auth validates credentials and creates session
6. Session cookie is set, user redirected to original page
7. `useUserSession()` reads session from cookie, updates reactive state
+
+## What this means in practice
+
+- client pages use `useUserSession()` and related composables
+- protected API routes should still call `requireUserSession(event)`
+- route rules improve navigation UX, but server-side checks remain the real security boundary
+- NuxtHub integration and schema generation are build-time concerns, not request-time concerns
diff --git a/docs/content/2.core-concepts/1.server-auth.md b/docs/content/2.core-concepts/1.server-auth.md
index 03bfaf0f..dec69ca4 100644
--- a/docs/content/2.core-concepts/1.server-auth.md
+++ b/docs/content/2.core-concepts/1.server-auth.md
@@ -13,13 +13,12 @@ Use server-side auth utilities in @onmax/nuxt-better-auth.
- `requireUserSession(event, options?)` — throws 401 if not authenticated, supports role matching
- `getRequestSession(event)` — request-cached session, preferred over repeated `getUserSession` in same request
- All server utils are auto-imported, no import statements needed
-
-Read more: https://better-auth.nuxt.dev/raw/core-concepts/server-auth.md
-Source: https://github.com/nuxt-modules/better-auth
```
::
+Use this page when you need authentication state or Better Auth APIs inside Nitro handlers, middleware, plugins, or other server-side code.
+
`serverAuth(event?)` returns the Better Auth instance (module-level singleton). In Nitro handlers, you should pass `event` so the module can resolve request-aware base URLs on initialization. Outside request contexts (seed scripts, tasks, plugins), you can call `serverAuth()` without an event.
## When to Use What
diff --git a/docs/content/2.core-concepts/2.sessions.md b/docs/content/2.core-concepts/2.sessions.md
index 7afa74c8..a1d1d540 100644
--- a/docs/content/2.core-concepts/2.sessions.md
+++ b/docs/content/2.core-concepts/2.sessions.md
@@ -15,13 +15,12 @@ Handle sessions with @onmax/nuxt-better-auth using useUserSession().
- Configure session lifetime in `server/auth.config.ts` via `session.expiresIn` and `session.cookieCache`
- Use `` or `ready` ref to avoid loading flashes
- Force refresh: `fetchSession({ force: true })`
-
-Read more: https://better-auth.nuxt.dev/raw/core-concepts/sessions.md
-Source: https://github.com/nuxt-modules/better-auth
```
::
+Use this page when you want to understand how session state moves between SSR, hydration, client updates, and server-side access.
+
```ts [pages/dashboard.vue]
const {
user,
diff --git a/docs/content/2.core-concepts/3.route-protection.md b/docs/content/2.core-concepts/3.route-protection.md
index c6f3a4e1..d337f861 100644
--- a/docs/content/2.core-concepts/3.route-protection.md
+++ b/docs/content/2.core-concepts/3.route-protection.md
@@ -16,13 +16,12 @@ Protect routes and API endpoints with @onmax/nuxt-better-auth.
- Role + custom rules: `requireUserSession(event, { user: { role: 'admin' }, rule: ({ user }) => user.verified })`
- Route rules auto-sync to client router for instant redirects
- Always protect API endpoints with `requireUserSession` — route rules are UX only
-
-Read more: https://better-auth.nuxt.dev/raw/core-concepts/route-protection.md
-Source: https://github.com/nuxt-modules/better-auth
```
::
+Use this page when you need to protect Nuxt pages, layouts, and API routes without guessing which layer is responsible for what.
+
## Quick Reference
| Method | Scope | Use Case |
@@ -32,6 +31,8 @@ Source: https://github.com/nuxt-modules/better-auth
| **Middleware** | Client | Complex client-side navigation logic. |
| **Server Utils** | API | Protecting API endpoints. |
+Route rules and page meta handle navigation and UX. Server-side checks with `requireUserSession(event)` remain the actual security boundary for protected data and mutations.
+
### Matching Logic
Role arrays use **OR** logic: the user needs any one of the listed values.
diff --git a/docs/content/2.core-concepts/4.auto-imports-aliases.md b/docs/content/2.core-concepts/4.auto-imports-aliases.md
index 2a99d797..f46fef5f 100644
--- a/docs/content/2.core-concepts/4.auto-imports-aliases.md
+++ b/docs/content/2.core-concepts/4.auto-imports-aliases.md
@@ -13,13 +13,12 @@ Use auto-imported utilities from @onmax/nuxt-better-auth.
- Component: `` for auth-ready rendering
- Alias `#nuxt-better-auth` exports types: `AuthUser`, `AuthSession`, `AuthSocialProviderId`
- Use `getRequestSession(event)` over repeated `getUserSession(event)` calls — it caches per request
-
-Read more: https://better-auth.nuxt.dev/raw/core-concepts/auto-imports-aliases.md
-Source: https://github.com/nuxt-modules/better-auth
```
::
+Use this page when you want a quick inventory of what the module registers for you and where each helper is available.
+
## Auto‑imports
**Client**
diff --git a/docs/content/2.core-concepts/5.security-caveats.md b/docs/content/2.core-concepts/5.security-caveats.md
index e8d36754..a4c6fe85 100644
--- a/docs/content/2.core-concepts/5.security-caveats.md
+++ b/docs/content/2.core-concepts/5.security-caveats.md
@@ -3,6 +3,8 @@ title: Security & Caveats
description: What is enforced where, and what you should not assume.
---
+Use this page when you are moving from “it works locally” to “it is safe to deploy”.
+
## Client redirects are not security
Client-side redirects improve UX but don't prevent unauthorized access. Always validate on the server.
diff --git a/docs/content/3.guides/1.role-based-access.md b/docs/content/3.guides/1.role-based-access.md
index 8ab8aa7a..3137e8b8 100644
--- a/docs/content/3.guides/1.role-based-access.md
+++ b/docs/content/3.guides/1.role-based-access.md
@@ -3,6 +3,8 @@ title: Role‑Based Access
description: Protect routes using generic field matching on AuthUser.
---
+Use this guide when your Better Auth user shape includes fields such as `role`, `teamRole`, or custom authorization flags and you want to use them in route rules or server checks.
+
## With Admin Plugin
```ts [server/auth.config.ts]
diff --git a/docs/content/3.guides/2.oauth-providers.md b/docs/content/3.guides/2.oauth-providers.md
index 901c7b97..f900cdeb 100644
--- a/docs/content/3.guides/2.oauth-providers.md
+++ b/docs/content/3.guides/2.oauth-providers.md
@@ -3,6 +3,8 @@ title: OAuth Providers
description: Configure OAuth providers and sign in with `signIn.social()`.
---
+Use this guide when you want to add a social provider to a full-mode Nuxt Better Auth setup.
+
This guide demonstrates OAuth setup using Google. Other providers follow the same pattern.
:read-more{to="https://www.better-auth.com/docs/concepts/oauth" title="Better Auth OAuth documentation"}
diff --git a/docs/content/3.guides/3.custom-database.md b/docs/content/3.guides/3.custom-database.md
index d0baae65..762e3425 100644
--- a/docs/content/3.guides/3.custom-database.md
+++ b/docs/content/3.guides/3.custom-database.md
@@ -3,6 +3,8 @@ title: Custom Database
description: Use your own database with Drizzle, Prisma, or Kysely adapters.
---
+Use this guide when you want Better Auth to run against your existing database stack instead of NuxtHub.
+
Better Auth supports any database through adapters. Use this guide when you need full control over your database setup or can't use NuxtHub.
## When to Use This
diff --git a/docs/content/3.guides/4.database-less-mode.md b/docs/content/3.guides/4.database-less-mode.md
index 5c7467f4..53f81ecf 100644
--- a/docs/content/3.guides/4.database-less-mode.md
+++ b/docs/content/3.guides/4.database-less-mode.md
@@ -3,6 +3,8 @@ title: Database-less Mode
description: Run Better Auth without a database for edge and serverless deployments.
---
+Use this guide when you want stateless sessions and you accept the operational tradeoffs that come with not having persistent auth records.
+
Better Auth supports running without a database using encrypted cookie sessions (JWE).
::callout{icon="i-lucide-external-link" to="https://www.better-auth.com/docs/concepts/database#primitives-for-database-less-auth"}
diff --git a/docs/content/3.guides/5.external-auth-backend.md b/docs/content/3.guides/5.external-auth-backend.md
index ea546296..5ae42e85 100644
--- a/docs/content/3.guides/5.external-auth-backend.md
+++ b/docs/content/3.guides/5.external-auth-backend.md
@@ -4,6 +4,8 @@ description: Use nuxt-better-auth with a separate Better Auth server.
navigation.icon: i-lucide-server
---
+Use this guide when the Nuxt app is only the frontend and Better Auth runs somewhere else.
+
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
diff --git a/docs/content/3.guides/6.migrate-from-nuxt-auth-utils.md b/docs/content/3.guides/6.migrate-from-nuxt-auth-utils.md
index 18bfaece..446495e7 100644
--- a/docs/content/3.guides/6.migrate-from-nuxt-auth-utils.md
+++ b/docs/content/3.guides/6.migrate-from-nuxt-auth-utils.md
@@ -3,6 +3,8 @@ title: Migrating from nuxt-auth-utils
description: Step-by-step guide to migrate from nuxt-auth-utils to Nuxt Better Auth.
---
+Use this guide when you already have a Nuxt app on `nuxt-auth-utils` and want a safe migration order.
+
This guide covers migrating from [`nuxt-auth-utils`](https://github.com/atinux/nuxt-auth-utils) to Nuxt Better Auth.
::warning
diff --git a/docs/content/3.guides/7.two-factor-auth.md b/docs/content/3.guides/7.two-factor-auth.md
index d4e64aab..a1864618 100644
--- a/docs/content/3.guides/7.two-factor-auth.md
+++ b/docs/content/3.guides/7.two-factor-auth.md
@@ -3,6 +3,8 @@ title: Two-Factor Authentication (TOTP + Backup Codes)
description: Enable two-factor auth using the Better Auth two-factor plugin.
---
+Use this guide when you already have a database-backed auth setup and want to add TOTP with backup codes.
+
Better Auth ships a `twoFactor` plugin with TOTP, OTP, and backup codes. It requires a database-backed setup (e.g., NuxtHub).
::steps
diff --git a/docs/content/3.guides/8.testing.md b/docs/content/3.guides/8.testing.md
index 94bbe891..5b7b2a02 100644
--- a/docs/content/3.guides/8.testing.md
+++ b/docs/content/3.guides/8.testing.md
@@ -3,6 +3,8 @@ title: Testing
description: Mock authentication in tests.
---
+Use this guide when you want to test pages, composables, or Nitro routes without relying on a live auth backend.
+
## Mocking useUserSession
```ts [tests/utils.ts]
diff --git a/docs/content/3.guides/9.production-deployment.md b/docs/content/3.guides/9.production-deployment.md
index b57be282..5c581374 100644
--- a/docs/content/3.guides/9.production-deployment.md
+++ b/docs/content/3.guides/9.production-deployment.md
@@ -3,6 +3,8 @@ title: Production Deployment
description: Checklist and best practices for deploying Nuxt Better Auth in production.
---
+Use this guide when your auth flow works locally and you are preparing to ship it to a real environment.
+
## Environment Variables
Production requires these environment variables:
diff --git a/docs/content/4.integrations/1.nuxthub.md b/docs/content/4.integrations/1.nuxthub.md
index 777352ef..6941d066 100644
--- a/docs/content/4.integrations/1.nuxthub.md
+++ b/docs/content/4.integrations/1.nuxthub.md
@@ -3,6 +3,8 @@ title: NuxtHub
description: Automatic database setup with schema generation and Drizzle ORM integration.
---
+Use this guide when you want the shortest path to database-backed auth with schema generation handled by the module.
+
NuxtHub provides the easiest way to add database persistence to your authentication. Enable NuxtHub and this module generates and manages your database schema.
::note
diff --git a/docs/content/4.integrations/2.devtools.md b/docs/content/4.integrations/2.devtools.md
index da6ec542..5aebb269 100644
--- a/docs/content/4.integrations/2.devtools.md
+++ b/docs/content/4.integrations/2.devtools.md
@@ -3,6 +3,8 @@ title: DevTools
description: Inspect auth configuration and manage users/sessions during development.
---
+Use this page when you are debugging auth configuration, sessions, users, or plugin state during development.
+
This module integrates with [Nuxt DevTools](https://devtools.nuxt.com/) out of the box. No configuration needed.
::note
diff --git a/docs/content/4.integrations/3.convex.md b/docs/content/4.integrations/3.convex.md
index f931cbf7..5d3ca5e9 100644
--- a/docs/content/4.integrations/3.convex.md
+++ b/docs/content/4.integrations/3.convex.md
@@ -3,6 +3,8 @@ title: Convex
description: Current status of Convex integration in this module.
---
+Use this page when you are evaluating whether this module has first-class Convex support.
+
This module does not currently provide a built-in Convex adapter integration.
## Status
diff --git a/docs/content/4.integrations/4.i18n.md b/docs/content/4.integrations/4.i18n.md
index 4a6f3d81..4574a337 100644
--- a/docs/content/4.integrations/4.i18n.md
+++ b/docs/content/4.integrations/4.i18n.md
@@ -3,6 +3,8 @@ title: i18n
description: Translate authentication errors with @nuxtjs/i18n.
---
+Use this guide when you already have `@nuxtjs/i18n` configured and you want auth errors to respect the active locale.
+
This integration enables translated authentication error messages using your existing `@nuxtjs/i18n` setup.
## Setup
diff --git a/docs/content/5.api/1.composables.md b/docs/content/5.api/1.composables.md
index 9f7707f0..5c16c5e0 100644
--- a/docs/content/5.api/1.composables.md
+++ b/docs/content/5.api/1.composables.md
@@ -3,6 +3,8 @@ title: Composables
description: API reference for client-side composables.
---
+Use this page when you need exact behavior for the client-side composables exposed by the module.
+
## useUserSession
The primary composable for accessing authentication state. Returns reactive user, session, and auth client.
@@ -219,6 +221,12 @@ const saveProfile = useAction(async (payload: { name: string }) => {
await saveProfile.execute({ name: 'Max' })
+## Related pages
+
+- [Sessions](/core-concepts/sessions)
+- [Server utilities](/api/server-utils)
+- [Components](/api/components)
+
if (saveProfile.status.value === 'error') {
console.error(saveProfile.error.value?.message)
}
diff --git a/docs/content/5.api/2.server-utils.md b/docs/content/5.api/2.server-utils.md
index a31581b4..1481e899 100644
--- a/docs/content/5.api/2.server-utils.md
+++ b/docs/content/5.api/2.server-utils.md
@@ -3,6 +3,8 @@ title: Server Utilities
description: API reference for server-side helpers available in Nitro event handlers.
---
+Use this page when you need exact behavior for the auto-imported server helpers registered by the module.
+
::warning
These utilities are only available in **full mode**. In [clientOnly mode](/guides/external-auth-backend), there is no local auth server, so these utilities are not registered.
::
@@ -202,3 +204,9 @@ export default defineEventHandler(async (event) => {
return getTeamSettings(teamId)
})
```
+
+## Related pages
+
+- [Server auth concept](/core-concepts/server-auth)
+- [Route protection](/core-concepts/route-protection)
+- [Types](/api/types)
diff --git a/docs/content/5.api/3.components.md b/docs/content/5.api/3.components.md
index 46386f04..3e32a84b 100644
--- a/docs/content/5.api/3.components.md
+++ b/docs/content/5.api/3.components.md
@@ -3,6 +3,8 @@ title: Components
description: Built‑in UI helpers.
---
+Use this page when you need the slot contract and rendering behavior for the built-in UI helper components.
+
## ``
Renders once session hydration is complete (`ready === true`) and exposes state via slots.
diff --git a/docs/content/5.api/4.types.md b/docs/content/5.api/4.types.md
index 5be76630..fd48c0be 100644
--- a/docs/content/5.api/4.types.md
+++ b/docs/content/5.api/4.types.md
@@ -3,6 +3,8 @@ title: Types
description: Public types and route rule shapes.
---
+Use this page when you need the public TypeScript surface exposed by the module and its generated auth types.
+
```ts
import type {
AppSession,
diff --git a/docs/content/7.examples/.navigation.yml b/docs/content/7.examples/.navigation.yml
deleted file mode 100644
index dc9e0fe2..00000000
--- a/docs/content/7.examples/.navigation.yml
+++ /dev/null
@@ -1 +0,0 @@
-title: Examples
diff --git a/docs/content/8.changelog/.navigation.yml b/docs/content/8.changelog/.navigation.yml
deleted file mode 100644
index 50818a03..00000000
--- a/docs/content/8.changelog/.navigation.yml
+++ /dev/null
@@ -1 +0,0 @@
-title: Changelog
diff --git a/docs/content/index.md b/docs/content/index.md
index 7aebafc3..fb280561 100644
--- a/docs/content/index.md
+++ b/docs/content/index.md
@@ -4,8 +4,70 @@ description: Seamless Better Auth integration for Nuxt with automatic route prot
navigation: false
---
-::landing-hero
-::
+Nuxt Better Auth is a Nuxt 4 module that wraps [Better Auth](https://www.better-auth.com/) with Nuxt-native configuration, route protection, SSR-safe session access, and optional NuxtHub schema generation.
-::landing-features
-::
+## Start here
+
+Use the docs in this order if you are setting up the module for the first time:
+
+1. [Quickstart](/getting-started)
+2. [Installation](/getting-started/installation)
+3. [Configuration](/getting-started/configuration)
+4. [Client setup](/getting-started/client-setup)
+5. [Route protection](/core-concepts/route-protection)
+
+You should finish that path with a working `/api/auth/*` backend, a client config, and a login flow that can read session state through `useUserSession()`.
+
+## Choose the right setup
+
+| If you want to... | Start here |
+| --- | --- |
+| Get a database-backed setup running quickly | [NuxtHub](/integrations/nuxthub) |
+| Plug Better Auth into your own database stack | [Custom database](/guides/custom-database) |
+| Reuse an external Better Auth server | [External auth backend](/guides/external-auth-backend) |
+| Avoid a database and accept stateless session tradeoffs | [Database-less mode](/guides/database-less-mode) |
+| Migrate from `nuxt-auth-utils` | [Migration guide](/guides/migrate-from-nuxt-auth-utils) |
+
+## What the module adds on top of Better Auth
+
+- `server/auth.config.ts` and `app/auth.config.ts` helpers
+- auto-imported client and server auth utilities
+- route protection through `routeRules` and page meta
+- SSR-aware session hydration
+- typed `AuthUser` and `AuthSession` inference from your config
+- optional NuxtHub database and schema integration
+
+## Documentation map
+
+### Getting started
+
+- [Quickstart](/getting-started)
+- [Installation](/getting-started/installation)
+- [Configuration](/getting-started/configuration)
+- [Client setup](/getting-started/client-setup)
+- [Type augmentation](/getting-started/type-augmentation)
+- [Schema generation](/getting-started/schema-generation)
+
+### Core concepts
+
+- [Server auth](/core-concepts/server-auth)
+- [Sessions](/core-concepts/sessions)
+- [Route protection](/core-concepts/route-protection)
+- [Auto-imports and aliases](/core-concepts/auto-imports-aliases)
+- [Security and caveats](/core-concepts/security-caveats)
+
+### Guides and integrations
+
+- [Role-based access](/guides/role-based-access)
+- [OAuth providers](/guides/oauth-providers)
+- [Two-factor authentication](/guides/two-factor-auth)
+- [Production deployment](/guides/production-deployment)
+- [NuxtHub](/integrations/nuxthub)
+- [i18n](/integrations/i18n)
+
+### API reference
+
+- [Composables](/api/composables)
+- [Server utilities](/api/server-utils)
+- [Components](/api/components)
+- [Types](/api/types)
diff --git a/docs/public/.well-known/skills/nuxt-better-auth/SKILL.md b/docs/public/.well-known/skills/nuxt-better-auth/SKILL.md
index 10591e1e..4ff47c5f 100644
--- a/docs/public/.well-known/skills/nuxt-better-auth/SKILL.md
+++ b/docs/public/.well-known/skills/nuxt-better-auth/SKILL.md
@@ -6,40 +6,35 @@ license: MIT
# Nuxt Better Auth
-Authentication module for Nuxt 4+ built on [Better Auth](https://www.better-auth.com/). Provides composables, server utilities, and route protection.
+Authentication module for Nuxt 4+ built on [Better Auth](https://www.better-auth.com/). It adds Nuxt-specific setup, route protection, server helpers, and typed auth state.
-> **Alpha Status**: This module is currently in alpha (v0.0.2-alpha.12) and not recommended for production use. APIs may change.
+> Alpha status: the package is still pre-stable. Verify behavior against the current docs and source before relying on edge cases.
## When to Use
- Installing/configuring `@onmax/nuxt-better-auth`
-- Implementing login/signup/signout flows
+- Implementing sign-in, sign-up, or sign-out flows
- Protecting routes (client and server)
- Accessing user session in API routes
- Integrating Better Auth plugins (admin, passkey, 2FA)
- Setting up database with NuxtHub
- Using clientOnly mode for external auth backends
-**For Nuxt patterns:** use `nuxt` skill
-**For NuxtHub database:** use `nuxthub` skill
-
## Available Guidance
| File | Topics |
| -------------------------------------------------------------------- | ---------------------------------------------------------------------- |
-| **[references/installation.md](references/installation.md)** | Module setup, env vars, config files |
-| **[references/client-auth.md](references/client-auth.md)** | useUserSession, signIn/signUp/signOut, BetterAuthState, safe redirects |
-| **[references/server-auth.md](references/server-auth.md)** | serverAuth, getUserSession, requireUserSession |
-| **[references/route-protection.md](references/route-protection.md)** | routeRules, definePageMeta, middleware |
-| **[references/plugins.md](references/plugins.md)** | Better Auth plugins (admin, passkey, 2FA) |
-| **[references/database.md](references/database.md)** | NuxtHub integration, Drizzle schema |
-| **[references/client-only.md](references/client-only.md)** | External auth backend, clientOnly mode, CORS |
-| **[references/types.md](references/types.md)** | AuthUser, AuthSession, type augmentation |
+| **[references/installation.md](references/installation.md)** | install flow, env vars, config files |
+| **[references/client-auth.md](references/client-auth.md)** | `useUserSession`, client methods, redirects, loading states |
+| **[references/server-auth.md](references/server-auth.md)** | `serverAuth`, `getUserSession`, `getRequestSession`, `requireUserSession` |
+| **[references/route-protection.md](references/route-protection.md)** | route rules, page meta, API protection |
+| **[references/plugins.md](references/plugins.md)** | plugin pairing between server and client |
+| **[references/database.md](references/database.md)** | NuxtHub schema generation, secondary storage |
+| **[references/client-only.md](references/client-only.md)** | external Better Auth backends and `clientOnly` mode |
+| **[references/types.md](references/types.md)** | public auth types and augmentation |
## Usage Pattern
-**Load based on context:**
-
- Installing module? → [references/installation.md](references/installation.md)
- Login/signup forms? → [references/client-auth.md](references/client-auth.md)
- API route protection? → [references/server-auth.md](references/server-auth.md)
@@ -49,7 +44,7 @@ Authentication module for Nuxt 4+ built on [Better Auth](https://www.better-auth
- External auth backend? → [references/client-only.md](references/client-only.md)
- TypeScript types? → [references/types.md](references/types.md)
-**DO NOT read all files at once.** Load based on context.
+Do not load every reference file by default. Pick the smallest file that matches the task.
## Key Concepts
@@ -84,9 +79,5 @@ routeRules: {
## Resources
-- [Module Docs](https://github.com/onmax/nuxt-better-auth)
+- [Documentation site](https://better-auth.nuxt.dev)
- [Better Auth Docs](https://www.better-auth.com/)
-
----
-
-_Token efficiency: Main skill ~300 tokens, each sub-file ~800-1200 tokens_
diff --git a/docs/public/.well-known/skills/nuxt-better-auth/references/client-auth.md b/docs/public/.well-known/skills/nuxt-better-auth/references/client-auth.md
index eeb87f2a..e76fa4f5 100644
--- a/docs/public/.well-known/skills/nuxt-better-auth/references/client-auth.md
+++ b/docs/public/.well-known/skills/nuxt-better-auth/references/client-auth.md
@@ -1,66 +1,49 @@
-# Client-Side Authentication
+# Client-side authentication
-## useUserSession()
-
-Main composable for auth state and methods.
+## Primary entry point
```ts
const {
- user, // Ref
- session, // Ref
- loggedIn, // ComputedRef
- ready, // ComputedRef - session fetch complete
- client, // Better Auth client (client-side only)
- signIn, // Proxy to client.signIn
- signUp, // Proxy to client.signUp
- signOut, // Sign out and clear session
- fetchSession, // Manually refresh session
- updateUser // Optimistic local user update
+ user,
+ session,
+ loggedIn,
+ ready,
+ client,
+ signIn,
+ signUp,
+ signOut,
+ fetchSession,
+ updateUser,
} = useUserSession()
```
-## Sign In
+## What to rely on
-```ts
-// Email/password
-await signIn.email({
- email: 'user@example.com',
- password: 'password123'
-}, {
- onSuccess: () => navigateTo('/dashboard')
-})
-
-// OAuth
-await signIn.social({ provider: 'github' })
-```
+- `ready` means the initial auth state has resolved.
+- `client` is browser-only and `null` during SSR.
+- `signIn` and `signUp` proxy Better Auth client methods.
+- `signOut` clears local state after the server sign-out flow completes.
+
+## Common patterns
-## Sign Up
+### Email sign-in
```ts
-await signUp.email({
- email: 'user@example.com',
- password: 'password123',
- name: 'John Doe'
-}, {
- onSuccess: () => navigateTo('/welcome')
-})
+await signIn.email(
+ { email: 'user@example.com', password: 'password123' },
+ { onSuccess: () => navigateTo('/dashboard') },
+)
```
-## Sign Out
+### Social sign-in
```ts
-await signOut()
-// or with redirect
-await signOut({ redirect: '/login' })
+await signIn.social({ provider: 'github' })
```
-## Check Auth State
+### Loading state
```vue
-
-
Loading...
Welcome, {{ user?.name }}
@@ -68,56 +51,15 @@ const { user, loggedIn, ready } = useUserSession()
```
-## Safe Redirects
-
-Always validate redirect URLs from query params to prevent open redirects:
+### Force refresh
```ts
-function getSafeRedirect() {
- const redirect = route.query.redirect as string
- // Must start with / and not // (prevents protocol-relative URLs)
- if (!redirect?.startsWith('/') || redirect.startsWith('//')) {
- return '/'
- }
- return redirect
-}
-
-await signIn.email({
- email, password
-}, {
- onSuccess: () => navigateTo(getSafeRedirect())
-})
-```
-
-## Wait for Session
-
-Useful when needing session before rendering:
-
-```ts
-await waitForSession() // 5s timeout
-if (loggedIn.value) {
- // Session is ready
-}
-```
-
-## Manual Session Refresh
-
-```ts
-// Refetch from server
await fetchSession({ force: true })
```
-## Session Management
-
-Additional session management via Better Auth client:
-
-```ts
-const { client } = useUserSession()
-
-// List all active sessions for current user
-const sessions = await client.listSessions()
+## Redirect rule
-// Revoke a specific session
+If you read `route.query.redirect`, validate it before navigating. Only allow local paths.
await client.revokeSession({ sessionId: 'xxx' })
// Revoke all sessions except current
diff --git a/docs/public/.well-known/skills/nuxt-better-auth/references/client-only.md b/docs/public/.well-known/skills/nuxt-better-auth/references/client-only.md
index a36e0f32..b9ff55db 100644
--- a/docs/public/.well-known/skills/nuxt-better-auth/references/client-only.md
+++ b/docs/public/.well-known/skills/nuxt-better-auth/references/client-only.md
@@ -1,10 +1,8 @@
-# Client-Only Mode (External Auth Backend)
+# Client-only mode
-When Better Auth runs on a separate backend (microservices, standalone server), use `clientOnly` mode.
+Use `clientOnly` when Better Auth runs on a separate backend.
-## Configuration
-
-### 1. Enable in nuxt.config.ts
+## Minimal setup
```ts
export default defineNuxtConfig({
@@ -15,73 +13,20 @@ export default defineNuxtConfig({
})
```
-### 2. Point client to external server
-
-```ts [app/auth.config.ts]
-import { defineClientAuth } from '@onmax/nuxt-better-auth/config'
-
-export default defineClientAuth({
- baseURL: 'https://auth.example.com', // External auth server
-})
-```
-
-### 3. Set frontend URL
-
-```ini [.env]
-NUXT_PUBLIC_SITE_URL="https://your-frontend.com"
+```ini
+NUXT_PUBLIC_SITE_URL=https://auth.example.com
```
-## What Changes
-
-| 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 utilities (`serverAuth()`, `getUserSession()`, `requireUserSession()`) | Available | **Not available** |
-| SSR session hydration | Server-side | Client-side only |
-| `useUserSession()`, route protection, `` | Works | Works |
-
-## CORS Requirements
-
-Ensure external auth server:
+## What changes
-- Allows requests from frontend (CORS with `credentials: true`)
-- Uses `SameSite=None; Secure` cookies (HTTPS required)
-- Includes frontend URL in `trustedOrigins`
+- no local `/api/auth/**` handlers
+- no local `server/auth.config.ts`
+- no server utilities such as `serverAuth()` or `requireUserSession()`
+- no SSR session hydration from a local auth server
+- `useUserSession()` still works on the client
-## SSR Considerations
+## External server requirements
-Session fetched client-side only:
-
-- Server-rendered pages render as "unauthenticated" initially
-- Hydrates with session data on client
-- Use `` for loading states
-
-```vue
-
- Loading...
- Welcome, {{ user.name }}
- Please log in
-
-```
-
-## Use Cases
-
-- **Microservices**: Auth service is separate deployment
-- **Shared auth**: Multiple frontends share one auth backend
-- **Existing backend**: Already have Better Auth server running elsewhere
-
-## Architecture Example
-
-```
-┌─────────────────┐ ┌─────────────────┐
-│ Nuxt App │────▶│ Auth Server │
-│ (clientOnly) │ │ (Better Auth) │
-│ │◀────│ │
-└─────────────────┘ └────────┬────────┘
- │
- ┌────────▼────────┐
- │ Database │
- └─────────────────┘
-```
+- allow cross-origin requests with credentials
+- use secure cross-site cookies when needed
+- include the frontend origin in `trustedOrigins`
diff --git a/docs/public/.well-known/skills/nuxt-better-auth/references/database.md b/docs/public/.well-known/skills/nuxt-better-auth/references/database.md
index e6bf9c18..3d43eac8 100644
--- a/docs/public/.well-known/skills/nuxt-better-auth/references/database.md
+++ b/docs/public/.well-known/skills/nuxt-better-auth/references/database.md
@@ -1,115 +1,45 @@
-# Database Integration
+# Database integration
-## NuxtHub Setup
+## Fastest database-backed path
+
+Use NuxtHub.
```ts
-// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxthub/core', '@onmax/nuxt-better-auth'],
- hub: { database: true },
- auth: {
- hubSecondaryStorage: true, // Optional: KV for session caching
- schema: {
- usePlural: false, // user vs users
- casing: 'camelCase' // camelCase or snake_case
- }
- }
+ hub: {
+ db: 'sqlite',
+ },
})
```
-## Schema Generation
-
-The module auto-generates Drizzle schema from Better Auth tables. Schema available via:
-
-```ts
-import { user, session, account, verification } from '#auth/database'
-```
-
-## Database Dialect
-
-Supports: `sqlite`, `postgresql`, `mysql`
+## What the module does with NuxtHub
-Schema syntax adapts to dialect:
+- reads `server/auth.config.ts`
+- generates auth tables from enabled Better Auth features
+- exposes generated schema through `#auth/schema`
+- can optionally use NuxtHub KV for session lookup caching
-- SQLite: `integer('id').primaryKey()`
-- PostgreSQL/MySQL: `uuid('id').primaryKey()` or `text('id').primaryKey()`
-
-## Schema Options
+## Secondary storage
```ts
-auth: {
- schema: {
- usePlural: true, // tables: users, sessions, accounts
- casing: 'snake_case' // columns: created_at, updated_at
- }
-}
-```
-
-| Option | Default | Description |
-| ----------- | ------------- | ------------------------ |
-| `usePlural` | `false` | Pluralize table names |
-| `casing` | `'camelCase'` | Column naming convention |
-
-## Extending Schema
-
-Add custom columns via NuxtHub's schema hooks:
-
-```ts
-// server/plugins/extend-schema.ts
-export default defineNitroPlugin(() => {
- useNitroApp().hooks.hook('hub:db:schema:extend', (schema) => {
- // Add custom tables or extend existing
- })
+export default defineNuxtConfig({
+ hub: {
+ db: 'sqlite',
+ kv: true,
+ },
+ auth: {
+ hubSecondaryStorage: true,
+ },
})
```
-## Secondary Storage (KV)
+Important:
-Enable session caching with KV:
+- `hubSecondaryStorage: true` requires `hub.kv: true`
+- `hubSecondaryStorage: 'custom'` means you provide your own `secondaryStorage`
+- use DB-only reads if you prefer stricter read-after-write consistency
-```ts
-auth: {
- hubSecondaryStorage: true
-}
-```
+## Non-NuxtHub setups
-Requires `hub.kv: true` in config. Build fails if KV is not enabled. Improves session lookup performance.
-
-## Server Config with DB
-
-Database adapter injected via context:
-
-```ts
-// server/auth.config.ts
-import { defineServerAuth } from '@onmax/nuxt-better-auth/config'
-
-export default defineServerAuth(({ db }) => ({
- database: db, // Already configured when hub.database: true
- emailAndPassword: { enabled: true }
-}))
-```
-
-## Manual Database Setup
-
-Without NuxtHub, configure manually:
-
-```ts
-// server/auth.config.ts
-import { drizzle } from 'drizzle-orm/...'
-import { defineServerAuth } from '@onmax/nuxt-better-auth/config'
-
-const db = drizzle(...)
-
-export default defineServerAuth({
- database: drizzleAdapter(db, { provider: 'sqlite' })
-})
-```
-
-## Migrations
-
-Better Auth creates tables automatically on first run. For production, generate migrations:
-
-```bash
-# Using Better Auth CLI
-npx better-auth generate
-```
+If you are not using NuxtHub, configure the Better Auth adapter yourself in `server/auth.config.ts` and manage schema generation separately.
diff --git a/docs/public/.well-known/skills/nuxt-better-auth/references/installation.md b/docs/public/.well-known/skills/nuxt-better-auth/references/installation.md
index 0fd0c67e..26282be9 100644
--- a/docs/public/.well-known/skills/nuxt-better-auth/references/installation.md
+++ b/docs/public/.well-known/skills/nuxt-better-auth/references/installation.md
@@ -1,123 +1,65 @@
-# Installation & Configuration
+# Installation and configuration
-## Install
+## Happy path
```bash
-pnpm add @onmax/nuxt-better-auth better-auth
+npx nuxi module add @onmax/nuxt-better-auth@alpha
```
-**Version Requirements:**
+Required files:
-- `@onmax/nuxt-better-auth`: `^0.0.2-alpha.12` (alpha)
-- `better-auth`: `^1.0.0` (module tested with `1.4.7`)
-- `@nuxthub/core`: `^0.10.0` (optional, for database)
+- `server/auth.config.ts`
+- `app/auth.config.ts` or the equivalent file inside your `srcDir`
+- `.env` with `NUXT_BETTER_AUTH_SECRET`
-## Module Setup
+## Required environment variables
-```ts
-// nuxt.config.ts
-export default defineNuxtConfig({
- modules: ['@onmax/nuxt-better-auth'],
- auth: {
- serverConfig: 'server/auth.config', // default
- clientConfig: 'app/auth.config', // default
- clientOnly: false, // true for external auth backend
- redirects: {
- login: '/login', // redirect when auth required
- guest: '/' // redirect when already logged in
- }
- }
-})
+```ini
+NUXT_BETTER_AUTH_SECRET=replace-with-a-random-32-character-secret
```
-## Environment Variables
+Optional but commonly required in production:
-```bash
-# Required (min 32 chars)
-NUXT_BETTER_AUTH_SECRET=your-secret-key-at-least-32-characters
-# Legacy fallback also supported: BETTER_AUTH_SECRET=your-secret-key-at-least-32-characters
-
-# Required in production for OAuth
+```ini
NUXT_PUBLIC_SITE_URL=https://your-domain.com
```
-## Server Config
+`BETTER_AUTH_SECRET` is still accepted as a fallback. Prefer `NUXT_BETTER_AUTH_SECRET`.
+
+## Minimal module setup
+
+```ts
+export default defineNuxtConfig({
+ modules: ['@onmax/nuxt-better-auth'],
+})
+```
+
+## Minimal server config
```ts
-// server/auth.config.ts
import { defineServerAuth } from '@onmax/nuxt-better-auth/config'
-// Object syntax (simplest)
export default defineServerAuth({
- emailAndPassword: { enabled: true },
- // OAuth providers
- socialProviders: {
- github: {
- clientId: process.env.GITHUB_CLIENT_ID as string,
- clientSecret: process.env.GITHUB_CLIENT_SECRET as string
- }
+ emailAndPassword: {
+ enabled: true,
},
})
-
-// Or function syntax (access context like runtimeConfig, db)
-export default defineServerAuth(({ runtimeConfig, db }) => ({
- emailAndPassword: { enabled: true },
- socialProviders: {
- github: {
- clientId: runtimeConfig.github.clientId,
- clientSecret: runtimeConfig.github.clientSecret
- }
- },
- session: {
- expiresIn: 60 * 60 * 24 * 7, // 7 days (default)
- updateAge: 60 * 60 * 24, // Update every 24h (default)
- freshAge: 60 * 60 * 24, // Consider fresh for 24h (default, 0 to disable)
- cookieCache: {
- enabled: true,
- maxAge: 60 * 5 // 5 minutes cookie cache
- }
- }
-}))
```
-Context available in `defineServerAuth`:
-
-- `runtimeConfig` - Nuxt runtime config
-- `db` - Database adapter (when NuxtHub enabled)
-
-### Session Options
-
-| Option | Default | Description |
-| ----------------------- | ------------------ | --------------------------------------------- |
-| `expiresIn` | `604800` (7 days) | Session lifetime in seconds |
-| `updateAge` | `86400` (24 hours) | How often to refresh session expiry |
-| `freshAge` | `86400` (24 hours) | Session considered "fresh" period (0 = never) |
-| `cookieCache.enabled` | `false` | Enable cookie caching to reduce DB queries |
-| `cookieCache.maxAge` | `300` (5 minutes) | Cookie cache lifetime |
-| `disableSessionRefresh` | `false` | Disable automatic session refresh |
-
-## Client Config
+## Minimal client config
```ts
-// app/auth.config.ts
import { defineClientAuth } from '@onmax/nuxt-better-auth/config'
-// Object syntax (simplest)
-export default defineClientAuth({
- // Client-side plugin options (e.g., passkey, twoFactor)
-})
-
-// Or function syntax (access context like siteUrl)
-export default defineClientAuth(({ siteUrl }) => ({
- // siteUrl contains the resolved base URL
-}))
+export default defineClientAuth({})
```
-## NuxtHub Integration
+## Important rules
-```ts
-// nuxt.config.ts
-export default defineNuxtConfig({
+- Do not set `secret` manually in `defineServerAuth()`. The module injects it.
+- Do not set `baseURL` manually in full mode. The module resolves it.
+- Use `auth.clientOnly = true` only when Better Auth runs on an external backend.
+- For database-backed auth with the shortest setup, prefer NuxtHub.
modules: ['@nuxthub/core', '@onmax/nuxt-better-auth'],
hub: { database: true },
auth: {
diff --git a/docs/public/.well-known/skills/nuxt-better-auth/references/plugins.md b/docs/public/.well-known/skills/nuxt-better-auth/references/plugins.md
index e456850d..ba990ffc 100644
--- a/docs/public/.well-known/skills/nuxt-better-auth/references/plugins.md
+++ b/docs/public/.well-known/skills/nuxt-better-auth/references/plugins.md
@@ -1,123 +1,42 @@
-# Better Auth Plugins
+# Better Auth plugins
-The module supports all Better Auth plugins. Configure in both server and client configs.
+## Rule of thumb
-## Server Plugin Setup
+If a Better Auth plugin has a client companion, register both:
+
+- server plugin in `server/auth.config.ts`
+- client plugin in `app/auth.config.ts`
+
+## Example
```ts
-// server/auth.config.ts
-import { defineServerAuth } from '@onmax/nuxt-better-auth/config'
-import { admin, twoFactor, passkey, multiSession } from 'better-auth/plugins'
+import { admin, twoFactor } from 'better-auth/plugins'
export default defineServerAuth({
- emailAndPassword: { enabled: true },
- plugins: [
- admin(),
- twoFactor({ issuer: 'MyApp' }),
- passkey(),
- multiSession()
- ]
+ plugins: [admin(), twoFactor()],
})
```
-## Client Plugin Setup
-
```ts
-// app/auth.config.ts
-import { defineClientAuth } from '@onmax/nuxt-better-auth/config'
-import { adminClient, twoFactorClient, passkeyClient, multiSessionClient } from 'better-auth/client/plugins'
+import { adminClient, twoFactorClient } from 'better-auth/client/plugins'
export default defineClientAuth({
- plugins: [
- adminClient(),
- twoFactorClient(),
- passkeyClient(),
- multiSessionClient()
- ]
+ plugins: [adminClient(), twoFactorClient()],
})
```
-## Common Plugins
-
-### Admin
-
-Role-based access control:
-
-```ts
-// Server
-import { admin } from 'better-auth/plugins'
-plugins: [admin()]
-
-// Client
-import { adminClient } from 'better-auth/client/plugins'
-plugins: [adminClient()]
-```
-
-Usage:
-
-```ts
-// Protect route
-await requireUserSession(event, { user: { role: 'admin' } })
-
-// Client: set user role
-await client.admin.setRole({ userId: 'xxx', role: 'admin' })
-```
-
-### Two-Factor (2FA)
-
-```ts
-// Server
-import { twoFactor } from 'better-auth/plugins'
-plugins: [twoFactor({ issuer: 'MyApp' })]
-
-// Client
-import { twoFactorClient } from 'better-auth/client/plugins'
-plugins: [twoFactorClient()]
-```
-
-Usage:
-
-```ts
-// Enable 2FA
-const { totpURI } = await client.twoFactor.enable({ password: 'xxx' })
-// Show QR code with totpURI
+## Common plugin pairs
-// Verify OTP on login
-await client.twoFactor.verifyTotp({ code: '123456' })
-```
+| Server | Client |
+| --- | --- |
+| `admin()` | `adminClient()` |
+| `twoFactor()` | `twoFactorClient()` |
+| `passkey()` | `passkeyClient()` |
+| `multiSession()` | `multiSessionClient()` |
-### Passkey
+## Why it matters
-WebAuthn/FIDO2 authentication:
-
-```ts
-// Server
-import { passkey } from 'better-auth/plugins'
-plugins: [passkey()]
-
-// Client
-import { passkeyClient } from 'better-auth/client/plugins'
-plugins: [passkeyClient()]
-```
-
-Usage:
-
-```ts
-// Register passkey
-await client.passkey.addPasskey()
-
-// Sign in with passkey
-await signIn.passkey()
-```
-
-### Multi-Session
-
-Allow multiple concurrent sessions:
-
-```ts
-// Server
-import { multiSession } from 'better-auth/plugins'
-plugins: [multiSession()]
+Without the matching client plugin, client-side methods and inferred types for that feature are incomplete.
// Client
import { multiSessionClient } from 'better-auth/client/plugins'
diff --git a/docs/public/.well-known/skills/nuxt-better-auth/references/route-protection.md b/docs/public/.well-known/skills/nuxt-better-auth/references/route-protection.md
index 31c8816b..c193ee31 100644
--- a/docs/public/.well-known/skills/nuxt-better-auth/references/route-protection.md
+++ b/docs/public/.well-known/skills/nuxt-better-auth/references/route-protection.md
@@ -1,105 +1,32 @@
-# Route Protection
+# Route protection
-Three layers of protection: route rules, page meta, and server middleware.
+## Layers
-## Route Rules (Global)
+1. `routeRules` or `nitro.routeRules` for broad app sections
+2. `definePageMeta({ auth })` for page-level overrides
+3. `requireUserSession(event)` for server-side enforcement
-Define auth requirements in `nuxt.config.ts`:
+## Recommended split
-```ts
-export default defineNuxtConfig({
- routeRules: {
- '/admin/**': { auth: { user: { role: 'admin' } } },
- '/dashboard/**': { auth: 'user' },
- '/login': { auth: 'guest' },
- '/public/**': { auth: false }
- }
-})
-```
-
-## Auth Modes
-
-| Mode | Behavior |
-| ----------------- | ------------------------------------------------------ |
-| `'user'` | Requires authenticated user |
-| `'guest'` | Only unauthenticated users (redirects logged-in users) |
-| `{ user: {...} }` | Requires user matching specific properties |
-| `false` | No protection |
-
-## Page Meta (Per-Page)
-
-Override or define auth for specific pages:
-
-```vue
-
-```
-
-```vue
-
-```
-
-```vue
-
-```
+- use route rules and page meta for navigation UX
+- use `requireUserSession(event)` for protected API routes and mutations
-## User Property Matching
+## Common route rules
```ts
-// Single value
-{ auth: { user: { role: 'admin' } } }
-
-// OR logic (array)
-{ auth: { user: { role: ['admin', 'moderator'] } } }
-
-// AND logic (multiple fields)
-{ auth: { user: { role: 'admin', verified: true } } }
-```
-
-## Redirect Configuration
-
-```ts
-// nuxt.config.ts
export default defineNuxtConfig({
- auth: {
- redirects: {
- login: '/login', // Where to redirect unauthenticated users
- guest: '/dashboard' // Where to redirect logged-in users from guest pages
- }
- }
-})
-```
-
-## Server Middleware
-
-Auth middleware runs on all `/api/**` routes matching `routeRules`.
-
-For custom API protection, use `requireUserSession()`:
-
-```ts
-// server/api/admin/[...].ts
-export default defineEventHandler(async (event) => {
- await requireUserSession(event, { user: { role: 'admin' } })
- // Handle request
+ routeRules: {
+ '/app/**': { auth: 'user' },
+ '/login': { auth: 'guest' },
+ '/admin/**': { auth: { user: { role: 'admin' } } },
+ },
})
```
-## Priority Order
-
-1. `definePageMeta({ auth })` - highest priority
-2. `routeRules` patterns - matched by path
-3. Default: no protection
-
-## Prerendered Pages
+## Matching
-Auth checks skip during prerender hydration. Session fetched client-side after hydration completes.
+- `'user'`: authenticated users only
+- `'guest'`: unauthenticated users only
+- `{ user: { ... } }`: user must match fields
+- arrays inside a field mean OR matching
+- multiple fields mean AND matching
diff --git a/docs/public/.well-known/skills/nuxt-better-auth/references/server-auth.md b/docs/public/.well-known/skills/nuxt-better-auth/references/server-auth.md
index daab9f3b..e86bd4b3 100644
--- a/docs/public/.well-known/skills/nuxt-better-auth/references/server-auth.md
+++ b/docs/public/.well-known/skills/nuxt-better-auth/references/server-auth.md
@@ -1,123 +1,45 @@
-# Server-Side Authentication
+# Server-side authentication
-## serverAuth()
+## Helpers
-Get the Better Auth instance for advanced operations:
+- `serverAuth(event?)`
+- `getUserSession(event)`
+- `getRequestSession(event)`
+- `requireUserSession(event, options?)`
+- `createSession(event, userId)`
+- `setSessionCookie(event, token)`
-```ts
-// server/api/custom.ts
-export default defineEventHandler(async (event) => {
- const auth = serverAuth()
- // Access full Better Auth API
- const sessions = await auth.api.listSessions({ headers: event.headers })
- return sessions
-})
-```
-
-Module-level singleton (safe to call multiple times - returns cached instance).
-
-### Available Server Methods
+All of them are auto-imported inside `server/`.
-Via `serverAuth().api`:
+## Which helper to use
-```ts
-const auth = serverAuth()
-
-// Session management
-await auth.api.listSessions({ headers: event.headers })
-await auth.api.revokeSession({ sessionId: 'xxx' }, { headers: event.headers })
-await auth.api.revokeOtherSessions({ headers: event.headers })
-await auth.api.revokeSessions({ headers: event.headers })
-
-// User management (with admin plugin)
-await auth.api.setRole({ userId: 'xxx', role: 'admin' }, { headers: event.headers })
-```
-
-## getUserSession()
+| Need | Helper |
+| --- | --- |
+| Access raw Better Auth APIs | `serverAuth(event)` |
+| Read session if it exists | `getUserSession(event)` |
+| Reuse the same session lookup in one request | `getRequestSession(event)` |
+| Enforce auth | `requireUserSession(event, options?)` |
+| Create session in a custom flow | `createSession(event, userId)` |
+| Attach session cookie manually | `setSessionCookie(event, token)` |
-Get current session without throwing (returns null if not authenticated):
+## Common pattern
```ts
export default defineEventHandler(async (event) => {
- const result = await getUserSession(event)
- if (!result) {
- return { guest: true }
- }
- return { user: result.user }
-})
-```
-
-Returns `{ user: AuthUser, session: AuthSession } | null`.
-
-## requireUserSession()
-
-Enforce authentication - throws if not authenticated:
+ const { user } = await requireUserSession(event, {
+ user: { role: 'admin' },
+ })
-```ts
-export default defineEventHandler(async (event) => {
- const { user, session } = await requireUserSession(event)
- // user and session are guaranteed to exist
return { userId: user.id }
})
```
-- Throws `401` if not authenticated
-- Throws `403` if user matching fails
-
-## User Matching
-
-Restrict access based on user properties:
-
-```ts
-// Single value - exact match
-await requireUserSession(event, {
- user: { role: 'admin' }
-})
-
-// Array - OR logic (any value matches)
-await requireUserSession(event, {
- user: { role: ['admin', 'moderator'] }
-})
-
-// Multiple fields - AND logic (all must match)
-await requireUserSession(event, {
- user: { role: 'admin', verified: true }
-})
-```
-
-## Custom Rules
-
-For complex validation logic:
-
-```ts
-await requireUserSession(event, {
- rule: ({ user, session }) => {
- return user.subscription?.active && user.points > 100
- }
-})
-
-// Combined with user matching
-await requireUserSession(event, {
- user: { verified: true },
- rule: ({ user }) => user.subscription?.plan === 'pro'
-})
-```
-
-## Pattern Examples
-
-```ts
-// Admin-only endpoint
-export default defineEventHandler(async (event) => {
- const { user } = await requireUserSession(event, {
- user: { role: 'admin' }
- })
- return getAdminData()
-})
+## Matching rules
-// Premium feature
-export default defineEventHandler(async (event) => {
- await requireUserSession(event, {
- rule: ({ user }) => ['pro', 'enterprise'].includes(user.plan)
+- scalar value: exact match
+- array value: OR match
+- multiple fields: AND match
+- `rule`: custom callback for logic that field matching cannot express
})
return getPremiumContent()
})
diff --git a/docs/public/.well-known/skills/nuxt-better-auth/references/types.md b/docs/public/.well-known/skills/nuxt-better-auth/references/types.md
index 2531fd16..fccc7e9f 100644
--- a/docs/public/.well-known/skills/nuxt-better-auth/references/types.md
+++ b/docs/public/.well-known/skills/nuxt-better-auth/references/types.md
@@ -1,123 +1,37 @@
-# TypeScript Types
+# TypeScript types
-## Module Alias
-
-Import types from the module alias:
-
-```ts
-import type { AuthUser, AuthSession, ServerAuthContext, AppAuthClient } from '#nuxt-better-auth'
-```
-
-## Core Types
-
-### AuthUser
-
-User object returned by `useUserSession()` and `requireUserSession()`:
-
-```ts
-interface AuthUser {
- id: string
- email: string
- name?: string
- image?: string
- emailVerified: boolean
- createdAt: Date
- updatedAt: Date
- // Plus any fields from plugins (role, etc.)
-}
-```
-
-### AuthSession
-
-Session object:
+## Primary imports
```ts
-interface AuthSession {
- id: string
- userId: string
- expiresAt: Date
- // token is filtered from exposed data
-}
+import type {
+ AuthUser,
+ AuthSession,
+ AuthMeta,
+ AuthRouteRules,
+ RequireSessionOptions,
+ AuthSocialProviderId,
+} from '#nuxt-better-auth'
```
-## Type Inference
+## Key guarantees
-Types are automatically inferred from your server config. The module uses `InferUser` and `InferSession` from Better Auth:
-
-```ts
-// Inferred from server/auth.config.ts
-type AuthUser = InferUser
-type AuthSession = InferSession
-```
+- `AuthUser` and `AuthSession` are inferred from your Better Auth config
+- plugin fields flow into `useUserSession()`, `requireUserSession()`, and auth route matching
+- `AuthSocialProviderId` is inferred from configured social providers
-## Plugin Type Augmentation
+## When to augment manually
-When using plugins, types extend automatically:
+Only add manual module augmentation if inference is not enough or you need to declare project-specific fields in advance.
```ts
-// With admin plugin
-interface AuthUser {
- // ... base fields
- role: 'user' | 'admin'
-}
+import '#nuxt-better-auth'
-// With 2FA plugin
-interface AuthUser {
- // ... base fields
- twoFactorEnabled: boolean
-}
-```
-
-## ServerAuthContext
-
-Available in `defineServerAuth()` callback:
-
-```ts
-interface ServerAuthContext {
- runtimeConfig: RuntimeConfig
- db?: DrizzleDatabase // When NuxtHub enabled
-}
-```
-
-## Using Types in Components
-
-```vue
-
-```
-
-## Using Types in Server
-
-```ts
-// server/utils/helpers.ts
-import type { AuthUser, AuthSession } from '#nuxt-better-auth'
-
-export function isAdmin(user: AuthUser): boolean {
- return user.role === 'admin'
+declare module '#nuxt-better-auth' {
+ interface AuthUser {
+ customField?: string
+ }
}
```
-
-## Custom User Fields
-
-Extend user type via Better Auth config:
-
-```ts
-// server/auth.config.ts
-import { defineServerAuth } from '@onmax/nuxt-better-auth/config'
-
-export default defineServerAuth({
- user: {
- additionalFields: {
- plan: { type: 'string' },
- credits: { type: 'number' }
}
}
})