| name | clerk-sdk-patterns |
| description | Common Clerk SDK patterns and best practices.
Use when implementing authentication flows, accessing user data,
or integrating Clerk SDK methods in your application.
Trigger with phrases like "clerk SDK", "clerk patterns",
"clerk best practices", "clerk API usage".
|
| allowed-tools | Read, Write, Edit, Grep |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
Clerk SDK Patterns
Overview
Learn common patterns and best practices for using the Clerk SDK effectively.
Prerequisites
- Clerk SDK installed and configured
- Basic understanding of React/Next.js
- ClerkProvider wrapping application
Instructions
Pattern 1: Server-Side Authentication
import { auth, currentUser } from '@clerk/nextjs/server'
export async function GET() {
const { userId, sessionId, orgId } = await auth()
if (!userId) {
return Response.json({ error: 'Unauthorized' }, { status: 401 })
}
const user = await currentUser()
return Response.json({
userId,
sessionId,
orgId,
email: user?.primaryEmailAddress?.emailAddress
})
}
Pattern 2: Client-Side Hooks
'use client'
import { useUser, useAuth, useClerk, useSession } from '@clerk/nextjs'
export function AuthenticatedComponent() {
const { user, isLoaded, isSignedIn } = useUser()
const { userId, getToken, signOut } = useAuth()
const clerk = useClerk()
const { session } = useSession()
const callExternalAPI = async () => {
const token = await getToken({ template: 'supabase' })
const res = await fetch('https://api.example.com', {
headers: { Authorization: `Bearer ${token}` }
})
}
if (!isLoaded) return <div>Loading...</div>
if (!isSignedIn) return <div>Please sign in
}
Pattern 3: Protected Routes with Middleware
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server'
const isPublicRoute = createRouteMatcher([
'/',
'/sign-in(.*)',
'/sign-up(.*)',
'/api/webhooks(.*)'
])
const isProtectedRoute = createRouteMatcher([
'/dashboard(.*)',
'/api/protected(.*)'
])
export default clerkMiddleware(async (auth, request) => {
if (isProtectedRoute(request)) {
await auth.protect()
}
})
export const config = {
matcher: ['/((?!.*\\..*|_next).*)', '/', '/(api|trpc)(.*)']
}
Pattern 4: Organization-Aware Queries
import { auth } from '@clerk/nextjs/server'
export async function GET() {
const { userId, orgId, orgRole } = await auth()
if (!orgId) {
return Response.json({ error: 'No organization selected' }, { status: 400 })
}
if (orgRole !== 'org:admin') {
return Response.json({ error: 'Admin access required' }, { status: 403 })
}
const data = await db.query.resources.findMany({
where: eq(resources.organizationId, orgId)
})
return Response.json(data)
}
Pattern 5: Custom JWT Templates
const { getToken } = useAuth()
const clerkToken = await getToken()
const supabaseToken = await getToken({ template: 'supabase' })
const hasuraToken = await getToken({ template: 'hasura' })
Output
- Server and client authentication patterns
- Protected route middleware
- Organization-aware queries
- Custom JWT tokens for integrations
Error Handling
| Error | Cause | Solution |
|---|
| auth() returns null | Not in server context | Use in Server Components or API routes |
| useUser() not updating | Component not re-rendering | Check ClerkProvider placement |
| getToken() fails | Template not configured | Configure JWT template in dashboard |
| orgId is null | No organization selected | Prompt user to select organization |
Examples
Complete Protected Page Pattern
import { auth, currentUser } from '@clerk/nextjs/server'
import { redirect } from 'next/navigation'
export default async function DashboardPage() {
const { userId } = await auth()
if (!userId) {
redirect('/sign-in')
}
const user = await currentUser()
return (
<main>
<h1>Dashboard</h1>
<UserProfile user={user} />
<DashboardContent userId={userId} />
</main>
)
}
Typed User Metadata
interface UserPublicMetadata {
tier: 'free' | 'pro' | 'enterprise'
onboarded: boolean
}
interface UserPrivateMetadata {
stripeCustomerId?: string
}
const user = await currentUser()
const tier = user?.publicMetadata?.tier ?? 'free'
Resources
Next Steps
Proceed to clerk-core-workflow-a for user sign-up and sign-in flows.