Auth & Data
Use when adding Clerk authentication to a Next.js App Router app, protecting routes behind sign-in, or reading the signed-in user in server code. Also use when auth() throws in a route handler, a protected route lets an unauthenticated request through, or the provider and middleware disagree about which routes are public. If a request needs to know who the user is, use this skill.
1 file
Description
Use when adding Clerk authentication to a Next.js App Router app, protecting routes behind sign-in, or reading the signed-in user in server code. Also use when auth() throws in a route handler, a protected route lets an unauthenticated request through, or the provider and middleware disagree about which routes are public. If a request needs to know who the user is, use this skill.
Adding sign in, gating a route or API behind auth, or fixing a 500 that traces back to auth() in a server context.
Install: pnpm add @clerk/nextjs.
Put keys in .env.local only, never in code:
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_...
CLERK_SECRET_KEY=sk_...
Wrap the root layout:
import { ClerkProvider } from "@clerk/nextjs";
export default function RootLayout({ children }) {
return <ClerkProvider><html><body>{children}</body></html></ClerkProvider>;
}
Add middleware.ts using clerkMiddleware() (not the retired authMiddleware):
import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";
const isProtected = createRouteMatcher(["/dashboard(.*)", "/api/private(.*)"]);
export default clerkMiddleware(async (auth, req) => {
if (isProtected(req)) await auth.protect();
});
export const config = { matcher: ["/((?!_next|.*\\..*).*)", "/(api|trpc)(.*)"] };
auth() from @clerk/nextjs/server is async: const { userId } = await auth();.
clerkMiddleware() for some environments (for example dev, when keys are domain-locked to production), auth() throws instead of returning null. Wrap server reads in a helper that returns null when Clerk is not active, and call that helper from API routes.auth.protect() in middleware redirects browser requests but returns 404 for API routes. For APIs, read userId and return your own 401.auth() in a client component. Use useAuth() / useUser() there.Related
Added 2026-07-01. Back to the Skill Library.

New tutorials, open-source projects, and deep dives on coding agents - delivered weekly.