Clerk Astro Patterns
ClerkOfficialCreated by clerk
- Skill
- Tool integration
- Software development
- MIT
- Low risk
- Has scripts
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides essential patterns for integrating Clerk authentication into Astro projects. It covers the configuration of middleware, handling authentication in server-side rendered (SSR) pages, managing Clerk components within React islands, and securing API routes. It clarifies the distinction between static and server-rendered pages, ensuring developers correctly implement auth checks and state management using the @clerk/astro SDK.
What it does
- Configures clerkMiddleware for request-level authentication handling.
- Demonstrates how to protect SSR pages using Astro.locals.auth().
- Provides patterns for using Clerk components in React islands with client:load.
- Explains how to secure API routes with proper status codes and auth checks.
- Outlines the correct import sources for components, stores, and server utilities.
- Addresses common pitfalls regarding rendering modes and middleware configuration.
When to use it
- When setting up Clerk authentication in a new or existing Astro project.
- When deciding between static and SSR rendering for protected routes.
- When implementing authentication checks within Astro API routes.
- When integrating Clerk React components into Astro islands.
- When troubleshooting authentication issues in production versus development environments.
Advantages
- Provides clear separation between SSR and static authentication patterns.
- Standardizes the use of Astro.locals.auth() for consistent auth checks.
- Includes specific guidance for React integration within Astro islands.
- Helps avoid common configuration errors related to Astro rendering modes.
Usage examples
- “How do I protect an SSR page in Astro using Clerk?”
- The agent will provide a code snippet showing how to use Astro.locals.auth() to check for a userId and redirect unauthenticated users to a sign-in page.
- “How do I secure an Astro API route with Clerk?”
- The agent will provide an example of an API route using context.locals.auth() to verify the user and return appropriate 401 or 403 HTTP status codes.
- “Why is my Clerk component not working in my Astro island?”
- The agent will explain the requirement for the client:load directive and verify that the component is imported from the correct @clerk/astro/react package.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/clerk/clerk-astro-patterns/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip clerk-astro-patterns.zip -d .agents/skills
Documentation by clerk
Astro Patterns
SDK: @clerk/astro v4+. Requires Astro 5+.
What Do You Need?
| Task | Reference |
|---|---|
Configure middleware (bare clerkMiddleware(), checks per page) | 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 middlewareStatic pages (
export const prerender = true) — Clerk middleware skips them; use client-side hooks in islandsIslands — React/Vue/Svelte components; use
useAuth()and other hooks from@clerk/astro/react
Request → clerkMiddleware() → SSR page → Astro.locals.auth()
↓
Island (.client) → useAuth() hookSetup
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 } from '@clerk/astro/server'
export const onRequest = clerkMiddleware()The middleware populates Astro.locals.auth(). Each page and API route checks for itself. createRouteMatcher was removed in @clerk/astro 4.0 (deprecated in 3.x). Don't add it. Existing uses must move to page and API-route checks before upgrading. See the Astro clerkMiddleware() reference.
SSR Page Auth
---
const { userId, orgId } = Astro.locals.auth()
if (!userId) return Astro.redirect('/sign-in')
---
<h1>Dashboard</h1>API Route Auth
// src/pages/api/data.ts
import type { APIRoute } from 'astro'
export const GET: APIRoute = ({ locals }) => {
const { userId } = locals.auth()
if (!userId) return new Response('Unauthorized', { status: 401 })
return Response.json({ userId })
}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, clerkClient | @clerk/astro/server |
useAuth, UserButton (no useUser) | @clerk/astro/react |
$userStore, $authStore | @clerk/astro/client |
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
Files
- ATTRIBUTION.mdAdded by AutoGineer854 B
- SKILL.md3.7 KiB
- evals/evals.json5.6 KiB
- references/api-routes.md2.0 KiB
- references/astro-react.md2.2 KiB
- references/island-components.md1.7 KiB
- references/middleware.md2.0 KiB
- references/ssr-pages.md1.8 KiB
- templates/astro-basic-auth/astro.config.mjsScript229 B
- templates/astro-basic-auth/package.json227 B
- templates/astro-basic-auth/src/layouts/Layout.astro522 B
- templates/astro-basic-auth/src/middleware.tsScript98 B
- templates/astro-basic-auth/src/pages/index.astro260 B
- templates/astro-basic-auth/src/pages/sign-in.astro135 B
- templates/astro-basic-auth/tsconfig.json42 B
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Declares allowed tools, Needs Node.js
Security
What our scanner noticed· Low risk
- Scripts that your agent may run
This skill includes scripts that your agent may run. Read them before you use it.
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- clerk
- Publisher
- Clerk (Official)
- Source
- clerk/skills · skills/clerk-astro-patterns · commit c5d2c0d
- Licence
- MIT License (redistribution allowed)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by clerk.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download clerk-astro-patterns.zip