clerk-orgs

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Organizations (B2B SaaS)

Organizations(面向B2B SaaS)

Prerequisite: Enable Organizations in Clerk Dashboard first.
前提条件:首先在Clerk控制台中启用Organizations功能。

Quick Start

快速开始

  1. Create an organization via dashboard or through Clerk API
  2. Use OrganizationSwitcher to let users switch between orgs
  3. Protect routes using orgSlug from URL and role checks
  1. 通过控制台或Clerk API创建组织
  2. 使用OrganizationSwitcher组件让用户在不同组织间切换
  3. 使用URL中的orgSlug和角色检查来保护路由

Documentation Reference

文档参考

Key Patterns

核心模式

1. Get Organization from Auth

1. 从Auth获取组织信息

Server-side access to organization:
typescript
import { auth } from '@clerk/nextjs/server'

const { orgId, orgSlug } = await auth()
console.log(`Current org: ${orgSlug}`)
服务端获取组织信息:
typescript
import { auth } from '@clerk/nextjs/server'

const { orgId, orgSlug } = await auth()
console.log(`Current org: ${orgSlug}`)

2. Dynamic Routes with Org Slug

2. 带组织Slug的动态路由

Create routes that accept org slug:
app/orgs/[slug]/page.tsx
app/orgs/[slug]/settings/page.tsx
Access the slug:
typescript
export default function DashboardPage({ params }: { params: { slug: string } }) {
  return <div>Organization: {params.slug}</div>
}
创建支持组织Slug的路由:
app/orgs/[slug]/page.tsx
app/orgs/[slug]/settings/page.tsx
获取Slug:
typescript
export default function DashboardPage({ params }: { params: { slug: string } }) {
  return <div>Organization: {params.slug}</div>
}

3. Check Organization Membership

3. 检查组织成员身份

Verify user has access to specific org:
typescript
import { auth } from '@clerk/nextjs/server'

export default async function ProtectedPage() {
  const { orgId, orgSlug } = await auth()

  if (!orgId) {
    return <div>Not in an organization</div>
  }

  return <div>Welcome to {orgSlug}</div>
}
验证用户是否有权限访问特定组织:
typescript
import { auth } from '@clerk/nextjs/server'

export default async function ProtectedPage() {
  const { orgId, orgSlug } = await auth()

  if (!orgId) {
    return <div>未加入任何组织</div>
  }

  return <div>欢迎访问{orgSlug}</div>
}

4. Role-Based Access Control

4. 基于角色的访问控制

Check if user has specific role:
typescript
const { has } = await auth()

if (!has({ role: 'org:admin' })) {
  return <div>Admin access required</div>
}
检查用户是否拥有特定角色:
typescript
const { has } = await auth()

if (!has({ role: 'org:admin' })) {
  return <div>需要管理员权限</div>
}

5. OrganizationSwitcher Component

5. OrganizationSwitcher组件

Let users switch between organizations:
typescript
import { OrganizationSwitcher } from '@clerk/nextjs'

export default function Nav() {
  return (
    <header>
      <h1>Dashboard</h1>
      <OrganizationSwitcher />
    </header>
  )
}
让用户在不同组织间切换:
typescript
import { OrganizationSwitcher } from '@clerk/nextjs'

export default function Nav() {
  return (
    <header>
      <h1>控制台</h1>
      <OrganizationSwitcher />
    </header>
  )
}

Default Roles

默认角色

All new members get assigned a role:
RolePermissions
org:admin
Full access, manage members, settings
org:member
Limited access, read-only
Custom roles can be created in the dashboard.
所有新成员都会被分配一个角色:
角色权限
org:admin
完全访问权限,可管理成员和设置
org:member
有限访问权限,只读
可在控制台中创建自定义角色。

Default Permissions

默认权限

PermissionRole
org:create
Can create new organizations
org:manage_members
Can invite/remove members (default: admin)
org:manage_roles
Can change member roles (default: admin)
org:update_metadata
Can update org metadata (default: admin)
权限对应角色
org:create
可创建新组织
org:manage_members
可邀请/移除成员(默认:管理员)
org:manage_roles
可修改成员角色(默认:管理员)
org:update_metadata
可更新组织元数据(默认:管理员)

Authorization Pattern

授权模式

Complete example protecting a route:
typescript
import { auth } from '@clerk/nextjs/server'
import { redirect } from 'next/navigation'

export default async function AdminPage({ params }: { params: { slug: string } }) {
  const { orgSlug, has } = await auth()

  // Verify user is in the org
  if (orgSlug !== params.slug) {
    redirect('/dashboard')
  }

  // Check if admin
  if (!has({ role: 'org:admin' })) {
    redirect(`/orgs/${orgSlug}`)
  }

  return <div>Admin settings for {orgSlug}</div>
}
保护路由的完整示例:
typescript
import { auth } from '@clerk/nextjs/server'
import { redirect } from 'next/navigation'

export default async function AdminPage({ params }: { params: { slug: string } }) {
  const { orgSlug, has } = await auth()

  // 验证用户是否属于当前组织
  if (orgSlug !== params.slug) {
    redirect('/dashboard')
  }

  // 检查是否为管理员
  if (!has({ role: 'org:admin' })) {
    redirect(`/orgs/${orgSlug}`)
  }

  return <div>{orgSlug}的管理员设置</div>
}

Common Pitfalls

常见问题

SymptomCauseSolution
orgSlug
is undefined
Not calling
await auth()
Use
const { orgSlug } = await auth()
Role check always failsNot awaiting
auth()
Add
await
before
auth()
Users can access other orgsNot checking orgSlug matches URLVerify
orgSlug === params.slug
Org not appearing in switcherOrganizations not enabledEnable in Clerk Dashboard → Organizations
Invitations not workingWrong role configurationEnsure members have invite role permissions
现象原因解决方案
orgSlug
未定义
未调用
await auth()
使用
const { orgSlug } = await auth()
角色检查始终失败未在调用
auth()
时添加
await
auth()
前添加
await
用户可访问其他组织未检查orgSlug是否与URL匹配验证
orgSlug === params.slug
组织未出现在切换器中未启用Organizations功能在Clerk控制台→Organizations中启用
邀请功能无法使用角色配置错误确保成员拥有邀请权限对应的角色

Workflow

工作流程

  1. Setup - Enable Organizations in Clerk Dashboard
  2. Create org - Users create org or admin creates via API
  3. Add members - Send invitations or add directly
  4. Assign roles - Default member role, promote to admin as needed
  5. Build protected routes - Use auth() to check orgSlug and roles
  6. Use OrganizationSwitcher - Let users switch between orgs
  1. 设置 - 在Clerk控制台中启用Organizations功能
  2. 创建组织 - 用户自行创建组织,或管理员通过API创建
  3. 添加成员 - 发送邀请或直接添加
  4. 分配角色 - 默认分配成员角色,按需提升为管理员
  5. 构建受保护路由 - 使用auth()检查orgSlug和角色
  6. 使用OrganizationSwitcher - 让用户在不同组织间切换