Skip to main content
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 custom 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:admin:example1' })) ||
    !has({ permission: 'org:admin:example2' })
  ) {
    // 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()
  }
})

The clerkMiddleware() function accepts an optional object. The following options are available:

  • Name
    audience?
    Type
    string | string[]
    Description

    A string or list of audiences. If passed, it is checked against the aud claim in the token.

  • Name
    authorizedParties?
    Type
    string[]
    Description

    An allowlist of origins to verify against, to protect your application from the subdomain cookie leaking attack.
    For example: ['http://localhost:3000', 'https://example.com']

  • Name
    clockSkewInMs?
    Type
    number
    Description

    Specifies the allowed time difference (in milliseconds) between the Clerk server (which generates the token) and the clock of the user's application server when validating a token. Defaults to 5000 ms (5 seconds).

  • Name
    domain?
    Type
    string
    Description

    The domain used for satellites to inform Clerk where this application is deployed.

  • Name
    isSatellite?
    Type
    boolean
    Description

    When using Clerk's satellite feature, this should be set to true for secondary domains.

  • Name
    jwtKey
    Type
    string
    Description

    Used to verify the session token in a networkless manner. Supply the PEM public key from the API keys page -> Show JWT public key -> PEM Public Key section in the Clerk Dashboard. It's recommended to use the environment variable instead. For more information, refer to Manual JWT verification.

  • Name
    organizationSyncOptions?
    Type
    OrganizationSyncOptions | undefined
    Description

    Used to activate a specific organization or personal account based on URL path parameters. If there's a mismatch between the active organization in the session (e.g., as reported by auth()) and the organization indicated by the URL, the middleware will attempt to activate the organization specified in the URL.

  • Name
    proxyUrl?
    Type
    string
    Description

    Specify the URL of the proxy, if using a proxy.

  • Name
    signInUrl
    Type
    string
    Description

    This URL will be used for any redirects that might happen and needs to point to your primary application on the client-side. This option is optional for production instances. It is required to be set for a satellite application in a development instance. It's recommended to use the environment variable instead.

  • Name
    signUpUrl
    Type
    string
    Description

    This URL will be used for any redirects that might happen and needs to point to your primary application on the client-side. This option is optional for production instances but must be set for a satellite application in a development instance. It's recommended to use the environment variable instead.

  • Name
    publishableKey
    Type
    string
    Description

    The Clerk Publishable Key for your instance. This can be found on the API keys page in the Clerk Dashboard.

  • Name
    secretKey?
    Type
    string
    Description

    The Clerk Secret Key for your instance. This can be found on the API keys page in the Clerk Dashboard. The CLERK_ENCRYPTION_KEY environment variable must be set when providing secretKey as an option, refer to Dynamic keys.

Feedback

What did you think of this content?

Last updated on