UNPKG

create-perfect-template

Version:

Create a modern Next.js SaaS template with progressive feature activation

72 lines (59 loc) 2 kB
import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; import { config as appConfig } from '../config'; let clerkMiddleware: any; let createRouteMatcher: any; if (appConfig.auth.enabled) { const clerkImports = require('@clerk/nextjs/server'); clerkMiddleware = clerkImports.clerkMiddleware; createRouteMatcher = clerkImports.createRouteMatcher; } // Define routes based on enabled services const getPublicRoutes = () => { const routes = [ '/', '/features(.*)', '/api/webhooks(.*)', ]; if (appConfig.billing.enabled) { routes.push('/pricing(.*)'); routes.push('/api/autumn(.*)'); } if (appConfig.auth.enabled) { routes.push('/sign-in(.*)'); routes.push('/sign-up(.*)'); } return routes; }; const isPublicRoute = appConfig.auth.enabled ? createRouteMatcher(getPublicRoutes()) : () => true; export default function middleware(req: NextRequest) { const { pathname } = req.nextUrl; // Redirect pricing page if billing not enabled if (pathname.startsWith('/pricing') && !appConfig.billing.enabled) { return NextResponse.redirect(new URL('/', req.url)); } // Redirect auth pages if auth not enabled if ((pathname.startsWith('/sign-in') || pathname.startsWith('/sign-up')) && !appConfig.auth.enabled) { return NextResponse.redirect(new URL('/dashboard', req.url)); } // No auth required in core mode if (!appConfig.auth.enabled) { return NextResponse.next(); } // Use Clerk middleware for auth-enabled mode return clerkMiddleware(async (auth: any, req: NextRequest) => { if (!isPublicRoute(req)) { await auth.protect(); } })(req); } export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], };