Complete Next.js integration patterns for Clerk authentication with App Router and Pages Router. Use when setting up Clerk in Next.js, configuring authentication middleware, implementing protected routes, setting up server/client components with auth, or when user mentions Clerk Next.js setup, App Router auth, Pages Router auth, or Next.js authentication integration.
Limited to specific tools
Additional assets for this skill
This skill is limited to using the following tools:
README.mdVALIDATION_SUMMARY.mdexamples/client-component-auth.tsxexamples/protected-route.tsxexamples/server-component-auth.tsxscripts/configure-middleware.shscripts/install-clerk.shscripts/setup-app-router.shscripts/setup-pages-router.shtemplates/app-router/layout.tsxtemplates/app-router/middleware.tstemplates/pages-router/_app.tsxtemplates/pages-router/api/auth.tsThis skill provides complete Clerk authentication integration for Next.js applications, supporting both App Router (Next.js 13+) and Pages Router patterns. It covers installation, middleware configuration, authentication helpers, and protected route patterns.
Install Clerk SDK and configure environment variables:
# Run automated installation script
bash ./skills/nextjs-integration/scripts/install-clerk.sh
# Or manually install
npm install @clerk/nextjs
Environment Variables:
# Create .env.local with Clerk credentials
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_your_key_here
CLERK_SECRET_KEY=sk_test_your_key_here
# Optional: Customize sign-in/sign-up URLs
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
What This Does:
Configure Clerk for Next.js App Router (13.4+):
# Run App Router setup script
bash ./skills/nextjs-integration/scripts/setup-app-router.sh
Files Created:
middleware.ts - Route protection at edgeapp/layout.tsx - ClerkProvider wrapperapp/sign-in/[[...sign-in]]/page.tsx - Sign-in pageapp/sign-up/[[...sign-up]]/page.tsx - Sign-up pageApp Router Features:
auth() helperuseAuth() hookCopy Template Files:
# Middleware configuration
cp ./skills/nextjs-integration/templates/app-router/middleware.ts ./middleware.ts
# Root layout with ClerkProvider
cp ./skills/nextjs-integration/templates/app-router/layout.tsx ./app/layout.tsx
Configure Clerk for Next.js Pages Router (12.x and earlier):
# Run Pages Router setup script
bash ./skills/nextjs-integration/scripts/setup-pages-router.sh
Files Created:
pages/_app.tsx - ClerkProvider wrapperpages/api/auth.ts - API route for auth callbackspages/sign-in/[[...index]].tsx - Sign-in pagepages/sign-up/[[...index]].tsx - Sign-up pagePages Router Features:
Copy Template Files:
# _app.tsx with ClerkProvider
cp ./skills/nextjs-integration/templates/pages-router/_app.tsx ./pages/_app.tsx
# Auth API route
cp ./skills/nextjs-integration/templates/pages-router/api/auth.ts ./pages/api/auth.ts
Configure middleware for route protection:
# Setup auth middleware with route matching
bash ./skills/nextjs-integration/scripts/configure-middleware.sh
Middleware Patterns:
/dashboard/*)Middleware Configuration:
// middleware.ts - Protects routes at the edge
import { authMiddleware } from "@clerk/nextjs";
export default authMiddleware({
publicRoutes: ["/", "/api/public"],
ignoredRoutes: ["/api/webhook"],
});
export const config = {
matcher: ['/((?!.+\\.[\\w]+$|_next).*)', '/', '/(api|trpc)(.*)'],
};
Use auth() helper in Server Components:
import { auth } from '@clerk/nextjs';
export default async function DashboardPage() {
const { userId } = auth();
if (!userId) {
redirect('/sign-in');
}
// Protected server component logic
const userData = await fetchUserData(userId);
return <div>Welcome {userData.name}</div>;
}
Server-Side Helpers:
auth() - Get current user sessioncurrentUser() - Get full user objectredirectToSignIn() - Redirect helperclerkClient - Server-side Clerk API clientUse React hooks in Client Components:
'use client';
import { useAuth, useUser } from '@clerk/nextjs';
export function UserProfile() {
const { userId, isLoaded, isSignedIn } = useAuth();
const { user } = useUser();
if (!isLoaded) return <div>Loading...</div>;
if (!isSignedIn) return <div>Please sign in</div>;
return <div>Hello {user.firstName}</div>;
}
Client-Side Hooks:
useAuth() - Authentication stateuseUser() - Current user datauseClerk() - Clerk instance methodsuseSignIn() - Sign-in flow controluseSignUp() - Sign-up flow control# 1. Install Clerk
bash ./skills/nextjs-integration/scripts/install-clerk.sh
# 2. Configure App Router
bash ./skills/nextjs-integration/scripts/setup-app-router.sh
# 3. Setup middleware
bash ./skills/nextjs-integration/scripts/configure-middleware.sh
# 4. Copy protected route example
cp ./skills/nextjs-integration/examples/protected-route.tsx ./app/dashboard/page.tsx
# 5. Copy server component auth example
cp ./skills/nextjs-integration/examples/server-component-auth.tsx ./app/profile/page.tsx
# 6. Start development server
npm run dev
Result: Fully configured Next.js App Router with Clerk authentication, protected routes, and sign-in/sign-up pages
# 1. Install Clerk
bash ./skills/nextjs-integration/scripts/install-clerk.sh
# 2. Configure Pages Router
bash ./skills/nextjs-integration/scripts/setup-pages-router.sh
# 3. Copy API route template
cp ./skills/nextjs-integration/templates/pages-router/api/auth.ts ./pages/api/auth.ts
# 4. Test authentication
npm run dev
Result: Pages Router setup with API route authentication and custom auth pages
Configure organization-based authentication:
// Server Component with organization context
import { auth } from '@clerk/nextjs';
export default async function TeamDashboard() {
const { orgId, userId } = auth();
if (!orgId) {
return <div>Please select an organization</div>;
}
const teamData = await fetchTeamData(orgId);
return <TeamView data={teamData} />;
}
Organization Features:
// App Router API route with auth
import { auth } from '@clerk/nextjs';
import { NextResponse } from 'next/server';
export async function GET() {
const { userId } = auth();
if (!userId) {
return new NextResponse('Unauthorized', { status: 401 });
}
const data = await fetchProtectedData(userId);
return NextResponse.json(data);
}
Dependencies:
@clerk/nextjs - Clerk Next.js SDKClerk Account:
Project Structure:
create-next-appapp/ directory (App Router) or pages/ directory (Pages Router)Environment Variables:
.env.local for local development.env.production for production (never commit secrets)Never Hardcode API Keys:
# ✅ CORRECT - Use environment variables
CLERK_SECRET_KEY=your_clerk_secret_key_here
# ❌ WRONG - Never commit secrets
const clerkSecret = "sk_test_abc123..." // DON'T DO THIS
Protect Sensitive Routes:
Secure API Routes:
// Always validate auth server-side
const { userId } = auth();
if (!userId) {
return new NextResponse('Unauthorized', { status: 401 });
}
Environment Variable Management:
.env.local for development (git-ignored).env.example with placeholders (safe to commit)Use App Router When:
Use Pages Router When:
Migration Path:
With Supabase:
With tRPC:
With Prisma:
With Vercel:
Middleware Not Running:
Sign-In Redirect Loop:
NEXT_PUBLIC_CLERK_SIGN_IN_URL matches routeServer Component Hydration:
Environment Variables Not Loading:
Plugin: clerk Version: 1.0.0 Category: Authentication Skill Type: Integration & Configuration