Nuxt and Nitro 2
Register withBetterSupabase as Nitro 2 server middleware with the Nuxt module or toH3V1, and guard server routes.
Nuxt 3 and 4 serve through Nitro 2, which runs on H3 1. Its events wrap Node's
request and response instead of a Web Request, so it has its own bridge:
toH3V1(entries) from better-supabase/h3/v1. H3 2 apps use
better-supabase/h3.
The Nuxt module
Write the entries once in a server module:
import { createServer, withBetterSupabase } from "better-supabase/server";
import { betterSupabase } from "../lib/supabase";
export const bs = createServer(betterSupabase);
export default [
withBetterSupabase(bs, { refresh: true, allow: ["user", "anon"] }),
];Then add the module and point it at that file:
export default defineNuxtConfig({
modules: ["better-supabase/nuxt"],
betterSupabase: { server: "~~/server/better-supabase" },
});The module registers the entries as server middleware, so every server route
reads db, bs, auth and tenant from event.context, and auto-imports
the Vue composables in components. Set composables: false to skip them.
Without the module
Register the middleware yourself in Nitro 2:
import { toH3V1 } from "better-supabase/h3/v1";
import entries from "../better-supabase";
export default defineEventHandler(toH3V1(entries));Guards and errors
guard(options) returns the refusal for a caller the options refuse (Problem
Details, or a redirect to signIn or mfa), or undefined:
import { guard } from "better-supabase/h3/v1";
const admins = guard({ roles: ["admin"] });
export default defineEventHandler(
async (event) =>
(await admins(event)) ?? event.context.db.members.findMany().orThrow(),
);problemOnError() turns an error thrown by .orThrow() into a Problem Details
Response and returns undefined for every other error. On Nitro's
Cloudflare presets, event.context.cloudflare.env seeds getEnv.
The middleware runs before the route handler, so entries that read the final
response (withDbStats, withServerTiming) see an empty one under H3 1.
Last updated on