clerk-nextjs-patterns

Implement Clerk authentication patterns for Next.js middleware, Server Actions, API routes, and caching.

Updated Apr 19, 2026
One-click install
npx skills add https://github.com/divinaarmuela/Content --skill clerk-nextjs-patterns-divinaarmuela
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: clerk-nextjs-patterns
Source: https://github.com/divinaarmuela/Content/tree/main/.claude/skills/clerk-nextjs-patterns
Command: npx skills add https://github.com/divinaarmuela/Content --skill clerk-nextjs-patterns-divinaarmuela

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill requires @clerk/nextjs, @clerk/backend, jsonwebtoken, next, react, and includes references (resource) components.

What problem does it solve? Securing a Next.js application with Clerk involves many distinct patterns—middleware route protection, Server Action authorization, API route 401/403 handling, user-scoped caching, and JWT verification—and getting any of them wrong creates security holes or confusing bugs like undefined userId or cross-user cache leaks. ## Core Features & Use Cases - Server vs Client Auth Guidance: Explains when to use await auth() from @clerk/nextjs/server versus client hooks like useAuth() and useUser(), including the <Show> component for conditional rendering. - Middleware Strategies: Provides public-first and protected-first clerkMiddleware configurations with createRouteMatcher, permission-gated routes, token-based protection, and session task handling. - Server Actions, API Routes & Caching: Shows how to protect mutations, return correct 401 vs 403 status codes, and build user-scoped unstable_cache keys that prevent data leaking between users. - JWT & Session Tokens: Covers getToken() with JWT templates for third-party APIs like Hasura and Supabase, plus manual JWT verification with @clerk/backend or jsonwebtoken for standalone servers. - Use Case: You need to protect all routes under /dashboard, secure a Server Action that creates posts, and call an external GraphQL API with a custom Clerk JWT—this Skill provides the exact patterns for each. ## Quick Start Ask the AI to protect your Next.js dashboard routes with Clerk middleware and convert a client component using useUser into a server component using await auth().

Frequently Asked Questions about clerk-nextjs-patterns

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I protect Next.js routes with Clerk middleware?

Use clerkMiddleware with createRouteMatcher from @clerk/nextjs/server to define public or protected route patterns, then call auth.protect() for matched routes. Choose public-first for marketing sites or protected-first for internal tools and dashboards.

How do I use auth() in Next.js Server Components with Clerk?

Import auth from @clerk/nextjs/server and always call it with await, since it is asynchronous. Destructure isAuthenticated and userId from the result, and return a sign-in prompt when the user is not authenticated.

What is the difference between auth() and useAuth() in Clerk Next.js?

auth() is an async server-side function from @clerk/nextjs/server used in Server Components, while useAuth() is a synchronous React hook from @clerk/nextjs for Client Components. Never mix them across the server-client boundary.

Why does my Next.js cache return another user's data with Clerk?

The cache key is missing the userId, so unstable_cache serves shared data across users. Include userId or orgId in the cache key and revalidation tags, then call revalidateTag after mutations to refresh the correct user's data.

How do I verify a Clerk JWT without middleware on a standalone server?

Extract the Bearer token from the Authorization header and verify it with verifyToken from @clerk/backend using CLERK_JWT_KEY, or use jsonwebtoken with CLERK_PEM_PUBLIC_KEY and RS256. Always check exp and nbf claims and return 401 for invalid tokens.

When should an API route return 401 versus 403 with Clerk?

Return 401 when the request is not authenticated, meaning no valid session exists. Return 403 when the user is authenticated but lacks the required role or permission, checked with the has() function from auth().