Setting the file. One moment.
Chapter 12 · Clerk Astro Patterns
Subchapter 12.4
references/middleware.mdMarkdown2 KBView on GitHub
Also bundled
Evals// src/middleware.ts
import { clerkMiddleware, createRouteMatcher } from '@clerk/astro/server'
const isProtectedRoute = createRouteMatcher([
'/dashboard(.*)',
'/settings(.*)',
'/api/private(.*)',
])
export const onRequest = clerkMiddleware((auth, context, next) => {
if (isProtectedRoute(context.request) && !auth().userId) {
return auth().redirectToSignIn()
}
return next()
})export const onRequest = clerkMiddleware((auth, context, next) => {
const { userId, orgId } = auth()
if (isProtectedRoute(context.request)) {
if (!userId) return auth().redirectToSignIn()
if (!orgId) return context.redirect('/select-org')
}
return next()
})export const onRequest = clerkMiddleware()The middleware still populates Astro.locals.auth — you just do the redirect check per-page.
createRouteMatcher([
'/dashboard', // exact
'/dashboard(.*)', // prefix match
'/api/private/(.*)', // nested
/^\/admin/, // regex
])clerkMiddleware(handler?, options?)
// handler: (auth, context, next) => Response | Promise<Response>
// auth: () => AuthObject (call it to get { userId, orgId, ... })
// context: Astro APIContext
// next: () => Promise<Response>export const prerender = trueauth() is a function — call it to get the auth object: auth().userId not auth.userIdnext() for non-protected routes