Nuxt
Build your first authentication flow with Aura Auth and Nuxt (Nitro)
This guide walks you through creating a complete authentication flow using Aura Auth in a Nuxt application.
Overview
Nuxt runs on the Nitro server engine, which natively uses h3 event handlers. Aura Auth integrates cleanly because you can map standard Web Requests via Nitro's toWebRequest utility and route them to Aura Auth handlers.
Before continuing, complete the installation and initial setup:
- Quick Start Guide to create your Aura Auth instance
- TypeScript Configuration for TypeScript-specific setup
- Nuxt Integration App for a fully working example
Then use this guide to integrate Aura Auth with a Nuxt server using best practices.
What You'll Build
You will create a small Nuxt setup with:
- a shared
shared/auth.tsserver configuration - a Nitro route at
server/api/auth/[...aura].tsthat forwards requests to Aura Auth handlers - a shared browser client in
shared/auth-client.ts - a Vue example that signs users in, reads the current session, and signs users out
Project Structure
Environment Setup
Create a .env file at the root of your project to store secrets securely.
# 32-bytes (256-bit) secret used to sign/encrypt sessions. Use a secure random value.
AURA_AUTH_SECRET="base64-or-hex-32-bytes"
AURA_AUTH_SALT="base64-or-hex-32-bytes".env file to version control. Use a secret manager in production.Setup Aura Auth
HTTP Handlers
Create an auth.ts file in your shared directory so it can be reused by both Nitro endpoints and client utilities.
import { createAuth } from "@aura-stack/auth"
export const auth = createAuth({
oauth: ["github"],
basePath: "/api/auth",
baseURL: "http://localhost:3000",
})
export const { handlers, jose, api } = authbasePath must match the route mounted in server/api/auth/[...aura].ts. baseURL should point to your local development server or deployed application URL.
Client API
import { createAuthClient } from "@aura-stack/auth/client"
export const authClient = createAuthClient({
basePath: "/api/auth",
baseURL: "http://localhost:3000",
})The baseURL should point to your server's URL, and basePath MUST match the path where your auth routes are mounted.
Mount HTTP Handlers
Create a wildcard catch-all route that delegates to Aura Auth's ALL handler. Nitro's toWebRequest utility ensures handlers.ALL receives a standard Request object.
import { toWebRequest } from "h3"
import { handlers } from "~/shared/auth"
export default defineEventHandler(async (event) => {
const webRequest = toWebRequest(event)
return await handlers.ALL(webRequest)
})/api/auth/*.Usage
Client-Side Rendering (CSR)
With Nuxt, you can use the built-in createAuthClient utility to handle authentication directly from your Vue components.
<script setup lang="ts">
import { ref, onMounted } from "vue"
import { authClient } from "~/shared/auth-client"
const session = ref(null)
onMounted(async () => {
const result = await authClient.getSession()
session.value = result.session
})
const signIn = () => {
void authClient.signIn("github")
}
const signOut = async () => {
await authClient.signOut()
session.value = null
}
</script>
<template>
<div>
<div v-if="session">
<p>Welcome, {{ session.user?.name }}</p>
<button @click="signOut">Sign Out</button>
</div>
<div v-else>
<button @click="signIn">Sign in with GitHub</button>
</div>
</div>
</template>This pattern works well for navigation bars, login pages, and other components that only need client-side session state.
Common Pitfalls
- Keep
basePathaligned with the Nitro route. If the route lives atserver/api/auth/[...aura].ts,basePathshould stay/api/auth. - Use the shared auth module everywhere. Import
shared/auth.tsfrom the Nitro route and any server-side helpers so there is one auth configuration. - Treat the browser client as optional. Use
authClientfor interactive UI, but keep the shared server handler in place so session handling stays consistent.