TrueSpec

Clerk Auth in Next.js App Router

Drop-in auth with Clerk, middleware protection, and user metadata

What You’ll Build

After following this guide, you will have a working implementation of clerk auth in next.js app router in your project. Add production-ready authentication to Next.js App Router in under 10 minutes with Clerk. Includes pre-built sign-in/sign-up UI components, middleware-based route protection, and server-side user access. No need to build auth UI from scratch.

Use Cases & Problems Solved

  • Protect routes so only authenticated users can access sensitive pages
  • Allow users to sign up, log in, and manage their accounts securely
  • Avoid storing raw passwords or building session management from scratch

Prerequisites

  • Clerk account (free tier available)
  • Next.js 14+ with App Router

Step-by-Step Implementation

Install Clerk

The following snippet shows how to install clerk. Copy this into your project and adjust the values for your environment.

npm install @clerk/nextjs

Add environment variables

The following snippet shows how to add environment variables. Copy this into your project and adjust the values for your environment.

# .env.local
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...

Wrap app with ClerkProvider

The following snippet shows how to wrap app with clerkprovider. Copy this into your project and adjust the values for your environment.

// app/layout.js
import { ClerkProvider, SignedIn, SignedOut, UserButton, SignInButton } from '@clerk/nextjs';

export default function RootLayout({ children }) {
  return (
    <ClerkProvider>
      <html lang="en">
        <body>
          <nav>
            <SignedOut><SignInButton /></SignedOut>
            <SignedIn><UserButton /></SignedIn>
          </nav>
          {children}
        </body>
      </html>
    </ClerkProvider>
  );
}

Protect routes with middleware

The following snippet shows how to protect routes with middleware. Copy this into your project and adjust the values for your environment.

// middleware.js (project root)
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server';

const isProtectedRoute = createRouteMatcher(['/dashboard(.*)']);

export default clerkMiddleware(async (auth, req) => {
  if (isProtectedRoute(req)) await auth.protect();
});

export const config = { matcher: ['/((?!.*\\..*|_next).*)'] };

⚠️ Don’t Do This

❌ Checking auth only on the client side

// Client-only check — data already sent to browser!
export default function SecretPage() {
  const { isSignedIn } = useUser();
  if (!isSignedIn) redirect('/sign-in');
  return <SecretData />; // Too late, HTML was already sent
}

✅ Use middleware for server-side route protection

// middleware.js — blocks request BEFORE page renders
export default clerkMiddleware(async (auth, req) => {
  if (isProtectedRoute(req)) await auth.protect();
});

Testing

Add these tests to verify your clerk auth in next.js app router implementation works correctly:

// __tests__/clerk.test.ts
import { describe, it, expect } from 'vitest';

describe('Clerk Auth in Next.js App Router', () => {
  it('should handle successful authentication', async () => {
    // Test the happy path
    const result = await authenticate({ email: 'test@example.com', password: 'valid' });
    expect(result.user).toBeDefined();
    expect(result.error).toBeNull();
  });

  it('should reject invalid credentials', async () => {
    const result = await authenticate({ email: 'test@example.com', password: 'wrong' });
    expect(result.user).toBeNull();
    expect(result.error).toBeDefined();
  });

  it('should handle missing fields', async () => {
    const result = await authenticate({ email: '', password: '' });
    expect(result.error).toBeDefined();
  });
});

Verification

npm run dev
# Visit /dashboard — should redirect to Clerk sign-in
# Sign in — should see UserButton avatar in nav
# Visit /dashboard again — should load successfully

Related Specs

Intermediate

Passwordless Magic Link Auth

Email magic link flow with Resend and custom token verification

Auth & Identity
Intermediate

Next.js Google OAuth Login

Complete Google OAuth flow with NextAuth.js, token handling, session management

Auth & Identity
Beginner

Supabase Email/Password Auth

Sign up, sign in, password reset, and protected routes with Supabase Auth

Auth & Identity