Diese Anleitung führt dich durch die Einrichtung der Clerk-Authentifizierung in deinem Kit-Projekt. Am Ende hast du funktionierende Anmeldung, Registrierung, Social Login und automatische Datenbanksynchronisierung.
Du kannst diese Seite überspringen und
pnpm dev:no-clerk ausführen, um ohne Clerk zu entwickeln. Kit bietet ein Mock-Authentifizierungssystem, mit dem du sofort das vollständige Dashboard erkunden kannst. Komm hierher zurück, wenn du bereit bist, echte Authentifizierung anzubinden.Clerk-Konto erstellen
1
Bei Clerk registrieren
Gehe zu clerk.com und erstelle ein kostenloses Konto. Clerks Free-Tier ist großzügig – er umfasst bis zu 10.000 monatlich aktive Benutzer.
2
Eine Anwendung erstellen
Klicke im Clerk-Dashboard auf Create application. Wähle einen Namen für deine App (z. B. „My SaaS") und wähle, welche Anmeldemethoden du aktivieren möchtest. Du kannst diese später ändern.
Aktiviere mindestens Email address als Identifier. Du kannst auch direkt Google- und GitHub-Social-Logins aktivieren – siehe dazu den Abschnitt Social-Login-Anbieter weiter unten.
3
Umgebung beachten
Clerk erstellt standardmäßig eine Development-Instanz. Diese ist ideal für die lokale Entwicklung. Wenn du live gehst, erstellst du eine separate Production-Instanz im Clerk-Dashboard.
API-Keys abrufen
Nach der Erstellung deiner Anwendung zeigt Clerk zwei API-Keys:
- Publishable Key (
pk_test_...) — Sicher im Browser exponierbar. Wird von ClerkProvider zur SDK-Initialisierung verwendet. - Secret Key (
sk_test_...) — Nur für den Server. Wird zur Webhook-Verifizierung und serverseitigen API-Aufrufen verwendet. Niemals im Client-Code exponieren.
Du findest diese jederzeit im Clerk-Dashboard unter API Keys.
Committe
CLERK_SECRET_KEY niemals in die Versionskontrolle. Er sollte nur in apps/boilerplate/.env.local (die gitignored ist) und in den Umgebungsvariablen deiner Hosting-Plattform (z. B. Vercel-Dashboard) existieren.Umgebungsvariablen konfigurieren
Füge deine Clerk-Keys zu
apps/boilerplate/.env.local hinzu. Kit verwendet 8 Clerk-bezogene Umgebungsvariablen:.env.example
# IMPORTANT: Replace these empty keys with your actual Clerk keys!
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=
CLERK_SECRET_KEY=
CLERK_WEBHOOK_SECRET=
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/login
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/register
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/dashboard
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/dashboard
Das macht jede Variable:
| Variable | Erforderlich | Zweck |
|---|---|---|
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY | Ja | Initialisiert das Clerk-SDK im Browser |
CLERK_SECRET_KEY | Ja | Serverseitige Operationen und Webhook-Verifizierung |
CLERK_WEBHOOK_SECRET | Ja | Verifiziert Webhook-Signaturen (siehe Webhook-Setup) |
NEXT_PUBLIC_CLERK_SIGN_IN_URL | Nein | Pfad zur Anmeldeseite. Standard: /login |
NEXT_PUBLIC_CLERK_SIGN_UP_URL | Nein | Pfad zur Registrierungsseite. Standard: /register |
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL | Nein | Weiterleitung nach Anmeldung. Standard: /dashboard |
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL | Nein | Weiterleitung nach Registrierung. Standard: /dashboard |
Die URL-Variablen haben bereits sinnvolle Standardwerte in Kit. In der Regel musst du nur die drei Key-Variablen setzen:
bash
# apps/boilerplate/.env.local
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_your_key_here
CLERK_SECRET_KEY=sk_test_your_key_here
CLERK_WEBHOOK_SECRET=whsec_your_secret_here
ClerkProvider im Root-Layout
Kits Root-Layout enthält bereits den
ClerkProvider. Du musst ihn nicht selbst hinzufügen – er ist vorkonfiguriert und umgebungsbewusst.Der Provider verwendet das
dynamic-Prop, das für Next.js 14 mit Streaming entscheidend ist:typescript
<ClerkProvider
dynamic
appearance={{
elements: {
formButtonPrimary: 'bg-primary hover:bg-primary/90',
footerActionLink: 'text-primary hover:text-primary/90',
},
}}
>
{content}
</ClerkProvider>
Ohne
dynamic bäckt Clerk den Sitzungstoken in das server-gerenderte HTML ein. Wenn Next.js die Seite streamt, kann der Client einen veralteten Token empfangen, was zu einem Hydration-Mismatch führt. Das dynamic-Prop weist Clerk an, den Sitzungstoken stattdessen auf dem Client zu lesen – der Mismatch wird dadurch vollständig vermieden.Das
appearance-Objekt passt Clerks vorgefertigte Komponenten (Anmeldeformular, User-Button) an die Primärfarbe deiner App an. Da Kit CSS Custom Properties für das Theming verwendet, passt sich die bg-primary-Klasse automatisch an das gewählte Farbthema an.Social-Login-Anbieter {#social-login-providers}
Clerk macht es einfach, Social Logins hinzuzufügen. Kits Auth-Formulare zeigen Social-Login-Buttons automatisch an, wenn du Anbieter im Clerk-Dashboard aktivierst.
1
OAuth-Credentials erstellen
Gehe zur Google Cloud Console, erstelle eine neue OAuth 2.0-Client-ID und setze die autorisierte Weiterleitungs-URI auf den von Clerk im Dashboard angegebenen Wert.
2
In Clerk aktivieren
Gehe im Clerk-Dashboard zu User & Authentication > Social connections, aktiviere Google und füge deine Client-ID und dein Client-Secret ein.
3
Testen
Starte deinen Dev-Server neu. Die Anmelde- und Registrierungsformulare zeigen jetzt einen „Continue with Google"-Button.
GitHub
1
Eine OAuth-App erstellen
Gehe zu GitHub Developer Settings, erstelle eine neue OAuth-App und setze die Callback-URL auf den von Clerk angegebenen Wert.
2
In Clerk aktivieren
Aktiviere im Clerk-Dashboard GitHub unter Social connections und füge deine Client-ID und dein Client-Secret ein.
3
Testen
Starte deinen Dev-Server neu. Die Auth-Formulare enthalten jetzt einen „Continue with GitHub"-Button neben allen anderen aktivierten Anbietern.
Clerk unterstützt über 20 Social-Anbieter, darunter Apple, Microsoft, Discord und viele mehr. Jeder folgt demselben Muster: OAuth-Credentials beim Anbieter erstellen, dann in Clerk aktivieren und konfigurieren. Die vollständige Liste findest du in der Clerk Social Connections-Dokumentation.
Multi-Faktor-Authentifizierung
Um MFA für deine Benutzer zu aktivieren:
- Gehe im Clerk-Dashboard zu User & Authentication > Multi-factor.
- Aktiviere Authenticator app (TOTP) und/oder SMS verification.
- Benutzer können dann MFA in ihren Profileinstellungen aktivieren.
Kit erfordert keine Code-Änderungen – Clerk übernimmt den gesamten MFA-Flow einschließlich Einrichtung, Verifizierung und Backup-Codes.
Webhook-Setup
Über Webhooks benachrichtigt Clerk deine Anwendung über Benutzerereignisse. Das ist entscheidend, um die Datenbank synchron zu halten – ohne Webhooks würden neue Benutzer ein Clerk-Konto, aber keinen Datenbankdatensatz haben.
Den Webhook-Endpunkt erstellen
1
Clerk-Webhooks öffnen
Gehe im Clerk-Dashboard zu Webhooks und klicke auf Add Endpoint.
2
Endpunkt-URL setzen
Für die lokale Entwicklung verwende einen Tunneldienst wie ngrok oder localtunnel:
bash
# Start your tunnel
ngrok http 3000
# Use the tunnel URL as your webhook endpoint:
# https://your-id.ngrok-free.app/api/webhooks/clerk
Für die Produktion verwende deine echte Domain:
https://yourdomain.com/api/webhooks/clerk
3
Events auswählen
Abonniere diese Events:
user.createduser.updateduser.deleted
4
Signing Secret kopieren
Nach der Endpunkt-Erstellung zeigt Clerk ein Signing Secret (beginnt mit
whsec_). Kopiere es und füge es zu deiner apps/boilerplate/.env.local hinzu:bash
CLERK_WEBHOOK_SECRET=whsec_your_signing_secret_here
Der Webhook-Handler
Kit enthält einen vorgefertigten Webhook-Handler unter
/api/webhooks/clerk. Er empfängt Clerk-Events, verifiziert ihre Echtheit und aktualisiert deine Datenbank. Hier ist die Signaturverifizierungslogik:src/app/api/webhooks/clerk/route.ts
export const POST = withRateLimit('webhooks', async (request: NextRequest) => {
try {
// Get the headers
const headerPayload = await headers()
const svix_id = headerPayload.get('svix-id')
const svix_timestamp = headerPayload.get('svix-timestamp')
const svix_signature = headerPayload.get('svix-signature')
// If there are no headers, error out
if (!svix_id || !svix_timestamp || !svix_signature) {
return new NextResponse('Error occured -- no svix headers', {
status: 400,
})
}
// Get the body
const payload = await request.json()
const body = JSON.stringify(payload)
// Create a new SVIX instance with your webhook secret
const wh = new Webhook(process.env.CLERK_WEBHOOK_SECRET || '')
let evt: WebhookEvent
// Verify the payload with the headers
try {
evt = wh.verify(body, {
'svix-id': svix_id,
'svix-timestamp': svix_timestamp,
'svix-signature': svix_signature,
}) as WebhookEvent
} catch (err) {
console.error('Error verifying webhook:', err)
return new NextResponse('Error occured', {
status: 400,
})
}
Der Handler ist mit
withRateLimit('webhooks', ...) umschlossen, um Missbrauch zu verhindern, und verwendet die Svix-Bibliothek, um sicherzustellen, dass jede Anfrage tatsächlich von Clerk stammt.SVIX-Signaturverifizierung
Jede Clerk-Webhook-Anfrage enthält drei Header:
| Header | Zweck |
|---|---|
svix-id | Eindeutiger Nachrichtenidentifikator (für Deduplizierung) |
svix-timestamp | Zeitpunkt des Versands (verhindert Replay-Angriffe) |
svix-signature | HMAC-Signatur, berechnet mit deinem Webhook-Secret |
Der Handler verifiziert diese gegen den Request-Body mit deinem
CLERK_WEBHOOK_SECRET. Schlägt die Verifizierung fehl, wird die Anfrage mit Status 400 abgelehnt.Behandelte Events
Wenn sich ein neuer Benutzer registriert, initialisiert das
user.created-Event seinen Datenbankdatensatz mit einem Free-Tier:src/app/api/webhooks/clerk/route.ts
if (eventType === 'user.created') {
const { id, email_addresses, first_name, last_name } = evt.data
const email = email_addresses[0]?.email_address
const name = [first_name, last_name].filter(Boolean).join(' ') || null
// Initialize Free Tier credits
const freeCredits = parseInt(
process.env.NEXT_PUBLIC_CREDIT_FREE_TIER_CREDITS || '20'
)
const resetDate = new Date()
resetDate.setDate(resetDate.getDate() + 30) // 30 days from now
// Create user in database with Free Tier
await prisma.user.upsert({
where: { clerkId: id },
update: {
email,
name,
},
create: {
clerkId: id,
email,
name,
// Free Tier initialization
tier: 'free',
creditBalance: freeCredits,
creditsPerMonth: freeCredits,
creditsResetAt: resetDate,
bonusCredits: 0,
},
})
console.log(`User ${id} created with Free Tier (${freeCredits} credits)`)
}
Wichtige Details:
- Upsert-Operation — Verwendet
prisma.user.upsertstattcreatefür Idempotenz. Wiederholt Clerk den Webhook, werden keine Duplikate erzeugt. - Free-Tier-Credits — Neue Benutzer erhalten Credits gemäß
NEXT_PUBLIC_CREDIT_FREE_TIER_CREDITS(Standard: 500). - 30-Tage-Reset — Das Guthaben wird 30 Tage nach Kontoerstellung zurückgesetzt.
- 200 zurückgeben — Gibt immer Status 200 zurück, um den Empfang zu bestätigen. Fehler zurückzugeben lässt Clerk den Webhook erneut senden, was zu Verarbeitungs-Stürmen führen kann.
Das
user.updated-Event synchronisiert E-Mail- und Namensänderungen, und user.deleted entfernt den Datensatz aus der Datenbank.Entwicklung ohne Clerk
Wenn du Clerk noch nicht eingerichtet hast oder Features ohne Authentifizierungs-Overhead entwickeln möchtest, bietet Kit einen No-Auth-Entwicklungsmodus:
bash
pnpm dev:no-clerk
Das setzt
NEXT_PUBLIC_CLERK_ENABLED=false, was das Mock-Authentifizierungssystem aktiviert:- Ein Test-Benutzer ist automatisch angemeldet (
free@test.example.com) - Alle Dashboard-Routen sind ohne Login zugänglich
- Das Clerk-SDK wird nicht geladen (schnellerer Start, keine API-Aufrufe)
- Auth-Hooks geben Mock-Daten mit identischen Interfaces zurück
Der Test-Benutzer stimmt mit den Datenbank-Seed-Daten überein, sodass alle Features (Credits, Billing, AI-Chat) wie erwartet funktionieren.
Der Demo-Modus (
NEXT_PUBLIC_DEMO_MODE=true) ist ähnlich, aber für öffentliche Deployments konzipiert. Er zeigt ein benutzerdefiniertes Login-Formular mit Tier-Wechsel-Buttons, sodass Besucher verschiedene Abonnementstufen erkunden können.