// 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.
| name | nextjs-integration |
| description | 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. |
| allowed-tools | Bash, Read, Write, Edit, WebFetch |
This 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