All Skills
Clerk

clerk-nextjs-patterns

Secure & Comply

Advanced Next.js patterns - middleware, Server Actions, caching with Clerk.

clerk/skills·4.9K installs
next-js
C
$npx skills add 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

ReferenceImpact
references/server-vs-client.mdCRITICAL - await auth() vs hooks
references/middleware-strategies.mdHIGH - Public-first vs protected-first, proxy.ts (Next.js <=15: middleware.ts)
references/server-actions.mdHIGH - Protect mutations
references/api-routes.mdHIGH - 401 vs 403
references/caching-auth.mdMEDIUM - 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

SymptomCauseFix
undefined userId in Server ComponentMissing awaitawait auth() not auth()
Auth not working on API routesMissing matcherAdd `'/(api
Cache returns wrong user's dataMissing userId in keyInclude userId in unstable_cache key
Mutations bypass authUnprotected Server ActionCheck auth() at start of action
Wrong HTTP error codeConfused 401/403401 = not signed in, 403 = no permission

See Also

  • setup/
  • orgs/

Docs

Next.js SDK