Nuxt Module
mbl-auth ยท v1.0.0 npm

Authentication that ships.

mbl-auth wraps Supabase with a production-ready Nuxt 4 module: SSR-safe sessions, role-based middleware, and a full admin API โ€” drop it in and move on.

Install

terminal
npm install @madebylars.com/mbl-auth

What you get

๐Ÿ”

SSR sessions via cookies

Uses @supabase/ssr for secure, server-rendered session handling. No localStorage leaking on first render.

๐ŸŽญ

Role-based access control

Configurable roles stored in Supabase user metadata. The admin middleware and hasRole() helper make authorization trivial.

๐Ÿ”—

OAuth & magic link

Built-in /confirm callback route handles OAuth redirects and magic links automatically.

๐Ÿ›ก๏ธ

Service key stays server-side

The Supabase service role key never reaches the browser. Admin operations only run in server routes.

๐Ÿ‘ฅ

Admin user management API

GET, PATCH (role), and DELETE endpoints at /api/admin/users. Automatically protected โ€” only admins can call them.

๐Ÿ“ฆ

Auto-imported composables

useSupabaseClient, useSupabaseUser, useSupabaseSession, useSupabaseUserRole โ€” all available without imports.

Configuration

nuxt.config.ts
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@madebylars.com/mbl-auth'],

  mblAuth: {
    supabaseUrl: process.env.SUPABASE_URL,
    supabaseKey: process.env.SUPABASE_ANON_KEY,
    supabaseServiceKey: process.env.SUPABASE_SERVICE_KEY,
    roles: ['admin', 'user'],
    defaultRole: 'user',
    redirect: {
      login: '/login',
      callback: '/confirm',
      forbidden: '/forbidden',
    },
  },
})

Composables

pages/profile.vue
<script setup>
// Reactive user & session โ€” SSR safe
const user = useSupabaseUser()
const session = useSupabaseSession()
const { role, hasRole } = useSupabaseUserRole()

// Auth actions
const supabase = useSupabaseClient()
await supabase.auth.signInWithPassword({ email, password })
await supabase.auth.signOut()
</script>

<template>
  <div v-if="user">
    Hello {{ user.email }} โ€” role: {{ role }}
  </div>
</template>

Route middleware

pages/dashboard.vue
// Protect any page with a one-liner
definePageMeta({ middleware: 'auth' })

// Restrict to admins only
definePageMeta({ middleware: 'admin' })