Docs

clerkMiddleware() | Astro

The clerkMiddleware() helper integrates Clerk authentication into your Astro application through middleware.

Configure clerkMiddleware()

Create a middleware.ts file inside your src/ directory.

src/middleware.ts
import { clerkMiddleware } from '@clerk/astro/server'

export const onRequest = clerkMiddleware()

createRouteMatcher()

createRouteMatcher() is a Clerk helper function that allows you to protect multiple routes. createRouteMatcher() accepts an array of routes and checks if the route the user is trying to visit matches one of the routes passed to it.

The createRouteMatcher() helper returns a function that, if called with the context.request object from the Middleware, will return true if the user is trying to access a route that matches one of the routes passed to createRouteMatcher().

In the following example, createRouteMatcher() sets all /dashboard and /forum routes as protected routes.

const isProtectedRoute = createRouteMatcher(['/dashboard(.*)', '/forum(.*)'])

Protect routes

You can protect routes by checking either or both of the following:

Protect routes based on user authentication status

To protect routes based on user authentication status, use auth().userId to check if the userId is present. If it is not, the user is not authenticated, and you can redirect them to the sign-in page.

src/middleware.ts
import { clerkMiddleware, createRouteMatcher } from '@clerk/astro/server'

const isProtectedRoute = createRouteMatcher(['/dashboard(.*)', '/forum(.*)'])

export const onRequest = clerkMiddleware((auth, context) => {
  const { redirectToSignIn, userId } = auth()

  if (!userId && isProtectedRoute(context.request)) {
    // Add custom logic to run before redirecting

    return redirectToSignIn()
  }
})

Protect routes based on user authorization status

To protect routes based on user authorization status, use auth().has() to check if the user has the required roles or permissions.

src/middleware.ts
import { clerkMiddleware, createRouteMatcher } from '@clerk/astro/server'

const isProtectedRoute = createRouteMatcher(['/admin(.*)'])

export const onRequest = clerkMiddleware((auth, context) => {
  const { has, redirectToSignIn } = auth()

  // Restrict admin routes to users with specific permissions
  if (
    (isProtectedRoute(context.request) && !has({ permission: 'org:sys_memberships:manage' })) ||
    !has({ permission: 'org:sys_domains_manage' })
  ) {
    // Add logic to run if the user does not have the required permissions; for example, redirecting to the sign-in page
    return redirectToSignIn()
  }
})

Protect all routes

To protect all routes in your application and define specific routes as public, you can use any of the above methods and simply invert the if condition.

import { clerkMiddleware, createRouteMatcher } from '@clerk/astro/server'

const isPublicRoute = createRouteMatcher(['/sign-in(.*)', '/sign-up(.*)'])

export const onRequest = clerkMiddleware((auth, context) => {
  const { redirectToSignIn, userId } = auth()

  if (!isPublicRoute(context.request) && !userId) {
    return redirectToSignIn()
  }
})

clerkMiddleware() options

The clerkMiddleware() function accepts an optional object. See the full list of options available here

Feedback

What did you think of this content?

Last updated on