Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Advanced Clerk auth patterns for Next.js: Server Actions, middleware, caching, and App Router integration.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/server-actions.md
1# Server Actions23Server Actions are public endpoints. Always verify auth.45## Basic Protection67```typescript8'use server';9import { auth } from '@clerk/nextjs/server';1011export async function createPost(formData: FormData) {12const { isAuthenticated, userId } = await auth();13if (!isAuthenticated) throw new Error('Unauthorized');1415const title = formData.get('title') as string;16await db.posts.create({ data: { title, authorId: userId } });17revalidatePath('/posts');18}19```2021## Org + Role Check (B2B)2223```typescript24'use server';25import { auth } from '@clerk/nextjs/server';2627export async function createTeamProject(formData: FormData) {28const { userId, orgId, orgRole } = await auth();29if (!userId || !orgId) throw new Error('Must be in an organization');30if (orgRole !== 'org:admin') throw new Error('Only admins can create projects');3132const name = formData.get('name') as string;33await db.projects.create({ data: { name, organizationId: orgId } });34}35```3637## Permission Check (RBAC)3839```typescript40'use server';41import { auth } from '@clerk/nextjs/server';4243export async function deleteProject(projectId: string) {44const { userId, has } = await auth();45if (!userId) throw new Error('Unauthorized');4647const canDelete = await has({ permission: 'org:project:delete' });48if (!canDelete) throw new Error('Missing permission');4950await db.projects.delete({ where: { id: projectId } });51}52```5354> **Core 2 ONLY (skip if current SDK):** `isAuthenticated` is not available. Use `if (!userId)` instead.5556[Docs](https://clerk.com/docs/reference/nextjs/server-actions)57