Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Create your first authenticated request with Clerk. Use when making initial API calls, testing authentication, or verifying Clerk integration works correctly. Trigger with phrases like "clerk hello world", "first clerk request", "test clerk auth", "verify clerk setup".
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 114% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 215% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 154% | 0% |
| case-21 | ✓→✗ | ▼ Worse | 60% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 105% | 0% |
Make your first authenticated requests using Clerk across server components, client components, API routes, and server actions. Validates your Clerk integration end-to-end.
clerk-install-auth completed)NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, CLERK_SECRET_KEY)typescript// app/dashboard/page.tsx import { auth, currentUser } from '@clerk/nextjs/server' import { redirect } from 'next/navigation' export default async function DashboardPage() { // auth() is lightweight — reads JWT from the session cookie, no API call const { userId } = await auth() if (!userId) redirect('/sign-in') // currentUser() makes a Backend API call — use sparingly, counts toward rate limit const user = await currentUser() return ( <div> <h1>Hello, {user?.firstName || 'User'}!</h1> <p>User ID: {userId}</p> <p>Email: {user?.emailAddresses[0]?.emailAddress}</p> <p>Created: {user?.createdAt ? new Date(user.createdAt).toLocaleDateString() : 'N/A'}</p> </div> ) }
Key distinction: auth() is cheap (JWT parsing, no network). currentUser() is expensive (Backend API call, rate-limited). Prefer auth() when you only need userId, orgId, or sessionClaims.
typescript// app/api/hello/route.ts import { auth } from '@clerk/nextjs/server' export async function GET() { const { userId, orgId, sessionClaims } = await auth() if (!userId) { return Response.json({ error: 'Unauthorized' }, { status: 401 }) } return Response.json({ message: 'Hello from Clerk!', userId, orgId: orgId || null, sessionId: sessionClaims?.sid, timestamp: new Date().toISOString(), }) }
typescript'use client' import { useUser, useAuth, useClerk } from '@clerk/nextjs' export function AuthTest() { const { user, isLoaded, isSignedIn } = useUser() const { getToken, signOut } = useAuth() const { openUserProfile } = useClerk() if (!isLoaded) return <div>Loading...</div> if (!isSignedIn) return <div>Not signed in</div> const testAPI = async () => { // getToken() returns the session JWT — use for calling your own API routes // or external services with Bearer token auth const token = await getToken() const res = await fetch('/api/hello', { headers: { Authorization: `Bearer ${token}` }, }) const data = await res.json() console.log('API response:', data) } return ( <div> <p>Signed in as: {user.primaryEmailAddress?.emailAddress}</p> <img src={user.imageUrl} alt="Avatar" width={48} height={48} /> <div className="flex gap-2 mt-4"> <button onClick={testAPI}>Test API</button> <button onClick={() => openUserProfile()}>Profile</button> <button onClick={() => signOut()}>Sign Out</button> </div> </div> ) }
typescript// app/actions.ts 'use server' import { auth } from '@clerk/nextjs/server' export async function greetUser() { const { userId } = await auth() if (!userId) throw new Error('Unauthorized') // Perform server-side work here (DB queries, external API calls, etc.) return { greeting: `Hello user ${userId}!`, timestamp: new Date().toISOString() } }
typescript// app/dashboard/greeting.tsx 'use client' import { greetUser } from '@/app/actions' import { useState } from 'react' export function GreetingButton() { const [msg, setMsg] = useState<string | null>(null) return ( <div> <button onClick={async () => { const result = await greetUser() setMsg(result.greeting) }}> Get Server Greeting </button> {msg && <p>{msg}</p>} </div> ) }
typescriptimport express from 'express' import { clerkMiddleware, requireAuth, getAuth } from '@clerk/express' const app = express() app.use(clerkMiddleware()) // Public endpoint app.get('/api/hello', (req, res) => { const { userId } = getAuth(req) res.json({ message: userId ? `Hello user ${userId}!` : 'Hello anonymous!', authenticated: !!userId, }) }) // Protected endpoint — returns 403 if no valid session app.get('/api/me', requireAuth(), (req, res) => { const { userId, orgId } = getAuth(req) res.json({ userId, orgId }) }) app.listen(3001)
| Error | Cause | Solution | |-------|-------|----------| | userId is null | User not authenticated | Redirect to /sign-in or check middleware covers route | | currentUser() returns null | Session expired or invalid | Refresh page; ensure middleware is running | | 401 from API route | Token missing or expired | Include Authorization: Bearer <token> header | | Hydration mismatch | Server/client state differs | Guard client components with isLoaded check | | auth() was called but Clerk can't detect clerkMiddleware() | Middleware not in project root | Move middleware.ts out of app/ to project root |
auth() over currentUser() in hot paths to avoid Backend API rate limitscurrentUser() calls with React's cache() function across server components in the same request@clerk/backend or @clerk/expressProceed to clerk-local-dev-loop for local development workflow setup.
User: Smallest possible Clerk + Next.js demo with a protected /me page.
Skill: scaffolds packages, middleware, sign-in UI, and /me reading user id.User: Confirm publishable + secret keys work against Clerk API.
Skill: runs a minimal session/user fetch and reports success or key-mismatch errors.Other measured skills in the registry, with their headline benchmark lift.