clerk-auth
This skill provides comprehensive knowledge for integrating Clerk authentication in React, Next.js, and Cloudflare Workers applications. It should be used when setting up user authentication, implementing protected routes, verifying JWT tokens, creating custom JWT templates with user metadata and organization claims, configuring Clerk middleware, integrating with shadcn/ui components, testing authentication flows, or troubleshooting Clerk authentication errors. Use when: adding Clerk to React/Vite projects, setting up Clerk in Next.js App Router, implementing Clerk authentication in Cloudflare Workers, configuring clerkMiddleware for route protection, creating custom JWT templates with shortcodes (user.id, user.email, user.public_metadata.role), accessing session claims for RBAC, integrating with Supabase/Grafbase, verifying tokens with @clerk/backend, integrating Clerk with Hono, using Clerk shadcn/ui components, writing E2E tests with Playwright, generating test session tokens, using test email addresses and phone numbers, or encountering authentication errors. Prevents 11 documented issues: missing secret key errors, API key migration failures, JWKS cache race conditions, CSRF vulnerabilities from missing authorizedParties, import path errors after Core 2 upgrade, JWT size limit issues, deprecated API version warnings, ClerkProvider JSX component errors, async auth() helper confusion, environment variable misconfiguration, and Vite dev mode 431 header errors. Keywords: clerk, clerk auth, clerk authentication, @clerk/nextjs, @clerk/backend, @clerk/clerk-react, clerkMiddleware, createRouteMatcher, verifyToken, useUser, useAuth, useClerk, JWT template, JWT claims, JWT shortcodes, custom JWT, session claims, getToken template, user.public_metadata, org_id, org_slug, org_role, CustomJwtSessionClaims, sessionClaims metadata, clerk webhook, clerk secret key, clerk publishable key, protected routes, Cloudflare Workers auth, Next.js auth, shadcn/ui auth, @hono/clerk-auth, "Missing Clerk Secret Key", "cannot be used as a JSX component", JWKS error, authorizedParties, clerk middleware, ClerkProvider, UserButton, SignIn, SignUp, clerk testing, test emails, test phone numbers, +clerk_test, 424242 OTP, session token, testing token, @clerk/testing, playwright testing, E2E testing, clerk test mode, bot detection, generate session token, test users
What this skill does
# Clerk Authentication **Status**: Production Ready ✅ **Last Updated**: 2025-10-28 **Dependencies**: None **Latest Versions**: @clerk/[email protected], @clerk/[email protected], @clerk/[email protected], @clerk/[email protected] --- ## Quick Start (10 Minutes) Choose your framework: - [React (Vite)](#react-vite-setup) - ClerkProvider + hooks - [Next.js App Router](#nextjs-app-router-setup) - Middleware + async auth() - [Cloudflare Workers](#cloudflare-workers-setup) - Backend verification --- ## React (Vite) Setup ### 1. Install Clerk \`\`\`bash npm install @clerk/clerk-react \`\`\` **Latest Version**: @clerk/[email protected] (verified 2025-10-22) ### 2. Configure ClerkProvider Update \`src/main.tsx\`: \`\`\`typescript import React from 'react' import ReactDOM from 'react-dom/client' import { ClerkProvider } from '@clerk/clerk-react' import App from './App.tsx' import './index.css' // Get publishable key from environment const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY if (!PUBLISHABLE_KEY) { throw new Error('Missing Publishable Key') } ReactDOM.createRoot(document.getElementById('root')!).render( <React.StrictMode> <ClerkProvider publishableKey={PUBLISHABLE_KEY}> <App /> </ClerkProvider> </React.StrictMode>, ) \`\`\` **CRITICAL**: - Use \`VITE_\` prefix for environment variables in Vite - ClerkProvider must wrap your entire app - Source: https://clerk.com/docs/references/react/clerk-provider ### 3. Add Environment Variables Create \`.env.local\`: \`\`\`bash VITE_CLERK_PUBLISHABLE_KEY=pk_test_... \`\`\` **Security Note**: Only \`VITE_\` prefixed vars are exposed to client code. ### 4. Use Authentication Hooks \`\`\`typescript import { useUser, useAuth, useClerk } from '@clerk/clerk-react' function App() { // Get user object (includes email, metadata, etc.) const { isLoaded, isSignedIn, user } = useUser() // Get auth state and session methods const { userId, sessionId, getToken } = useAuth() // Get Clerk instance for advanced operations const { openSignIn, signOut } = useClerk() // Always check isLoaded before rendering auth-dependent UI if (!isLoaded) { return <div>Loading...</div> } if (!isSignedIn) { return <button onClick={() => openSignIn()}>Sign In</button> } return ( <div> <h1>Welcome {user.firstName}!</h1> <p>Email: {user.primaryEmailAddress?.emailAddress}</p> <button onClick={() => signOut()}>Sign Out</button> </div> ) } \`\`\` **Why This Matters**: - \`isLoaded\` prevents flash of wrong content - \`useUser()\` provides full user object with metadata - \`useAuth()\` provides session tokens and auth state - Source: https://clerk.com/docs/references/react/use-user --- ## Next.js App Router Setup ### 1. Install Clerk \`\`\`bash npm install @clerk/nextjs \`\`\` **Latest Version**: @clerk/[email protected] (verified 2025-10-22) - **New in v6**: Async auth() helper, Next.js 15 support, static rendering by default - Source: https://clerk.com/changelog/2024-10-22-clerk-nextjs-v6 ### 2. Configure Environment Variables Create \`.env.local\`: \`\`\`bash NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_... CLERK_SECRET_KEY=sk_test_... # Optional: Customize sign-in/up pages 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 \`\`\` **CRITICAL**: - \`CLERK_SECRET_KEY\` must NEVER be exposed to client - Use \`NEXT_PUBLIC_\` prefix for client-side vars only - Source: https://clerk.com/docs/guides/development/clerk-environment-variables ### 3. Add Middleware for Route Protection Create \`middleware.ts\` in project root: \`\`\`typescript import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server' // Define which routes are public (everything else requires auth) const isPublicRoute = createRouteMatcher([ '/', '/sign-in(.*)', '/sign-up(.*)', '/api/webhooks(.*)', // Clerk webhooks should be public ]) export default clerkMiddleware(async (auth, request) => { // Protect all routes except public ones if (!isPublicRoute(request)) { await auth.protect() } }) export const config = { matcher: [ // Skip Next.js internals and static files '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], } \`\`\` **CRITICAL**: - \`auth.protect()\` is async in v6 (breaking change from v5) - \`createRouteMatcher()\` accepts glob patterns - Alternative: protect specific routes instead of inverting logic - Source: https://clerk.com/docs/reference/nextjs/clerk-middleware ### 4. Wrap App with ClerkProvider Update \`app/layout.tsx\`: \`\`\`typescript import { ClerkProvider } from '@clerk/nextjs' import './globals.css' export default function RootLayout({ children, }: { children: React.ReactNode }) { return ( <ClerkProvider> <html lang="en"> <body>{children}</body> </html> </ClerkProvider> ) } \`\`\` ### 5. Use auth() in Server Components \`\`\`typescript import { auth, currentUser } from '@clerk/nextjs/server' export default async function DashboardPage() { // Get auth state (lightweight) const { userId, sessionId } = await auth() // Get full user object (heavier, fewer calls) const user = await currentUser() if (!userId) { return <div>Unauthorized</div> } return ( <div> <h1>Dashboard</h1> <p>User ID: {userId}</p> <p>Email: {user?.primaryEmailAddress?.emailAddress}</p> </div> ) } \`\`\` **CRITICAL**: - \`auth()\` is async in v6 (breaking change) - Use \`auth()\` for lightweight checks - Use \`currentUser()\` when you need full user object --- ## Cloudflare Workers Setup ### 1. Install Dependencies \`\`\`bash npm install @clerk/backend hono \`\`\` **Latest Versions**: - @clerk/[email protected] (verified 2025-10-22) - [email protected] ### 2. Configure Environment Variables Create \`.dev.vars\` for local development: \`\`\`bash CLERK_SECRET_KEY=sk_test_... CLERK_PUBLISHABLE_KEY=pk_test_... \`\`\` **Production**: Use \`wrangler secret put CLERK_SECRET_KEY\` ### 3. Implement Token Verification Create \`src/index.ts\`: \`\`\`typescript import { Hono } from 'hono' import { verifyToken } from '@clerk/backend' type Bindings = { CLERK_SECRET_KEY: string CLERK_PUBLISHABLE_KEY: string } type Variables = { userId: string | null sessionClaims: any | null } const app = new Hono<{ Bindings: Bindings; Variables: Variables }>() // Middleware: Verify Clerk token app.use('/api/*', async (c, next) => { const authHeader = c.req.header('Authorization') if (!authHeader) { c.set('userId', null) c.set('sessionClaims', null) return next() } const token = authHeader.replace('Bearer ', '') try { const { data, error } = await verifyToken(token, { secretKey: c.env.CLERK_SECRET_KEY, // IMPORTANT: Set authorizedParties to prevent CSRF attacks authorizedParties: ['https://yourdomain.com'], }) if (error) { console.error('Token verification failed:', error) c.set('userId', null) c.set('sessionClaims', null) } else { c.set('userId', data.sub) c.set('sessionClaims', data) } } catch (err) { console.error('Token verification error:', err) c.set('userId', null) c.set('sessionClaims', null) } return next() }) // Protected route app.get('/api/protected', (c) => { const userId = c.get('userId') if (!userId) { return c.json({ error: 'Unauthorized' }, 401) } return c.json({ message: 'This is protected', userId, sessionClaims: c.get('sessionClaims'), }) }) export default app \`\`\` **CRITICAL**: - Always set \`authorizedParties\` to prevent CSRF attacks - Use \`secretKey\`, not deprecated \`apiKey\` - Source: https://clerk.com/docs/reference/backend/verify-token --- ## JWT Te
Related in Design
contribute
IncludedLocal-only OSS contribution command center. Auto-refreshes the user's in-flight PR and issue state on invoke so conversations start with full context — no need to brief Claude on what's in flight. Helps the user find issues to contribute to on GitHub, builds per-repo dossiers of what each upstream expects (CLA, DCO, branch convention, AI policy, draft-first, review bots, issue templates), runs deterministic gates before any external action so AI-assisted contributions don't reach maintainers as slop. State is markdown-only: candidate files at ~/.contribute-system/candidates/, repo dossiers at ~/.contribute-system/research/, append-only event log at ~/.contribute-system/log.jsonl. No database, no cloud calls. Use when the user asks about their PRs / issues / contributions, wants to find new work to take on, claim an issue, build/refresh a repo's dossier, or draft a Design Issue or PR. Trigger with "/contribute", "what's my PR status", "find a contribution", "claim issue X", "draft a Design Issue for Y", "refresh dossier for Z".
architectural-analysis
IncludedUser-triggered deep architectural analysis of a codebase or scoped subtree across eight modes — information architecture, data flow, integration points, UI surfaces, interaction patterns, data model, control flow, and failure modes. This skill should be used when the user asks to "diagram this codebase," "map the architecture," "show the data flow," "give me an ERD," "trace control flow," "find the integration points," "verify the layout pattern," "audit the UX architecture," or any similar request whose primary deliverable is mermaid diagrams plus cited reports under docs/architecture/. Dispatches haiku/sonnet sub-agents in parallel for per-mode exploration, then verifies every citation mechanically before any node lands in a diagram. Not for one-off prose explanations of code (use code-explanation) or for high-level system design from scratch (use system-design).
mcp
IncludedModel Context Protocol (MCP) server development and tool management. Languages: Python, TypeScript. Capabilities: build MCP servers, integrate external APIs, discover/execute MCP tools, manage multi-server configs, design agent-centric tools. Actions: create, build, integrate, discover, execute, configure MCP servers/tools. Keywords: MCP, Model Context Protocol, MCP server, MCP tool, stdio transport, SSE transport, tool discovery, resource provider, prompt template, external API integration, Gemini CLI MCP, Claude MCP, agent tools, tool execution, server config. Use when: building MCP servers, integrating external APIs as MCP tools, discovering available MCP tools, executing MCP capabilities, configuring multi-server setups, designing tools for AI agents.
react-native-skia
IncludedDesign, build, debug, and optimise high-polish animated graphics in React Native or Expo using @shopify/react-native-skia, Reanimated, and Gesture Handler. Use when the user wants canvas-driven UI, shaders, paths, rich text, image filters, sprite fields, Skottie, video frames, snapshots, web CanvasKit setup, or performance tuning for custom motion-heavy elements such as loaders, hero art, cards, charts, progress indicators, particle systems, or gesture-driven surfaces. Also use when the user asks for fluid, glow, glass, blob, parallax, 60fps/120fps, or GPU-friendly animated effects in React Native, even if they do not explicitly say "Skia". Do not use for ordinary form/layout work with standard views.
plaid
IncludedProduct Led AI Development — guides founders from idea to launched product. Six capabilities: Idea (discover a product idea), Validate (pressure-test the idea against fatal flaws, problem reality, competition, and 2-week MVP feasibility), Plan (vision intake + document generation), Design (translate image references into a design.md spec), Launch (go-to-market strategy), and Build (roadmap execution). Use when someone says "PLAID", "plaid idea", "help me find an idea", "product idea", "idea from my business", "idea from my expertise", "plaid validate", "validate my idea", "pressure-test", "is this idea good", "find fatal flaws", "validate the problem", "plan a product", "define my vision", "generate a PRD", "product strategy", "plaid design", "design from image", "translate image to design", "create design.md", "extract design tokens", "plaid launch", "go-to-market", "launch plan", "GTM strategy", "launch playbook", "plaid build", "build the app", "start building", or "execute the roadmap".
nextjs-framer-motion-animations
IncludedAdds production-safe Motion for React or Framer Motion animations to Next.js apps, including reveal, hover and tap micro-interactions, whileInView, stagger, AnimatePresence, layout and layoutId transitions, reorder, scroll-linked UI, and lightweight route-content transitions. Use when the user asks to add, refactor, or debug Motion or Framer Motion in App Router or Pages Router codebases, especially around server/client boundaries, reduced motion, LazyMotion, bundle size, hydration, or route transitions. Avoid for GSAP-style timelines, WebGL or 3D scenes, heavy scroll storytelling, or CSS-only effects unless Motion is explicitly requested.