Skip to main content

Astro Quickstart

Hand this prompt to your agent to add auth to your app with the Clerk CLI. No need to leave your terminal or copy and paste API keys.

Add Clerk to Astro
# Add Clerk Authentication

Use the Clerk CLI to add authentication. In agent environments, supported frameworks default to accountless setup: `npx -y clerk@latest init` provisions a claimable application and writes temporary development keys without requiring a Clerk account.

## Before you start

Show the user this checklist and wait for a yes:

```
Here's what I'll do to get you set up with Clerk.

1. Set up Clerk in this project, or scaffold a new app if this directory is empty
2. Start your app with Clerk installed.

Shall I proceed?
```

## Existing authentication

Before `init`, inspect auth dependencies, routes, middleware, sessions, and user records. If auth already exists, stop and propose a migration plan covering:

- User export/import through the Backend API with stable external IDs, compatible password hashes, and OAuth continuity.
- Protected routes, tokens, possible session termination at cutover, and a big-bang or gradual rollout.

Migration guide: https://clerk.com/docs/guides/development/migrating/overview

## Step 1a: Existing project

From the project root:

```bash
npx -y clerk@latest init
```

`init` detects the framework and package manager, installs the SDK, and applies framework setup — provider, middleware, auth routes, env. Do not pass `--framework` or `--pm` unless the user wants to override detection. Do not list apps or ask which Clerk app to use.

## Step 1b: Empty directory

Ask which framework and package manager to use, defaulting to Next.js and npm:

```bash
npx -y clerk@latest init --framework <framework> --pm <package-manager>
```

If a lockfile is present, let it pick the package manager: `pnpm-lock.yaml` -> `pnpm`, `yarn.lock` -> `yarn`, `bun.lock` or `bun.lockb` -> `bun`, `package-lock.json` -> `npm`.

## Step 1c: Accountless development keys

For a signed-out user on a supported framework, `init` provisions a claimable application and writes temporary keys to the detected environment file. Relay the filename and claim instruction printed by the CLI. The app stays unclaimed until the user runs `npx -y clerk@latest auth login`; don't run it unless asked. Use `--accountless` only to force this flow while signed in.

Frameworks without accountless support need real API keys. There, `init` applies what setup it can and prints the remaining steps.

To link an existing Clerk application, add `--app <application_id>` — but only when the user supplies the ID. If they want to link and have no ID, run `npx -y clerk@latest apps list --json`, show the names and IDs, and ask. Never choose an application for them.

## Step 2: Fall back to docs when init is incomplete

If `init` reports the framework is unsupported or undetected, follow the quickstart instead.

`init` scaffolds Next.js, React, React Router, Nuxt, TanStack Start, Astro, Vue, JavaScript/Vite, Expo, Express, Fastify, iOS, and Android.

Use `https://clerk.com/docs/<slug>/getting-started/quickstart.md?manual=1`. Keep the init ID for `astro`, `nuxt`, `react-router`, `react`, `vue`, `fastify`, `expo`, `ios`, and `android`. Map `next` -> `nextjs`, `@tanstack/react-start` -> `tanstack-react-start`, `vite` or vanilla JS -> `js-frontend`, and `express` -> `expressjs`. Chrome extensions use `chrome-extension`.

Everything else: https://clerk.com/docs/llms.txt

## Step 3: Add visible auth controls

The app needs sign-in, sign-up, and signed-in user controls, worked into the existing layout or navigation. If they already exist, adapt them instead of duplicating.

For Next.js App Router:

```text
import { SignInButton, SignUpButton, Show, UserButton } from '@clerk/nextjs'

<>
  <Show when="signed-out">
    <SignInButton />
    <SignUpButton />
  </Show>
  <Show when="signed-in">
    <UserButton />
  </Show>
</>
```

Astro imports from `@clerk/astro/components`. Nuxt auto-imports the components; explicit imports come from `@clerk/nuxt/components`. Other frameworks use the same names from their Clerk package, such as `@clerk/vue` or `@clerk/react`.

## Step 4: Verify

```bash
npx -y clerk@latest doctor
```

Then start the app, confirm the auth controls render, and fix anything the CLI reports.

## Step 5: If using shadcn/ui

If `components.json` exists in the project root, add `@clerk/ui` with the package manager from Step 1 — `npm install`, `pnpm add`, `yarn add`, or `bun add`.

Apply the theme in your provider:

```text
import { shadcn } from '@clerk/ui/themes'

<ClerkProvider appearance={{ theme: shadcn }}>{children}</ClerkProvider>
```

Add to global CSS:

```css
@import '@clerk/ui/themes/shadcn.css';
```

## Critical rules

- Use Node.js 20.9.0 or later.
- Next.js 15+: `auth()` is async. Always `await auth()`
- `ClerkProvider` goes inside `<body>`, not wrapping `<html>`
- Never expose `CLERK_SECRET_KEY` in client code
- Use the current framework package, such as `@clerk/nextjs`, `@clerk/react`, `@clerk/expo`, `@clerk/react-router`, or `@clerk/tanstack-react-start`; never legacy Core 2 names such as `@clerk/clerk-react` or `@clerk/clerk-expo`.
- Do not read or print existing environment variable files; ask the user for any missing non-sensitive configuration

Docs: https://clerk.com/docs/cli https://clerk.com/docs/llms.txt

## After setup

Have the user sign up as their first test user. Congratulate them once the profile icon appears in the nav.

Before production, have the user claim the app with `npx -y clerk@latest auth login`, then configure production with `npx -y clerk@latest deploy`. Unclaimed apps and temporary keys aren't production-ready.

Then offer Organizations — multi-tenancy, team invitations, roles and permissions, and enterprise SSO.

If yes:

1. Run `npx -y clerk@latest enable orgs`.
2. Add `<OrganizationSwitcher />` next to the existing `<UserButton />`, or the framework equivalent.
3. Have them create an organization from the switcher and invite a teammate.

If no, point them to Organizations (https://clerk.com/docs/guides/organizations/overview), Components (https://clerk.com/docs/reference/components/overview), and the Dashboard (https://dashboard.clerk.com/).

Or set up Clerk yourself by following the step-by-step instructions.

Step-by-step setup instructions

Create a new Astro app

If you don't already have an Astro app, run the following commands to create a new one.

npm create astro@latest clerk-astro
cd clerk-astro
pnpm create astro clerk-astro
cd clerk-astro
yarn create astro clerk-astro
cd clerk-astro
bunx create-astro clerk-astro
cd clerk-astro

Install @clerk/astro

The Clerk Astro SDKAstro Icon gives you access to a set of components, hooks, and stores to make user authentication easier.

Run the following command to install the SDK and the @astrojs/node adapter, which this quickstart uses:

npm install @astrojs/node @clerk/astro
pnpm add @astrojs/node @clerk/astro
yarn add @astrojs/node @clerk/astro
bun add @astrojs/node @clerk/astro

If you're adding Clerk to an existing app, keep your Astro version and adapter — the SDK supports Astro 5, 6, and 7. If you need an adapter, install the @astrojs/node major that matches your Astro version (v11 for Astro 7, v10 for Astro 6, v9 for Astro 5). If npm reports a peer conflict, update Astro to its latest minor first — the newest adapter releases require recent Astro minors. If you're on Astro 4, upgrade to Astro 5 or later first — the SDK no longer supports it.

Set your Clerk API keys

.env
PUBLIC_CLERK_PUBLISHABLE_KEY=YOUR_PUBLISHABLE_KEY
CLERK_SECRET_KEY=YOUR_SECRET_KEY

Update astro.config.mjs

To configure Clerk in your Astro app, you will need to update your astro.config.mjs.

astro.config.mjs
import { defineConfig } from 'astro/config'
import node from '@astrojs/node'
import clerk from '@clerk/astro'

export default defineConfig({
  integrations: [clerk()],
  adapter: node({ mode: 'standalone' }),
  output: 'server',
})

Add clerkMiddleware() to your app

clerkMiddleware()Astro Icon grants you access to user authentication state throughout your app. To add clerkMiddleware() to your app, follow these steps:

  1. Create a middleware.ts file.
    • If you're using the /src directory, create middleware.ts in the /src directory.
    • If you're not using the /src directory, create middleware.ts in the root directory.
  2. In your middleware.ts file, export an onRequest constant and assign the result of the clerkMiddleware() function to it.
    src/middleware.ts
    import { clerkMiddleware } from '@clerk/astro/server'
    
    export const onRequest = clerkMiddleware()
  3. By default, clerkMiddleware() will not protect any routes. All routes are public and you must opt-in to protection. To require a signed-in user, protect resources close to where they're used, as shown in the guide on reading user data.

Create a header with Clerk components

You can control which content signed-in and signed-out users can see with Clerk's prebuilt control components. The following example creates a header using the following components:

src/layouts/Layout.astro
---
import { Show, UserButton, SignInButton, SignUpButton } from '@clerk/astro/components'

const { title } = Astro.props
---

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="generator" content={Astro.generator} />
    <title>{title}</title>
  </head>
  <body>
    <header>
      <Show when="signed-out">
        <SignInButton mode="modal" />
        <SignUpButton mode="modal" />
      </Show>
      <Show when="signed-in">
        <UserButton />
      </Show>
    </header>
    <slot />
  </body>
</html>

<style>
  html,
  body {
    margin: 0;
    width: 100%;
    height: 100%;
  }
</style>

Then, use the layout on your homepage:

src/pages/index.astro
---
import Layout from '../layouts/Layout.astro'
import { Show } from '@clerk/astro/components'
---

<Layout title="Clerk + Astro">
  <Show when="signed-out">
    <p>Sign in to try Clerk out!</p>
  </Show>
  <Show when="signed-in">
    <p>You are signed in!</p>
  </Show>
</Layout>

Run your project

Run your project with the following command:

npm run dev
pnpm run dev
yarn dev
bun run dev

Create your first user

  1. Visit your app's homepage at http://localhost:4321.
  2. Select "Sign up" on the page and authenticate to create your first user.

Next steps

Explore the most relevant next steps for your SDK using the following guides.

Prebuilt components

Learn how to add Clerk's prebuilt authentication and user-management UI to your app.

Build custom flows

Learn how to build custom user interfaces entirely from scratch using the Clerk API.

Read user data

Learn how to use Clerk's helpers to read user data in your app.

Configure clerkMiddleware()

Learn how to integrate Clerk authentication into your Astro app through middleware.

More to explore

Explore additional Clerk features that help you build, manage, and grow your application.

  • Organizations - Organizations are shared accounts that let teams collaborate, manage members and roles, and control access to shared resources.
  • Billing - Billing enables you to manage subscriptions, free trials, payments, plans, and billing-related webhook events for B2C and B2B applications.
  • Waitlist - Waitlist lets you collect signups and control access to new products or features before launch through a simple, integrated workflow.

Feedback

What did you think of this content?

Last updated on