Clerk to nowoczesna platforma do autentykacji i zarządzania użytkownikami, zaprojektowana specjalnie dla aplikacji React i Next.js. W przeciwieństwie do tradycyjnych rozwiązań jak Auth0 czy Firebase Auth, Clerk oferuje gotowe, w pełni konfigurowalne komponenty UI, zaawansowane zarządzanie sesjami i organizacjami, oraz głęboką integrację z ekosystemem React.
🎯 Czego się nauczysz:
- Konfiguracja Clerk w projekcie Next.js
- Gotowe komponenty UI (SignIn, SignUp, UserButton)
- Ochrona tras i middleware
- Zarządzanie użytkownikami i sesjami
- Organizacje i role użytkowników
- Webhooks i zdarzenia
- Custom flow i rozszerzenia
- Best practices bezpieczeństwa
TL;DR — Szybkie podsumowanie
| Funkcja | Clerk | Auth0 | Firebase Auth |
|---|---|---|---|
| Gotowe komponenty UI | ✅ Tak | ❌ Nie | ❌ Nie |
| Next.js App Router | ✅ Full | ⚠️ Partial | ⚠️ Partial |
| Organizacje/B2B | ✅ Built-in | 💰 Dodatkowo | ❌ Nie |
| Cena (start) | Darmowy | Darmowy | Darmowy |
🔐 Czym jest Clerk?
Clerk to kompletna platforma identity, która eliminuje potrzebę budowania własnego systemu autentykacji. Oferuje nie tylko logowanie i rejestrację, ale także zaawansowane funkcje zarządzania użytkownikami, organizacjami, uprawnieniami i bezpieczeństwem.
Kluczowe cechy
- Gotowe komponenty UI – prebuilt, w pełni konfigurowalne komponenty React
- Wieloczynnikowa autentykacja – MFA z TOTP, SMS, email codes, passkeys
- Organizacje i B2B – zarządzanie organizacjami, rolami, zaproszeniami
- Edge-ready – middleware Next.js, obsługa Edge Runtime
⚙️ Instalacja i konfiguracja
1. Utworzenie aplikacji w Clerk Dashboard
Utwórz konto na clerk.com i dodaj nową aplikację. Pobierz klucze API:
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY– klucz publicznyCLERK_SECRET_KEY– klucz prywatny
2. Instalacja SDK
# Dla Next.js
npm install @clerk/nextjs
# Dla React (Vite, CRA)
npm install @clerk/clerk-react
# Dla Express.js backendu
npm install @clerk/express
3. Konfiguracja środowiska
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...
# Opcjonalne – custom redirect URLs
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/dashboard
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/onboarding
4. Inicjalizacja w aplikacji
import { ClerkProvider } from '@clerk/nextjs'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<ClerkProvider>
<html lang="pl">
<body>{children}</body>
</html>
</ClerkProvider>
)
}
🎨 Podstawowe komponenty
SignIn i SignUp
import { SignIn } from '@clerk/nextjs'
export default function SignInPage() {
return (
<div className="flex justify-center items-center min-h-screen">
<SignIn
appearance={{
elements: {
formButtonPrimary: 'bg-blue-600 hover:bg-blue-700',
card: 'shadow-xl'
}
}}
/>
</div>
)
}
UserButton – menu użytkownika
import { UserButton, SignedIn, SignedOut, SignInButton } from '@clerk/nextjs'
export function Header() {
return (
<header className="flex justify-between items-center p-4 border-b">
<h1>Moja Aplikacja</h1>
<div>
<SignedIn>
<UserButton afterSignOutUrl="/" />
</SignedIn>
<SignedOut>
<SignInButton mode="modal">
<button className="bg-blue-600 text-white px-4 py-2 rounded">
Zaloguj się
</button>
</SignInButton>
</SignedOut>
</div>
</header>
)
}
🛡️ Ochrona tras – Middleware
Clerk oferuje potężny middleware do ochrony tras w Next.js:
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server'
const isProtectedRoute = createRouteMatcher([
'/dashboard(.*)',
'/settings(.*)',
'/api/protected(.*)'
])
const isAdminRoute = createRouteMatcher([
'/admin(.*)'
])
export default clerkMiddleware(async (auth, req) => {
// Ochrona zalogowanych tras
if (isProtectedRoute(req)) {
await auth().protect()
}
// Ochrona tras admina
if (isAdminRoute(req)) {
await auth().protect({ role: 'org:admin' })
}
})
export const config = {
matcher: [
'/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)',
'/(api|trpc)(.*)',
],
}
👤 Dostęp do danych użytkownika
W komponentach serwerowych
import { auth, currentUser } from '@clerk/nextjs/server'
export default async function DashboardPage() {
const { userId, sessionClaims } = await auth()
const user = await currentUser()
if (!userId) {
return <div>Brak dostępu</div>
}
return (
<div>
<h1>Witaj, {user?.firstName}!</h1>
<p>Email: {user?.emailAddresses[0].emailAddress}</p>
<p>Rola: {sessionClaims?.metadata?.role}</p>
</div>
)
}
W komponentach klientowych
'use client'
import { useUser, useAuth } from '@clerk/nextjs'
export function UserInfo() {
const { user, isLoaded } = useUser()
const { userId } = useAuth()
if (!isLoaded) {
return <div>Ładowanie...</div>
}
return (
<div>
<img src={user?.imageUrl} alt="Avatar" className="w-16 h-16 rounded-full" />
<p>{user?.fullName}</p>
<p>ID: {userId}</p>
</div>
)
}
🏢 Organizacje (B2B)
Clerk oferuje zaawansowane zarządzanie organizacjami – idealne dla aplikacji B2B:
import { OrganizationList, CreateOrganization } from '@clerk/nextjs'
export default function OrganizationSelectorPage() {
return (
<div className="container mx-auto py-8">
<h2 className="text-2xl font-bold mb-4">Wybierz organizację</h2>
<OrganizationList
afterSelectOrganizationUrl="/dashboard"
/>
<div className="mt-8">
<h3 className="text-xl font-semibold mb-4">Utwórz nową</h3>
<CreateOrganization afterCreateOrganizationUrl="/dashboard" />
</div>
</div>
)
}
Sprawdzenie roli w organizacji
import { auth } from '@clerk/nextjs/server'
export default async function AdminPage() {
const { orgRole, orgId } = await auth()
if (orgRole !== 'org:admin') {
return <div>Brak uprawnień</div>
}
return <div>Panel administratora organizacji {orgId}</div>
}
🔌 Webhooks – zdarzenia
Clerk wysyła webhooki dla kluczowych zdarzeń – rejestracji, logowania, aktualizacji profilu:
import { Webhook } from 'svix'
import { headers } from 'next/headers'
import { WebhookEvent } from '@clerk/nextjs/server'
const webhookSecret = process.env.CLERK_WEBHOOK_SECRET
export async function POST(req: Request) {
const payload = await req.text()
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 (!svix_id || !svix_timestamp || !svix_signature) {
return new Response('Missing headers', { status: 400 })
}
const wh = new Webhook(webhookSecret)
let evt: WebhookEvent
try {
evt = wh.verify(payload, {
'svix-id': svix_id,
'svix-timestamp': svix_timestamp,
'svix-signature': svix_signature,
}) as WebhookEvent
} catch (err) {
return new Response('Invalid signature', { status: 400 })
}
// Obsługa zdarzeń
const eventType = evt.type
if (eventType === 'user.created') {
const { id, email_addresses } = evt.data
await createUserInDatabase({
clerkId: id,
email: email_addresses[0].email_address,
})
}
if (eventType === 'user.deleted') {
const { id } = evt.data
await deleteUserFromDatabase(id)
}
return new Response('OK', { status: 200 })
}
📊 Cennik i limity
| Plan | Cena | Użytkownicy | Kluczowe funkcje |
|---|---|---|---|
| Free | $0 | 10,000 /msc | OAuth, Email, MFA (TOTP), Organizacje |
| Pro | $25/msc | 100,000 /msc | + SMS MFA, SAML SSO, Custom domain |
| Enterprise | Custom | Unlimited | + SLA, Dedicated support, Audit logs |
✨ Best practices
- Nigdy nie expose’uj
CLERK_SECRET_KEYw kodzie klienta - Używaj middleware do ochrony tras – nie tylko komponentów
- Weryfikuj webhooki za pomocą podpisu (signature)
- Używaj HTTPS w produkcji
- Włącz MFA dla kont administracyjnych
- Używaj
auth()w komponentach serwerowych – szybsze niż client-side - Cache’uj dane użytkownika gdy to możliwe
- Używaj Edge Runtime dla middleware
📋 Podsumowanie
| Funkcja | Komponent/Hook | Opis |
|---|---|---|
| Logowanie | <SignIn /> | Gotowy komponent logowania |
| Rejestracja | <SignUp /> | Gotowy komponent rejestracji |
| Menu użytkownika | <UserButton /> | Avatar z dropdown menu |
| Ochrona tras | clerkMiddleware | Middleware Next.js |
| Dane usera (server) | auth(), currentUser() | Server-side helpers |
| Dane usera (client) | useUser(), useAuth() | React hooks |
| Organizacje | <OrganizationList /> | Wybór/utworzenie org |
🎯 Kiedy używać Clerk?
✅ Wybierz Clerk jeśli: Budujesz nowoczesną aplikację React/Next.js, cenisz gotowe komponenty, potrzebujesz zaawansowanego zarządzania użytkownikami i organizacjami, lub chcesz szybko wdrożyć autentykację bez pisania własnego kodu.
❌ Rozważ alternatywę jeśli: Potrzebujesz self-hosted rozwiązania, masz bardzo specyficzne wymagania UI których nie da się osiągnąć w Clerk, lub szukasz darmowego rozwiązania dla bardzo dużej skali.
📚 Bibliografia
- Clerk Inc. (2026). Clerk Documentation. clerk.com/docs
- Clerk Inc. (2026). Clerk Next.js SDK. clerk.com/docs/quickstarts/nextjs
- Clerk Inc. (2026). Clerk Components Reference. clerk.com/docs/components
- Clerk Inc. (2026). Webhooks Documentation. clerk.com/docs/webhooks
- Clerk Inc. (2026). Organizations and B2B. clerk.com/docs/organizations