@xenterprises/nuxt-x-neon-auth
v0.3.1
Published
A reusable Nuxt layer providing comprehensive authentication with Neon Auth integration
Downloads
302
Readme
nuxt-x-neon-auth
Nuxt layer providing authentication with Neon Auth (Better Auth) integration. Includes pre-built pages, components, composables, and global auth middleware.
Install
npm install @xenterprises/nuxt-x-neon-authAdd to your nuxt.config.ts:
export default defineNuxtConfig({
extends: ["@xenterprises/nuxt-x-neon-auth"],
});Usage
<script setup lang="ts">
const { login, signup, logout, isLoading, isAuthenticated, checkAuth } = useXAuth();
onMounted(() => checkAuth());
await login("[email protected]", "password123");
await signup("[email protected]", "password123");
await logout();
</script>Configuration
app.config.ts
export default defineAppConfig({
xAuth: {
redirects: {
login: "/auth/login",
signup: "/auth/signup",
afterLogin: "/",
afterSignup: "/",
afterLogout: "/auth/login",
},
features: {
oauth: false,
magicLink: false,
otp: false,
forgotPassword: true,
},
socialLoginProviders: ["google", "github"],
},
});Options Table
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| redirects.login | string | "/auth/login" | Login page path |
| redirects.signup | string | "/auth/signup" | Signup page path |
| redirects.afterLogin | string | "/" | Redirect after login |
| redirects.afterSignup | string | "/" | Redirect after signup |
| redirects.afterLogout | string | "/auth/login" | Redirect after logout |
| features.oauth | boolean | false | Enable OAuth/social login |
| features.magicLink | boolean | false | Enable magic link auth |
| features.otp | boolean | false | Enable OTP auth |
| features.forgotPassword | boolean | true | Enable password reset |
| socialLoginProviders | OAuthProvider[] | ["google"] | OAuth providers to display |
nuxt.config.ts
The layer provides:
ssr: false— client-side rendering (auth relies on browser APIs)@nuxt/uiand@nuxtjs/color-modemodules- Tailwind CSS v4 via
@tailwindcss/viteplugin
Override any of these in your consuming app's nuxt.config.ts.
Environment Variables
| Variable | Required | Description |
|----------|----------|-------------|
| NUXT_PUBLIC_NEON_AUTH_URL | Yes | Neon Auth endpoint URL (e.g. https://your-project.neonauth.xxx.neon.tech/your-db/auth) |
Composables
useXAuth()
High-level composable with toast notifications, loading states, and navigation.
| Property / Method | Type | Description |
|-------------------|------|-------------|
| user | () => Promise<User \| null> | Get current user |
| isLoading | Ref<boolean> | Loading state |
| isAuthenticated | Ref<boolean> | Auth status (call checkAuth() first) |
| emailSent | Ref<boolean> | Whether an email was sent (magic link / forgot password) |
| codeSent | Ref<boolean> | Whether an OTP code was sent |
| checkAuth() | () => Promise<User \| null> | Check auth status and update isAuthenticated |
| login(email, password) | () => Promise<User \| null> | Sign in with credentials |
| signup(email, password) | () => Promise<User \| null> | Create account |
| logout() | () => Promise<boolean> | Sign out |
| forgotPassword(email) | () => Promise<boolean> | Send password reset email |
| resetPassword(code, password) | () => Promise<true \| {error}> | Reset password with token |
| loginWithProvider(provider) | () => Promise<boolean> | OAuth sign in |
| loginWithOAuth(provider) | () => Promise<boolean> | Alias for loginWithProvider |
| sendOtp(email) | () => Promise<boolean> | Send OTP code |
| verifyOtp(code) | () => Promise<User \| null> | Verify OTP code |
| sendMagicLink(email) | () => Promise<boolean> | Send magic link email |
| handleMagicLinkCallback(token) | () => Promise<true \| {error}> | Verify magic link token |
| changePassword(current, new) | () => Promise<boolean> | Change password (authenticated) |
| updateUser({name?, image?}) | () => Promise<boolean> | Update user profile |
| deleteAccount(password) | () => Promise<boolean> | Delete user account |
| resetState() | () => void | Reset emailSent and codeSent |
| authClient | object | Direct access to Neon Auth client |
useXNeonAuth()
Lower-level composable wrapping the Neon Auth client with Vue reactivity.
| Method | Description |
|--------|-------------|
| currentUser() | Get current session user |
| signInWithCredential(email, password) | Sign in with email/password |
| signUpWithCredential(email, password, name?) | Create account |
| signOut() | Sign out |
| signInWithOAuth(provider, options?) | OAuth sign in |
| sendOtpCode(email) | Send OTP verification code |
| verifyOtpCode(otp) | Verify OTP code |
| sendMagicLinkEmail(email, options?) | Send magic link |
| verifyMagicLink(token) | Verify magic link token |
| sendForgotPasswordEmail(email) | Send password reset email |
| changePassword(current, new) | Change password |
| updateUser({name?, image?}) | Update profile |
| deleteAccount(password) | Delete account |
| authClient | Raw Neon Auth client |
All methods return { status: "ok", data? } or { status: "error", error: { message } }.
Pages
| Path | Description |
|------|-------------|
| /auth/login | Login page |
| /auth/signup | Signup page |
| /auth/forgot-password | Password reset request |
| /auth/magic-link | Magic link sign in |
| /auth/otp | OTP sign in |
| /auth/logout | Logout page |
| /auth/handler/[slug] | Auth callback handler (magic-link, password-reset, oauth, email-verification) |
Components
| Component | Props | Description |
|-----------|-------|-------------|
| <XAuthLogin /> | — | Login form with email/password, OAuth, OTP/magic link links |
| <XAuthSignup /> | — | Signup form with email/password and OAuth |
| <XAuthForgotPassword /> | — | Password reset request form |
| <XAuthMagicLink /> | — | Magic link email form |
| <XAuthOtp /> | — | OTP email + code verification form |
| <XAuthMagicLinkCallback /> | — | Magic link token verification handler |
| <XAuthOAuthButton /> | provider, variant?, color? | Single OAuth provider button |
| <XAuthOAuthButtonGroup /> | providers? | Group of OAuth buttons from config |
| <XAuthErrorBoundary /> | error?, title?, retry? | Error display with optional retry |
| <XAuthHandler /> | type, redirectTo?, redirectDelay? | Generic auth callback handler |
XAuthHandler Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| type | "magic-link" \| "password-reset" \| "oauth" \| "email-verification" | required | Handler type |
| redirectTo | string | "/" | Redirect after success |
| redirectDelay | number | 1500 | Delay before redirect (ms) |
XAuthOAuthButton Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| provider | OAuthProvider | required | OAuth provider name |
| variant | string | "outline" | Button variant |
| color | string | "neutral" | Button color |
Middleware
The layer includes a global auth middleware (auth.global.ts) that:
- Redirects authenticated users away from auth pages (
/auth/*) to home - Redirects unauthenticated users from protected pages to
/auth/login - Allows unauthenticated access to
/handler/*routes (callbacks)
Supported OAuth Providers
Google, GitHub, Apple, Microsoft, Discord, Facebook, Twitter, LinkedIn, GitLab, Spotify, Twitch, Slack, Notion, Linear, Figma, Atlassian, Salesforce, Cognito, and more (30+ via Better Auth).
Error Reference
All useXAuth() methods show toast notifications on error. The lower-level useXNeonAuth() returns structured errors:
| Error | Context | Description |
|-------|---------|-------------|
| "No OTP session found" | verifyOtpCode | Called verify without first sending a code |
| "Invalid credentials" | signInWithCredential | Wrong email or password |
| "Email already exists" | signUpWithCredential | Account already registered |
| "Token expired" | verifyMagicLink, resetPassword | Auth token expired |
| "Incorrect password" | changePassword | Current password wrong |
How It Works
Neon Auth Client —
useXNeonAuth()creates a client viacreateAuthClient()from@neondatabase/neon-js/auth, pointing to your Neon Auth endpoint. This handles all HTTP communication with the auth backend.High-level Composable —
useXAuth()wrapsuseXNeonAuth()with loading states, toast notifications (via Nuxt UI), and automatic navigation after auth events.Global Middleware —
auth.global.tsruns on every route change, checking session status viacurrentUser(). Authenticated users are bounced from auth pages; unauthenticated users are bounced from protected pages.Pre-built Pages — Each auth page renders a corresponding component using the
authlayout (centered card on gray background). The[slug]handler page routes magic-link, password-reset, OAuth, and email-verification callbacks.Components — Built with Nuxt UI v4's
UAuthForm,UButton,UIcon, etc. Forms use Zod schemas for validation. OAuth buttons are configurable viaapp.config.ts.
Layer Architecture
nuxt.config.ts— Registers CSS, modules (@nuxt/ui,@nuxtjs/color-mode), Tailwind, and setsssr: false.app.config.ts— Default auth configuration (redirects, features, providers) with TypeScript augmentation forAppConfigInput.app/composables/—useXNeonAuth(low-level client wrapper) anduseXAuth(high-level with UX).app/middleware/— Global auth route guard.app/components/X/Auth/— 10 auth components.app/pages/auth/— 7 auth pages.app/layouts/auth.vue— Centered card layout with logo slot.app/types/index.ts— TypeScript types for auth responses, user sessions, OAuth providers, and config.
