Next.js 15 Middleware & Route Guard Architect
AI assistants constantly mangle middleware matcher regexes, accidentally leaving sensitive API routes unprotected or running Edge middleware on every single image fetch. Generate a production-ready middleware.ts in seconds.
Select Auth Stack
The Webhook Matcher Disaster
If your middleware runs on Stripe or Resend webhooks and redirects unauthenticated requests to /login with an HTTP 307 redirect, Stripe will treat the response as a failed delivery and eventually disable your webhook endpoint in production.
Our generated middleware explicitly bypasses webhook paths so signatures remain intact.
import { createServerClient } from '@supabase/ssr';
import { NextResponse, type NextRequest } from 'next/server';
export async function middleware(request: NextRequest) {
let response = NextResponse.next({
request: {
headers: request.headers,
},
});
const pathname = request.nextUrl.pathname;
// 1. Always bypass webhooks (preserves raw signature buffer)
if (pathname.startsWith('/api/webhooks')) {
return response;
}
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return request.cookies.getAll();
},
setAll(cookiesToSet) {
cookiesToSet.forEach(({ name, value }) => request.cookies.set(name, value));
response = NextResponse.next({
request,
});
cookiesToSet.forEach(({ name, value, options }) =>
response.cookies.set(name, value, options)
);
},
},
}
);
// Refresh auth session
const { data: { user } } = await supabase.auth.getUser();
// 2. Protect authenticated paths
const isProtected = ["/dashboard","/settings","/api/user"].some((path) => pathname.startsWith(path));
if (isProtected && !user) {
const redirectUrl = request.nextUrl.clone();
redirectUrl.pathname = '/login';
redirectUrl.searchParams.set('redirect', pathname);
return NextResponse.redirect(redirectUrl);
}
// 3. Redirect logged-in users away from login/signup
const isAuthPage = pathname === '/login' || pathname === '/signup';
if (isAuthPage && user) {
const redirectUrl = request.nextUrl.clone();
redirectUrl.pathname = '/dashboard';
return NextResponse.redirect(redirectUrl);
}
return response;
}
export const config = {
matcher: [
/*
* Match all request paths except:
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
* - images, png, svg, webp, jpg
*/
'/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
],
};Middleware route coverage is Check 11 in our 108 launch criteria. The Founder Pass ($15 one-time) verifies that your private API handlers and Server Actions cannot be bypassed even if someone hits them directly.