skilly. Buy ad slot
All skills
Astro · Security · Frontend / AGENT SKILL

clerk-astro-patterns

clerk/skills
12.8K installs 76 GitHub stars
0

Integrate Clerk authentication with Astro middleware, SSR pages, islands, and API routes.
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.

BEFORE YOU INSTALL

Understand the trade-offs.

Evidence to help you choose, prepare, and use this skill with confidence.

SECURITY REVIEW

Not yet assessed

Review the original instructions and requested permissions before installing.

No security review is available for this catalog entry yet.

SKILL QUALITY

Not yet assessed

How clearly the skill guides your agent, how complete its workflow is, and how you can check the outcome.

No quality assessment is available for this catalog entry yet.

The full skill.

Original instructions from the publisher’s SKILL.md

# Astro Patterns

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

```ts
import { defineConfig } from 'astro/config'
import clerk from '@clerk/astro'

export default defineConfig({
  integrations: [clerk()],
  output: 'server',
})
```

### src/middleware.ts

```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

```astro
---
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 install
- `clerk-custom-ui` - Custom flows & appearance
- `clerk-orgs` - B2B organizations

## Docs

[Astro SDK](https://clerk.com/docs/astro/getting-started/quickstart)

Skill folder

Files included alongside SKILL.md in the publisher’s repository.