
Clerk Auth
Implement Clerk sign-in, middleware, organizations, webhooks, and user sync in a Next.js App Router SaaS without guessing env vars or layout wiring.
Install
npx skills add https://github.com/sickn33/antigravity-awesome-skills --skill clerk-authWhat is this skill?
- Next.js 14/15 App Router setup with ClerkProvider wrapping the root layout
- Documented .env.local keys for publishable, secret, sign-in/up URLs, and post-auth redirects
- Pre-built SignIn, SignUp, and UserButton component placement patterns
- Coverage themes for middleware, organizations, webhooks, and user sync in skill scope
- Apache 2.0 sourced patterns from vibeship-spawner-skills lineage
Adoption & trust: 662 installs on skills.sh; 40.1k GitHub stars; 3/3 security scanners passed (skills.sh audits).
Recommended Skills
Journey fit
Authentication integration is classic Build work once you are wiring the product backend and third-party identity. Integrations is the right shelf because Clerk is an external auth provider with env keys, middleware, and webhook contracts—not generic frontend styling alone.
Common Questions / FAQ
Is Clerk Auth safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.
SKILL.md
READMESKILL.md - Clerk Auth
# Clerk Authentication Expert patterns for Clerk auth implementation, middleware, organizations, webhooks, and user sync ## Patterns ### Next.js App Router Setup Complete Clerk setup for Next.js 14/15 App Router. Includes ClerkProvider, environment variables, and basic sign-in/sign-up components. Key components: - ClerkProvider: Wraps app for auth context - <SignIn />, <SignUp />: Pre-built auth forms - <UserButton />: User menu with session management ### Code_example # Environment variables (.env.local) NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_... CLERK_SECRET_KEY=sk_test_... 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 // app/layout.tsx import { ClerkProvider } from '@clerk/nextjs'; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <ClerkProvider> <html lang="en"> <body>{children}</body> </html> </ClerkProvider> ); } // app/sign-in/[[...sign-in]]/page.tsx import { SignIn } from '@clerk/nextjs'; export default function SignInPage() { return ( <div className="flex justify-center items-center min-h-screen"> <SignIn /> </div> ); } // app/sign-up/[[...sign-up]]/page.tsx import { SignUp } from '@clerk/nextjs'; export default function SignUpPage() { return ( <div className="flex justify-center items-center min-h-screen"> <SignUp /> </div> ); } // components/Header.tsx import { SignedIn, SignedOut, SignInButton, UserButton } from '@clerk/nextjs'; export function Header() { return ( <header className="flex justify-between p-4"> <h1>My App</h1> <SignedOut> <SignInButton /> </SignedOut> <SignedIn> <UserButton afterSignOutUrl="/" /> </SignedIn> </header> ); } ### Anti_patterns - Pattern: ClerkProvider inside page component | Why: Provider must wrap entire app in root layout | Fix: Move ClerkProvider to app/layout.tsx - Pattern: Using auth() without middleware | Why: auth() requires clerkMiddleware to be configured | Fix: Set up middleware.ts with clerkMiddleware ### References - https://clerk.com/docs/nextjs/getting-started/quickstart ### Middleware Route Protection Protect routes using clerkMiddleware and createRouteMatcher. Best practices: - Single middleware.ts file at project root - Use createRouteMatcher for route groups - auth.protect() for explicit protection - Centralize all auth logic in middleware ### Code_example // middleware.ts import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server'; // Define protected route patterns const isProtectedRoute = createRouteMatcher([ '/dashboard(.*)', '/settings(.*)', '/api/private(.*)', ]); // Define public routes (optional, for clarity) const isPublicRoute = createRouteMatcher([ '/', '/sign-in(.*)', '/sign-up(.*)', '/api/webhooks(.*)', ]); export default clerkMiddleware(async (auth, req) => { // Protect matched routes if (isProtectedRoute(req)) { await auth.protect(); } }); export const config = { matcher: [ // Match all routes except 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)(.*)', ], }; // Advanced: Role-based protection export default clerkMiddleware(async (auth, req) => { if (isProtectedRoute(req)) { await auth.protect(); } // Admin routes require admin role if (req.nextUrl.pathname.startsWith('/admin')) { await auth.protect({ role: 'org:admin', }); } // Premium routes require premium permission if (req.nextUrl.pathname.star