Astro Patterns
SkillDev tools'Astro patterns with Clerk — middleware, SSR pages, island components,
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Astro Patterns skill
What this skill tells your AI
The instructions your AI receives, as published by clerk/skills in skills/frameworks/clerk-astro-patterns/SKILL.md and read by ahel’s review.
SDK: @clerk/astro v3+. Requires Astro 4.15+.
What Do You Need?
| Task | Reference |
|---|---|
| Configure middleware | references/middleware.md |
| Protect SSR pages | references/ssr-pages.md |
| Use Clerk in island components | references/island-components.md |
| Auth in API routes | references/api-routes.md |
| Use Clerk with React in Astro | references/astro-react.md |
Mental Model
Astro has two rendering modes per page: SSR and static prerender. Clerk works differently in each:
- SSR pages — use
Astro.locals.auth()which is populated by the middleware - Static pages (
export const prerender = true) — Clerk middleware skips them; use client-side hooks in islands - Islands — React/Vue/Svelte components; use
useAuth()and other hooks from@clerk/astro/react
Request → clerkMiddleware() → SSR page → Astro.locals.auth()
↓
Island (.client) → useAuth() hook
Setup
astro.config.mjs
import { defineConfig } from 'astro/config'
import clerk from '@clerk/astro'
export default defineConfig({
integrations: [clerk()],
output: 'server',
})
src/middleware.ts
import { clerkMiddleware, createRouteMatcher } from '@clerk/astro/server'
const isProtectedRoute = createRouteMatcher(['/dashboard(.*)'])
export const onRequest = clerkMiddleware((auth, context, next) => {
if (isProtectedRoute(context.request) && !auth().userId) {
return auth().redirectToSignIn()
}
return next()
})
SSR Page Auth
---
const { userId, orgId } = Astro.locals.auth()
if (!userId) return Astro.redirect('/sign-in')
---
<h1>Dashboard</h1>
Common Pitfalls
| Symptom | Cause | Fix |
|---|---|---|
Astro.locals.auth is undefined | Missing middleware | Add clerkMiddleware to src/middleware.ts |
| Auth works in dev but not production | output: 'static' globally | Set output: 'server' or hybrid for protected pages |
| Static page has no auth | Prerendered pages skip middleware | Use export const prerender = false or move to island |
| Island not reactive to sign-in | Missing client:load directive | Add client:load to the island component |
Import Map
| What | Import From |
|---|---|
clerkMiddleware, createRouteMatcher | @clerk/astro/server |
useAuth, useUser, UserButton | @clerk/astro/react |
Astro components (<SignIn>, etc.) | @clerk/astro/components |
Env Variables
# .env
PUBLIC_CLERK_PUBLISHABLE_KEY=pk_...
CLERK_SECRET_KEY=sk_...
Astro uses PUBLIC_ prefix for client-exposed variables (not NEXT_PUBLIC_).
See Also
clerk-setup- Initial Clerk installclerk-custom-ui- Custom flows & appearanceclerk-orgs- B2B organizations
Docs
Signals
- GitHub stars
- 71
- Forks
- 4
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
clerk-astro-patterns- Source
- github.com/clerk/skills