Clerk Auth Setup in Under 10 Minutes - 2026 Guide
Production-ready Clerk authentication setup for Next.js. Real errors, exact versions, and copy-paste code patterns for indie hackers.
TL;DR
Clerk provides OAuth + passwordless auth with zero backend. Install @clerk/nextjs (verify latest version in official docs), add environment variables, wrap your app in <ClerkProvider>, and protect routes with middleware. Full setup: ~8 minutes.
---
Why Clerk?
Traditional auth requires:
Clerk handles all of this. You get:
For indie projects, this saves 20+ hours.
---
Step 1: Create Clerk Account & Get Keys
1. Go to [clerk.com](https://clerk.com) 2. Sign up and create a new application 3. Select your framework (Next.js recommended) 4. Copy your API keys from the dashboard
You'll get:
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY (safe to expose)CLERK_SECRET_KEY (keep private)Verify current pricing tiers in [official docs](https://clerk.com/docs/pricing) - plans update frequently.
---
Step 2: Install Dependencies
```bash npm install @clerk/nextjs
or yarn add @clerk/nextjs
```Current stable version: verify with: ```bash npm view @clerk/nextjs version ```
As of 2026, versions follow semver. Pin to major: "@clerk/nextjs": "^5.0.0" (verify in official docs for latest).
---
Step 3: Set Environment Variables
Create .env.local:
```bash NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_xxxxx CLERK_SECRET_KEY=sk_test_xxxxx 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 ```
⚠️ .env.local is gitignored by default. Never commit secrets.
---
Step 4: Wrap App with ClerkProvider
app/layout.tsx (App Router):
```typescript import { ClerkProvider } from '@clerk/nextjs'; import type { Metadata } from 'next';
export const metadata: Metadata = { title: 'My App', };
export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <ClerkProvider> <html lang="en"> <body>{children}</body> </html> </ClerkProvider> ); } ```
pages/_app.tsx (Pages Router - legacy):
```typescript import { ClerkProvider } from '@clerk/nextjs'; import type { AppProps } from 'next/app';
function MyApp({ Component, pageProps }: AppProps) { return ( <ClerkProvider> <Component {...pageProps} /> </ClerkProvider> ); }
export default MyApp; ```
---
Step 5: Create Auth Routes
app/sign-in/[[...index]]/page.tsx:
```typescript import { SignIn } from '@clerk/nextjs';
export default function SignInPage() { return ( <div className="flex items-center justify-center min-h-screen"> <SignIn /> </div> ); } ```
app/sign-up/[[...index]]/page.tsx:
```typescript import { SignUp } from '@clerk/nextjs';
export default function SignUpPage() { return ( <div className="flex items-center justify-center min-h-screen"> <SignUp /> </div> ); } ```
The [[...index]] dynamic route handles Clerk's internal routing.
---
Step 6: Protect Routes with Middleware
middleware.ts (root of project):
```typescript import { authMiddleware } from '@clerk/nextjs';
export default authMiddleware({ publicRoutes: ['/', '/about', '/pricing'], ignoredRoutes: ['/api/webhooks(.*)'], });
export const config = { matcher: [ '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest))(?:.*))' ] }; ```
Any route NOT in publicRoutes requires authentication.
---
Step 7: Add User Components (Optional)
Display logged-in user:
```typescript import { UserButton, useUser } from '@clerk/nextjs';
export default function Dashboard() { const { user, isLoaded } = useUser();
if (!isLoaded) return <div>Loading...</div>;
return ( <div className="flex justify-between items-center p-4"> <h1>Welcome, {user?.firstName}!</h1> <UserButton /> </div> ); } ```
The <UserButton /> shows avatar + dropdown menu with sign-out.
---
Common Console Errors
Error 1: Missing publishable key ``` Error: Clerk: The publishable key is missing. Make sure to set NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY in your .env.local ```
→ Check .env.local exists and is loaded. Restart dev server.
Error 2: Middleware redirect loop ``` Error: Infinite redirect detected. AuthMiddleware is continuously redirecting to /sign-in ```
→ Add /sign-in and /sign-up to publicRoutes array in middleware.
Error 3: useUser() in Server Component ``` Error: "useUser" is a client component. Use 'use client' directive. ```
→ Add 'use client' at the top of component using auth hooks.
---
Production Checklist
pk_test_)CLERK_SECRET_KEY in hosting platform's env vars (Vercel, Netlify, etc.)---
Additional Resources
Related guides: [JWT tokens in Next.js](/?guide=jwt-nextjs) | [Protecting API routes](/?guide=api-route-protection)
---
What am I missing?
This guide covers basic auth flow. Please share in comments:
Your real-world experience helps future readers. 👇