clerk avatar

Clerk Nextjs Patterns

clerk/skills

This 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.

npx skills add https://github.com/clerk/skills --skill clerk-nextjs-patterns

Next.js Patterns

Version: Check package.json for the SDK version — see clerk skill for the version table. Core 2 differences are noted inline with > **Core 2 ONLY (skip if current SDK):** callouts. For basic setup, see setup/.

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 from auth():
  • isAuthenticated — boolean, replaces the !!userId pattern
  • sessionStatus'active' | 'pending', for detecting incomplete session tasks
  • userId, orgId, orgSlug, has(), protect() — unchanged

Core 2 ONLY (skip if current SDK): isAuthenticated and sessionStatus are not available. Check !!userId instead.

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): isAuthenticated is not available. Use if (!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>. See custom-ui/core-3/show-component.md for 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

Next.js SDK

GitHub Owner

Owner: clerk

More skills