One middleware rule protects the portal and ignores everything else
The entire authentication boundary for the site is nine lines of middleware. Clerk's createRouteMatcher takes one pattern — /portal(.*) — and returns a function that checks whether the current request URL matches. If it matches, auth.protect fires and redirects unauthenticated users to the sign-in page. If it does not match, the middleware does nothing and the request passes through untouched. Every service page, every checkout flow, every API route outside the portal, the homepage, the notes, the donate page — none of them hit the auth check. The matcher config at the bottom excludes static files and Next.js internals so the middleware only runs on actual page and API requests. Two regex patterns handle that — one for pages that are not static assets, one for API and tRPC routes. The whole file imports two functions from Clerk and exports one middleware function and one config object. No role checks at this layer. No redirect logic. No session inspection. The middleware answers one question — is this a portal route and is the user signed in. Role-based access happens deeper in the stack. The admin layout checks publicMetadata.role. The server actions check requireAdmin or auth individually. The middleware is the outer wall. Everything inside handles its own permissions. One pattern, one check, one redirect. The marketing site stays completely open. The portal stays completely locked.
Comments coming soon
Sign in with TikTok to leave a comment. Coming soon.