🔌 routeWrapper()
Wrap your Next.js App Router API Handlers (e.g., GET, POST) with automatic try-catch, standardized error responses, and optional authentication gating.
Setting Up Secure API Routes
If you need a traditional REST API endpoint to serve external systems or complex backend processes inside the /app/api/ layout, you can use routeWrapper() to guard against crashes and enforce that a request contains a valid Supabase Session.
// app/api/posts/route.ts
import { routeWrapper } from "next-supa-utils/server";
import { NextResponse } from "next/server";
export const POST = routeWrapper(
async (request, { supabase, user }) => {
const body = await request.json();
// Perform database insertions knowing 'user' is guaranteed
const { data, error } = await supabase
.from("posts")
.insert({ ...body, user_id: user.id })
.single();
if (error) throw error;
return NextResponse.json({ data });
},
{ requireAuth: true } // Auto-returns a 401 HTTP response if the caller is not logged in
);
API Reference
Signature:
function routeWrapper<TContext>(
handler: (request: NextRequest, context: RouteHandlerContext<TContext>) => Promise<NextResponse | Response>,
options?: RouteWrapperOptions
): (request: NextRequest, context: NextRouteContext) => Promise<NextResponse>
Context (RouteHandlerContext)
The second argument handed inside the callback (context) automatically provides:
params: Auto-resolved dynamic route params (e.g.,{ id: "123" }) from your folder structure.supabase: An initialized Supabase server client instance (always available).user: The authenticated user (guaranteed non-null ifrequireAuth: true).
Options (RouteWrapperOptions)
Configuring behavior is simple using the options object:
| Configuration | Type | Description |
|---|---|---|
requireAuth | boolean | If true, returns a JSON 401 Unauthorized response if the user has no valid session token in their headers/cookies. |
supabaseUrl | string | Explicit Supabase URL override. |
supabaseAnonKey | string | Explicit Supabase Anon Key override. |
[!tip] Throwing Standard Errors! You don't have to manually compose
NextResponse.json({ error }, { status: 500 })inside the body! Just throw an error or throw the Supabase error! The wrapper will pick it up and emit an isomorphic 500 automatically.