Clerk Nextjs Patterns
clerk/skillsThis skill provides advanced Next.js authentication patterns using Clerk, enabling developers to implement secure server and client-side auth, session management, and conditional rendering in Next.js applications. It offers key capabilities such as server components authentication with `auth()`, client-side hooks, and handling common pitfalls, making it suitable for developers building complex or scalable Next.js projects with Clerk integration. The skill also includes best practices, pattern examples, and migration guides for Clerk SDK versions, supporting effective and secure auth workflows.
Next.js Patterns
Version: Check
package.jsonfor the SDK version — seeclerkskill for the version table. Core 2 differences are noted inline with> **Core 2 ONLY (skip if current SDK):**callouts. For basic setup, seesetup/.
Impact Levels
- CRITICAL - Breaking bugs, security holes
- HIGH - Common mistakes
- MEDIUM - Optimization
References
Reference
Impact
references/server-vs-client.md
CRITICAL - await auth() vs hooks
references/middleware-strategies.md
HIGH - Public-first vs protected-first, proxy.ts (Next.js <=15: middleware.ts)
references/server-actions.md
HIGH - Protect mutations
references/api-routes.md
HIGH - 401 vs 403
references/caching-auth.md
MEDIUM - User-scoped caching
Mental Model
Server vs Client = different auth APIs:
- Server:
await auth()from@clerk/nextjs/server(async!) - Client:
useAuth()hook from@clerk/nextjs(sync) Never mix them. Server Components use server imports, Client Components use hooks. Key properties fromauth(): isAuthenticated— boolean, replaces the!!userIdpatternsessionStatus—'active'|'pending', for detecting incomplete session tasksuserId,orgId,orgSlug,has(),protect()— unchanged
Core 2 ONLY (skip if current SDK):
isAuthenticatedandsessionStatusare not available. Check!!userIdinstead.
Minimal Pattern
// Server Component
import { auth } from '@clerk/nextjs/server'
export default async function Page() {
const { isAuthenticated, userId } = await auth() // MUST await!
if (!isAuthenticated) return <p>Not signed in</p>
return <p>Hello {userId}</p>
}
Core 2 ONLY (skip if current SDK):
isAuthenticatedis not available. Useif (!userId)instead.
Conditional Rendering with <Show>
For client-side conditional rendering based on auth state:
import { Show } from '@clerk/nextjs'
<Show when="signed-in" fallback={<p>Please sign in</p>}>
<Dashboard />
</Show>
Core 2 ONLY (skip if current SDK): Use
<SignedIn>and<SignedOut>components instead of<Show>. Seecustom-ui/core-3/show-component.mdfor the full migration table.
Common Pitfalls
Symptom
Cause
Fix
undefined userId in Server Component
Missing await
await auth() not auth()
Auth not working on API routes
Missing matcher
Add `'/(api
Cache returns wrong user's data
Missing userId in key
Include userId in unstable_cache key
Mutations bypass auth
Unprotected Server Action
Check auth() at start of action
Wrong HTTP error code
Confused 401/403
401 = not signed in, 403 = no permission
See Also
setup/orgs/
Docs
GitHub Owner
Owner: clerk
GitHub Links
- Website: https://clerk.com
- Twitter: https://twitter.com/ClerkDev
- Email: hello@clerk.com
- Verified domains:
clerk,clerk.com