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.
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:
- User authentication status -- user is signed in or out
- User authorization status -- user has the required role or permission
Protect routes based on user authentication status
To protect routes based on user authentication status, use  to check if isAuthenticated is true. If it's not, the user is not authenticated, and you can redirect them to the sign-in page.
import { clerkMiddleware, createRouteMatcher } from '@clerk/astro/server'
const isProtectedRoute = createRouteMatcher(['/dashboard(.*)', '/forum(.*)'])
export const onRequest = clerkMiddleware((auth, context) => {
  const { isAuthenticated, redirectToSignIn } = auth()
  if (!isAuthenticated && 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 to check if the user has the required roles or custom permissions.
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 { isAuthenticated, redirectToSignIn, userId } = auth()
  if (!isPublicRoute(context.request) && !isAuthenticated) {
    return redirectToSignIn()
  }
})clerkMiddleware() options
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 - audclaim 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 - truefor secondary domains.
 
- Name
- jwtKey
- Type
- string
- Description
- Used to verify the session token in a networkless manner. Supply the JWKS Public Key from the API keys page 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 in the session (e.g., as reported by ) 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
- The full URL or path to your sign-in page. Needs to point to your primary application on the client-side. Required for a satellite application in a development instance. It's recommended to use the environment variable instead. 
 
- Name
- signUpUrl
- Type
- string
- Description
- The full URL or path to your sign-up page. Needs to point to your primary application on the client-side. Required 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_KEYenvironment variable must be set when providing- secretKeyas an option, refer to Dynamic keys.
 
OrganizationSyncOptions
The organizationSyncOptions property on the clerkMiddleware() options
object has the type OrganizationSyncOptions, which has the following properties:
- Name
- organizationPatterns
- Type
- Pattern[]
- Description
- Specifies URL patterns that are organization-specific, containing an organization ID or slug as a path parameter. If a request matches this path, the organization identifier will be used to set that org as active. - If the route also matches the - personalAccountPatternsprop, this prop takes precedence.- Patterns must have a path parameter named either - :id(to match a Clerk organization ID) or- :slug(to match a Clerk organization slug).- Common examples: - ["/orgs/:slug", "/orgs/:slug/(.*)"]
- ["/orgs/:id", "/orgs/:id/(.*)"]
- ["/app/:any/orgs/:slug", "/app/:any/orgs/:slug/(.*)"]
 
 
- Name
- personalAccountPatterns
- Type
- Pattern[]
- Description
- URL patterns for resources that exist within the context of a user's personal account. - If the route also matches the - organizationPatternprop, the- organizationPatternprop takes precedence.- Common examples: - ["/me", "/me/(.*)"]
- ["/user/:any", "/user/:any/(.*)"]
 
 
Pattern
A Pattern is a string that represents the structure of a URL path. In addition to any valid URL, it may include:
- Named path parameters prefixed with a colon (e.g., :id,:slug,:any).
- Wildcard token, (.*), which matches the remainder of the path.
Examples
- /orgs/:slug
- /app/:any/orgs/:id
- /personal-account/(.*)
Feedback
Last updated on