Skills
Chapter 12 of 22
Astro patterns with Clerk — middleware, SSR pages, island components, API routes, static vs SSR rendering.
1 minute · 192 words · 12 sections
22 chapters · 80 min
| 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 |
Astro has two rendering modes per page: SSR and static prerender. Clerk works differently in each:
Astro.locals.auth() which is populated by the middlewareexport const prerender = true) — Clerk middleware skips them; use client-side hooks in islandsuseAuth() and other hooks from @clerk/astro/reactRequest → clerkMiddleware() → SSR page → Astro.locals.auth()
↓
Island (.client) → useAuth() hookimport { defineConfig } from 'astro/config'
import clerk from '@clerk/astro'
export default defineConfig({
integrations: [clerk()],
output: 'server',
})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()
})---
const { userId, orgId } = Astro.locals.auth()
if (!userId) return Astro.redirect('/sign-in')
---
<h1>Dashboard</h1>| 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 |
| What | Import From |
|---|---|
clerkMiddleware, createRouteMatcher | @clerk/astro/server |
useAuth, useUser, UserButton | @clerk/astro/react |
Astro components (<SignIn>, etc.) | @clerk/astro/components |
# .env
PUBLIC_CLERK_PUBLISHABLE_KEY=pk_...
CLERK_SECRET_KEY=sk_...Astro uses PUBLIC_ prefix for client-exposed variables (not NEXT_PUBLIC_).
clerk-setup - Initial Clerk installclerk-custom-ui - Custom flows & appearanceclerk-orgs - B2B organizationsInstall this repository
npx skills add clerk/skills/plugin marketplace add clerk/skillsSkills install per repository, not per chapter — the CLI has no documented per-skill form, so we do not print one.
Astro patterns with Clerk — middleware, SSR pages, island components, API routes, static vs SSR rendering. Triggers on: astro clerk, clerk astro middleware, astro protected page, clerk island component, astro API route auth, clerk astro SSR.
The verbatim description from this skill’s front matter — the string an agent matches on to decide whether to load it.
WebFetchskills/frameworks/clerk-astro-patterns/SKILL.mdmain, last pushed 6 August 2026.SKILL.md, not by matching a directory convention. 5 distinct layouts observed: .agents/skills/*/SKILL.md, skills/core/*/SKILL.md, skills/features/*/SKILL.md, skills/frameworks/*/SKILL.md, skills/mobile/*/SKILL.md.h1 and no skipped levels:.claude-plugin/marketplace.json by Clerk, declaring 4 plugins. It is read for editorial metadata only — never as the skill index, which is always the repository tree./clerk/skills.md, and each chapter at its own .md URL.12 files · 16 KB
Everything this skill ships beside its prose. All of it is set here, as subchapters of chapter 12.
Documentation the agent loads on demand, rather than up front.
Templates, schemas and fixtures the skill draws on.
Everything else published alongside the skill.