
integrating-clerk-nextjs
by asvskartheek
SKILL.md
name: integrating-clerk-nextjs description: Integrates Clerk authentication into Next.js App Router applications following current best practices. Use when the user asks to "add Clerk", "integrate Clerk", "set up Clerk authentication", "add user authentication", or mentions Clerk setup in Next.js App Router projects. allowed-tools: Read, Write, Edit, Bash, Grep, Glob
Integrating Clerk with Next.js App Router
Enforces current and correct instructions for integrating Clerk into Next.js App Router applications.
Quick Start
For a typical integration:
- Install
@clerk/nextjs@latest - Set up environment variables in
.env.local - Create
middleware.tswithclerkMiddleware() - Wrap app with
<ClerkProvider>inapp/layout.tsx - Add Clerk components (
<SignInButton>,<UserButton>, etc.)
Complete Integration Workflow
Step 1: Install Clerk SDK
npm install @clerk/nextjs
Step 2: Configure Environment Variables
Action: Create or update .env.local with Clerk API keys.
CRITICAL:
- NEVER write actual keys to tracked files
- ONLY use placeholder values in code examples
- Verify
.gitignoreexcludes.env*files
# .env.local
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=YOUR_PUBLISHABLE_KEY
CLERK_SECRET_KEY=YOUR_SECRET_KEY
Get keys from: Clerk Dashboard → API Keys
Step 3: Create Middleware
File: middleware.ts (at project root, or in src/ if using src directory)
// middleware.ts
import { clerkMiddleware } from "@clerk/nextjs/server";
export default clerkMiddleware();
export const config = {
matcher: [
// Skip Next.js internals and all static files, unless found in search params
"/((?!_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)(.*)",
],
};
CRITICAL: Use clerkMiddleware() from @clerk/nextjs/server - NOT authMiddleware() (deprecated).
Step 4: Wrap App with ClerkProvider
File: app/layout.tsx
Before editing:
- Read the existing
app/layout.tsxfile - Identify the current structure
- Preserve existing imports and metadata
Add these imports:
import {
ClerkProvider,
SignInButton,
SignUpButton,
SignedIn,
SignedOut,
UserButton,
} from "@clerk/nextjs";
Wrap the app:
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<ClerkProvider>
<html lang="en">
<body>
<header>
<SignedOut>
<SignInButton />
<SignUpButton />
</SignedOut>
<SignedIn>
<UserButton />
</SignedIn>
</header>
{children}
</body>
</html>
</ClerkProvider>
);
}
Step 5: Verify Implementation
Run through this checklist before completing:
- Middleware:
clerkMiddleware()used inmiddleware.ts - Layout:
<ClerkProvider>wraps app inapp/layout.tsx - Imports: References from
@clerk/nextjsor@clerk/nextjs/server - App Router: Using
app/directory (notpages/or_app.tsx) - Environment Variables: Only placeholders in code, actual keys in
.env.local - File Security:
.env*in.gitignore
Step 6: Test the Integration
npm run dev
Navigate to the app and verify:
- Sign-in/sign-up buttons appear for unauthenticated users
- User button appears for authenticated users
- Authentication flow works end-to-end
Server-Side Authentication
When accessing authentication data in Server Components or API routes:
import { auth } from "@clerk/nextjs/server";
export default async function Page() {
const { userId } = await auth();
if (!userId) {
return <div>Not authenticated</div>;
}
return <div>User ID: {userId}</div>;
}
CRITICAL:
- Import
authfrom@clerk/nextjs/server - Always use
await auth()(it's async)
Protected Routes
To protect specific routes, update middleware.ts:
import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";
const isProtectedRoute = createRouteMatcher([
'/dashboard(.*)',
'/profile(.*)',
]);
export default clerkMiddleware(async (auth, req) => {
if (isProtectedRoute(req)) {
await auth.protect();
}
});
export const config = {
matcher: [
"/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)",
"/(api|trpc)(.*)",
],
};
CRITICAL: What NOT to Do
NEVER do the following:
- ❌ Use
authMiddleware()- it's deprecated, useclerkMiddleware() - ❌ Reference
_app.tsxorpages/directory for Clerk setup - ❌ Import from deprecated APIs (
withAuth, oldcurrentUser) - ❌ Write actual API keys to tracked files
- ❌ Use sync
auth()- it's async, always useawait auth() - ❌ Forget to wrap with
<ClerkProvider>in layout
See reference/outdated-patterns.md for detailed examples of deprecated approaches.
Troubleshooting
Issue: "clerkMiddleware is not a function"
- Cause: Using old version of
@clerk/nextjs - Fix: Run
npm install @clerk/nextjs@latest
Issue: Authentication not working
- Check: Is
middleware.tsat the root (or insrc/if using src directory)? - Check: Are environment variables set correctly in
.env.local? - Check: Is the app wrapped with
<ClerkProvider>?
Issue: TypeScript errors with auth()
- Cause: Not awaiting async
auth()function - Fix: Change
const { userId } = auth()toconst { userId } = await auth()
Best Practices
- Environment Variables: Always use
.env.localfor local development - Type Safety: Use TypeScript for better autocomplete and type checking
- Protected Routes: Use
createRouteMatcherfor route-based protection - Server Components: Leverage
auth()for server-side authentication checks - Error Handling: Wrap authentication calls in try-catch for production apps
Additional Resources
Example Implementation
Here's a complete minimal example:
middleware.ts:
import { clerkMiddleware } from "@clerk/nextjs/server";
export default clerkMiddleware();
export const config = {
matcher: [
"/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)",
"/(api|trpc)(.*)",
],
};
app/layout.tsx:
import { ClerkProvider, SignInButton, SignedIn, SignedOut, UserButton } from "@clerk/nextjs";
import "./globals.css";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<ClerkProvider>
<html lang="en">
<body>
<header>
<SignedOut>
<SignInButton />
</SignedOut>
<SignedIn>
<UserButton />
</SignedIn>
</header>
<main>{children}</main>
</body>
</html>
</ClerkProvider>
);
}
app/page.tsx:
import { auth } from "@clerk/nextjs/server";
export default async function Home() {
const { userId } = await auth();
return (
<div>
<h1>Welcome {userId ? "back" : "to our app"}!</h1>
</div>
);
}
.env.local:
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...
スコア
総合スコア
リポジトリの品質指標に基づく評価
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
レビュー
レビュー機能は近日公開予定です