Cookbook & Integration Examples
Realistic recipes for Laravel Sanctum, custom REST APIs, SSR Dashboards, and Session Managers.
Reference & Recipes Nuxt 3.12+ / Nuxt 4 / TypeScript
Laravel Sanctum / API Integration
Laravel APIs often issue plaintext API tokens via Sanctum:
Laravel Controller
php
// app/Http/Controllers/AuthController.php
public function login(Request $request)
{
$credentials = $request->validate([
'email' => 'required|email',
'password' => 'required',
]);
if (!Auth::attempt($credentials)) {
return response()->json(['message' => 'Invalid credentials'], 401);
}
$user = Auth::user();
$token = $user->createToken('nuxt-session')->plainTextToken;
return response()->json([
'success' => true,
'message' => 'Authenticated successfully',
'data' => [
'token' => $token,
'user' => $user,
]
]);
}
Nuxt Configuration
typescript
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['nuxt-bearer-auth'],
bearerAuth: {
apiBaseUrl: 'https://laravel-api.example.com/api',
redisUrl: process.env.REDIS_URL,
endpoints: {
login: 'login',
logout: 'logout',
me: 'user',
},
},
})
Generic Node/Go/Python Bearer API
For a FastAPI or Express backend issuing JWT bearer tokens:
typescript
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['nuxt-bearer-auth'],
bearerAuth: {
apiBaseUrl: 'https://api.myapp.com',
endpoints: {
login: 'auth/token',
refresh: 'auth/refresh',
me: 'auth/profile',
},
responsePaths: {
token: ['access_token'],
refreshToken: ['refresh_token'],
user: ['user_info'],
}
}
})
SSR Authenticated Dashboard Recipe
Here is a full-page SSR Dashboard that fetches data securely during server rendering:
vue
<script setup lang="ts">
// Page requires authentication (protected by default middleware)
const auth = useBearerAuth()
// Fetch dashboard data during SSR using the Nuxt server route
const { data: analytics, pending, error } = await useFetch('/api/dashboard/stats')
async function handleLogout() {
await auth.logout()
}
</script>
<template>
<div class="dashboard-layout">
<header class="flex justify-between items-center p-4 border-b">
<div>
<h2 class="text-xl font-bold">Welcome back, {{ auth.user.value?.name }}</h2>
<p class="text-sm text-gray-500">{{ auth.user.value?.email }}</p>
</div>
<button @click="handleLogout" class="px-4 py-2 bg-red-600 text-white rounded">
Log Out
</button>
</header>
<main class="p-6">
<div v-if="pending">Loading dashboard metrics...</div>
<div v-else-if="error">Error loading metrics: {{ error.message }}</div>
<div v-else class="grid grid-cols-3 gap-6">
<div class="metric-card">
<span class="label">Total Orders</span>
<span class="val">{{ analytics?.totalOrders }}</span>
</div>
<div class="metric-card">
<span class="label">Revenue</span>
<span class="val">${{ analytics?.revenue }}</span>
</div>
<div class="metric-card">
<span class="label">Active Sessions</span>
<span class="val">{{ analytics?.activeSessions }}</span>
</div>
</div>
</main>
</div>
</template>
Multi-Device Session Manager UI
Allow your users to view all currently active browser sessions and remotely revoke unrecognized devices:
vue
<script setup lang="ts">
import type { PublicSession } from 'nuxt-bearer-auth'
// GET /api/auth/sessions returns { sessions: PublicSession[] }
const { data, refresh, pending } = await useFetch<{ sessions: PublicSession[] }>('/api/auth/sessions')
const revokingId = ref<string | null>(null)
async function revoke(id: string) {
revokingId.value = id
try {
await $fetch(`/api/auth/sessions/${id}`, { method: 'DELETE' })
await refresh()
} finally {
revokingId.value = null
}
}
</script>
<template>
<div class="max-w-3xl mx-auto p-6">
<h2 class="text-2xl font-bold mb-4">Security & Active Devices</h2>
<p class="text-gray-400 mb-6">Manage active sessions logged into your account across devices.</p>
<div v-if="pending" class="text-gray-400">Loading active sessions...</div>
<div v-else class="space-y-4">
<div
v-for="s in data?.sessions"
:key="s.id"
class="p-4 rounded-xl border border-gray-800 bg-gray-900/60 flex items-center justify-between"
>
<div class="space-y-1">
<div class="flex items-center gap-2">
<span class="font-medium text-white">{{ s.userAgent || 'Unknown Device' }}</span>
<span class="text-xs px-2 py-0.5 rounded bg-emerald-500/10 text-emerald-400 border border-emerald-500/20">
Active
</span>
</div>
<p class="text-xs text-gray-400">
IP: {{ s.ipAddress || 'Unknown' }} · Last active: {{ new Date(s.lastActivity).toLocaleString() }}
</p>
</div>
<button
@click="revoke(s.id)"
:disabled="revokingId === s.id"
class="px-3 py-1.5 text-xs font-medium text-red-400 hover:text-red-300 hover:bg-red-500/10 rounded-lg border border-red-500/20 transition"
>
{{ revokingId === s.id ? 'Revoking...' : 'Revoke Session' }}
</button>
</div>
</div>
</div>
</template>