원클릭으로
api-auth-clerk
Clerk managed authentication - ClerkProvider, middleware, pre-built components, hooks, server-side auth, organizations, webhooks
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Clerk managed authentication - ClerkProvider, middleware, pre-built components, hooks, server-side auth, organizations, webhooks
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming, embeddings, image generation, audio transcription, translation, summarization, and Inference Endpoints
LiteLLM proxy server setup, TypeScript client patterns via OpenAI SDK, model routing, fallbacks, load balancing, spend tracking, virtual keys, and production deployment
Serverless GPU compute platform for AI model deployment — web endpoints, GPU functions, model serving, and TypeScript client patterns
Local LLM inference with the Ollama JavaScript client -- chat, streaming, tool calling, vision, embeddings, structured output, model management, and OpenAI-compatible endpoint
Replicate SDK patterns for TypeScript/Node.js -- client setup, predictions, streaming, webhooks, file handling, model versioning, deployments, and training
Together AI SDK patterns for TypeScript — client setup, chat completions, streaming, structured output, function calling, embeddings, image generation, fine-tuning, and OpenAI-compatible endpoints
| name | api-auth-clerk |
| description | Clerk managed authentication - ClerkProvider, middleware, pre-built components, hooks, server-side auth, organizations, webhooks |
Quick Guide: Clerk provides managed authentication with pre-built UI components, server-side helpers, and organization-based multi-tenancy. Use
clerkMiddleware()for route protection,<Show>for conditional rendering, hooks for client state, andauth()/currentUser()for server-side auth. Clerk Core 3 (2026) replaces<SignedIn>/<SignedOut>with<Show>, renames the middleware file toproxy.ts(Next.js 16+), and consolidates packages.
<critical_requirements>
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
import type, named constants)
(You MUST use @clerk/nextjs/server for ALL server-side imports -- NEVER import server helpers from @clerk/nextjs)
(You MUST verify webhooks using Clerk's verifyWebhook helper -- NEVER trust unverified webhook payloads)
(You MUST use <Show> component instead of deprecated <SignedIn>/<SignedOut>/<Protect> -- these are removed in Core 3)
(You MUST NOT pass the full currentUser() object to the client -- it contains privateMetadata that must stay server-side)
(You MUST protect routes in BOTH middleware AND data access layer -- middleware alone is insufficient)
</critical_requirements>
Auto-detection: Clerk, ClerkProvider, clerkMiddleware, @clerk/nextjs, useUser, useAuth, useClerk, useSession, useOrganization, SignIn, SignUp, UserButton, UserProfile, OrganizationSwitcher, auth(), currentUser(), CLERK_SECRET_KEY, NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, Show when="signed-in"
When to use:
Key patterns covered:
<SignIn>, <SignUp>, <UserButton>, <Show>)useUser, useAuth, useSession, useOrganization)auth(), currentUser()) in Server Components, Route Handlers, Server ActionsclerkMiddleware() and createRouteMatcher()When NOT to use:
Detailed Resources:
Clerk is a managed authentication platform that handles the entire auth lifecycle: sign-up, sign-in, session management, user profiles, organizations, and MFA. Instead of building auth from scratch, you integrate Clerk's SDK and pre-built components.
Core principles:
auth() and currentUser() in Server Components and Route Handlers. Only use client hooks (useUser, useAuth) when you need reactive client-side state.<SignIn>, <SignUp>, <UserButton> components. Only build custom flows when the pre-built components genuinely cannot meet requirements.verifyWebhook.When to use Clerk:
When NOT to use Clerk:
Every Clerk app needs <ClerkProvider> wrapping the app and clerkMiddleware() protecting routes. See examples/core.md for full setup examples.
Key rules:
ClerkProvider goes inside <body>, not wrapping <html> -- Core 3 requires thisNEXT_PUBLIC_CLERK_PUBLISHABLE_KEY env var, never hardcode keysproxy.ts on Next.js 16+ or middleware.ts on Next.js <=15verifyWebhook)CLERK_WEBHOOK_SIGNING_SECRET is the env var for webhook signing (not CLERK_WEBHOOK_SECRET)// proxy.ts (Next.js 16+) or middleware.ts (Next.js <=15)
const isPublicRoute = createRouteMatcher([
"/",
"/sign-in(.*)",
"/sign-up(.*)",
"/api/webhooks(.*)",
]);
export default clerkMiddleware(async (auth, req) => {
if (!isPublicRoute(req)) {
await auth.protect();
}
});
Why good: Public routes explicitly whitelisted, everything else requires auth, webhook endpoint is public (verified separately)
// BAD: clerkMiddleware() with no callback
export default clerkMiddleware(); // All routes are PUBLIC by default!
Why bad: clerkMiddleware() without callback attaches auth data but does not protect any route
<Show>Use <Show> for conditional rendering (Core 3 replacement for <SignedIn>/<SignedOut>/<Protect>). See examples/components.md for full examples.
<Show when="signed-out"><SignInButton /></Show>
<Show when="signed-in"><UserButton /></Show>
<Show when={{ role: "org:admin" }}><AdminPanel /></Show>
<Show when={(has) => has({ permission: "org:invoices:manage" })}><InvoiceManager /></Show>
Why good: <Show> is the Core 3 API, supports string/object/callback conditions, fallback prop for unauthorized
// BAD: Deprecated -- removed in Core 3
<SignedIn>...</SignedIn>
<SignedOut>...</SignedOut>
<Protect role="admin">...</Protect>
Why bad: <SignedIn>, <SignedOut>, <Protect> removed in Core 3, use <Show> with when prop
Sign-in/sign-up pages require catch-all route segments [[...sign-in]] for multi-step flows (MFA, OAuth callbacks).
Use hooks in Client Components for reactive auth state. Always check isLoaded before accessing data. See examples/hooks.md for complete examples.
"use client";
const { isLoaded, isSignedIn, user } = useUser();
if (!isLoaded) return <div>Loading...</div>;
if (!isSignedIn) return <div>Please sign in</div>;
// Now safe to access user.firstName, user.emailAddresses, etc.
Why good: Prevents hydration errors from accessing undefined during init, prevents TypeError from accessing null when signed out
// BAD: Accessing user without guards
const { user } = useUser();
return <p>{user.firstName}</p>; // Runtime error when isLoaded=false or isSignedIn=false
Why bad: user is undefined until loaded and null when signed out
Key hooks:
useUser() -- user profile data (name, email, avatar)useAuth() -- session tokens (getToken()), userId, orgId, has() for authorizationuseOrganization() -- active org data, membership, paginated members listuseReverification() -- re-authenticate before sensitive actions (Core 3)In Core 3, getToken() throws ClerkOfflineError when offline instead of returning null -- always wrap in try/catch.
Use auth() and currentUser() from @clerk/nextjs/server. See examples/server.md for complete examples.
auth() -- lightweight, no API call, reads session claims:
import { auth } from "@clerk/nextjs/server";
const { userId, orgId, isAuthenticated, redirectToSignIn } = await auth();
if (!isAuthenticated) return redirectToSignIn();
currentUser() -- full user object, makes Backend API call:
import { currentUser } from "@clerk/nextjs/server";
const user = await currentUser();
// CRITICAL: Pick safe fields before passing to client components
const safeData = { firstName: user.firstName, imageUrl: user.imageUrl };
Why critical: currentUser() returns privateMetadata that must never reach the client. Explicitly pick fields.
Defense in depth: Auth MUST be checked in every Server Action and Route Handler, not just middleware:
"use server";
const { userId } = await auth();
if (!userId) throw new Error("Unauthorized");
// userId scopes all queries/mutations to current user
Use auth.protect() or has() for granular access control. See examples/organizations.md for RBAC patterns.
// Middleware: role-based route protection
await auth.protect((has) => has({ role: "org:admin" }));
// Server Component: permission check
const { has } = await auth();
if (!has({ permission: "org:invoices:delete" })) redirect("/dashboard");
// Client: conditional rendering by role
<Show when={{ role: "org:admin" }}><AdminPanel /></Show>
Permission format: org:<feature>:<action> (e.g., org:invoices:create, org:reports:read)
Default roles: org:admin (all permissions), org:member (read-only). Custom roles configured in Clerk Dashboard.
Use Clerk webhooks (via Svix) to sync user data to your database. See examples/server.md for complete handler.
import { verifyWebhook } from "@clerk/nextjs/webhooks";
export async function POST(req: Request) {
const evt = await verifyWebhook(req); // reads CLERK_WEBHOOK_SIGNING_SECRET env var
// evt.type: "user.created" | "user.updated" | "user.deleted" | "organization.*" | ...
// evt.data: UserJSON | OrganizationJSON | etc.
}
Why good: verifyWebhook validates Svix signature, always returns 200 to prevent retries, webhook route is public in middleware (verified by signature not by auth)
// BAD: No signature verification
const body = await req.json(); // Anyone can POST fake data!
await db.insert(users).values(body.data); // Security vulnerability
Why bad: No signature verification means anyone can send fake webhook events to your endpoint
Import types from @clerk/shared/types (Core 3): UserJSON, OrganizationJSON, OrganizationMembershipJSON
<decision_framework>
Where do you need auth data?
|-- Server Component, Route Handler, Server Action
| |-- Need just userId/sessionId? --> auth()
| |-- Need full user object? --> currentUser()
| |-- Need to protect the route? --> auth.protect()
| +-- Need org context? --> auth() returns orgId, orgRole
|
+-- Client Component (interactive UI)
|-- Need user profile data? --> useUser()
|-- Need session/token data? --> useAuth()
|-- Need org data? --> useOrganization()
+-- Need low-level Clerk API? --> useClerk()
What kind of route is it?
|-- Public (landing, sign-in, sign-up, webhooks)
| +-- Add to isPublicRoute matcher, skip auth.protect()
|
|-- Authenticated (dashboard, profile, settings)
| +-- auth.protect() in middleware + auth() check in data layer
|
+-- Authorized (admin, org-specific, permission-gated)
|-- Role-based? --> auth.protect({ role: "org:admin" })
+-- Permission-based? --> auth.protect((has) => has({ permission: "org:feature:action" }))
What auth UI do you need?
|-- Full sign-in page --> <SignIn /> on catch-all route
|-- Full sign-up page --> <SignUp /> on catch-all route
|-- Sign-in button (modal) --> <SignInButton />
|-- User avatar + menu --> <UserButton />
|-- Full profile editor --> <UserProfile />
|-- Org switcher --> <OrganizationSwitcher />
+-- Conditional content --> <Show when="signed-in"> or <Show when={{ role: "..." }}>
</decision_framework>
<red_flags>
High Priority Issues:
@clerk/nextjs instead of @clerk/nextjs/server (breaks in Server Components)<SignedIn>/<SignedOut>/<Protect> components (removed in Core 3)currentUser() object to client components (leaks privateMetadata)verifyWebhook signature verification@clerk/types instead of @clerk/shared/types (Core 3 rename)Medium Priority Issues:
isLoaded before accessing hook data (causes hydration errors)currentUser() on the client side (it is server-only)authMiddleware() (deprecated, replaced by clerkMiddleware())CLERK_WEBHOOK_SECRET instead of CLERK_WEBHOOK_SIGNING_SECRETCommon Mistakes:
middleware.ts on Next.js 16+ (should be proxy.ts) or proxy.ts on Next.js <=15 (should be middleware.ts)[[...sign-in]] on sign-in/sign-up pages (breaks multi-step flows)getToken() without try/catch in Core 3 (throws ClerkOfflineError when offline instead of returning null)prefetch={false} to <Link> components pointing at protected routes from public pagesGotchas & Edge Cases:
currentUser() counts against Backend API rate limits -- prefer useUser() hook on the client when possibleauth() in Server Components is deduplicated per request (safe to call multiple times)<Show when={{ role: "org:admin" }}> requires an active organization in the sessionorg: prefix (e.g., org:admin, org:member, org:billing)@clerk/clerk-react renamed to @clerk/react in Core 3 -- update imports after upgrade</red_flags>
<critical_reminders>
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
import type, named constants)
(You MUST use @clerk/nextjs/server for ALL server-side imports -- NEVER import server helpers from @clerk/nextjs)
(You MUST verify webhooks using Clerk's verifyWebhook helper -- NEVER trust unverified webhook payloads)
(You MUST use <Show> component instead of deprecated <SignedIn>/<SignedOut>/<Protect> -- these are removed in Core 3)
(You MUST NOT pass the full currentUser() object to the client -- it contains privateMetadata that must stay server-side)
(You MUST protect routes in BOTH middleware AND data access layer -- middleware alone is insufficient)
Failure to follow these rules will create authentication vulnerabilities or break on Clerk Core 3.
</critical_reminders>