Skip to main content
Docs

Organizations quickstart

Organizations let you group users with roles and permissions, enabling you to build multi-tenant B2B apps like Slack (workspaces), Linear (teams), or Vercel (projects) where users can switch between different team contexts.

Enable organizations

Organizations are disabled by default. To enable them:

  1. In the Clerk Dashboard, navigate to the Organizations Settings page.
  2. Select Enable Organizations.
  3. In the modal, choose whether to allow personal accounts:
    • Personal accounts disabled (default): Every user must belong to an organization. This is recommended for most B2B applications.
    • Personal accounts enabled: Users can operate in their own individual workspace or join organizations.
  4. Select Enable.

Learn more about configuring organizations in the dedicated guide.

Add the <OrganizationSwitcher /> component

The <OrganizationSwitcher /> component is the easiest way to let users create, switch between, and manage organizations. It's recommended to place it in your app's header or navigation so it's always accessible. For example:

components/Header.tsx
export default function Header() {
  return (
    <header>
      <OrganizationSwitcher />
    </header>
  )
}

Use Clerk's hooks to access the current organization and role within your components:

  • The useOrganization() hook is used to access information about the currently active organization.
  • The useOrganizationList() hook is used to access information about the current user's organization memberships.
export default function Page() {
  const { organization } = useOrganization()
  const { userMemberships } = useOrganizationList({
    userMemberships: true,
  })

  return (
    <div className="p-8">
      <h1 className="text-2xl font-bold mb-4">
        Welcome to the <strong>{organization?.name}</strong> organization
      </h1>
      <p className="mb-6">
        Your role in this organization:{' '}
        <strong>
          {/* Find the organization membership that matches the
            currently active organization and return the role */}
          {
            userMemberships?.data?.find(
              (membership) => membership.organization.id === organization?.id,
            )?.role
          }
        </strong>
      </p>
    </div>
  )
}

Clerk's JS Backend SDKClerk Icon provides methods for accessing organization data server-side. For example, to get information about an organization, you can use the getOrganization()Clerk Icon method. It requires the organization ID, which can be accessed through the AuthClerk Icon object.

This example is written for Next.js App Router, but can be adapted to other frameworks by using the appropriate method for accessing the Auth objectClerk Icon, and the appropriate initialization for clerkClient()Clerk Icon.

import { auth, clerkClient } from '@clerk/nextjs/server'
import { OrganizationSwitcher } from '@clerk/nextjs'

export default async function Page() {
  // The `Auth` object gives you access to properties like `orgId`
  // Accessing the `Auth` object differs depending on the SDK you're using
  // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object
  const { orgId } = await auth()

  // Check if there is an active organization
  if (!orgId) {
    return (
      <>
        <p>Set an active organization to access this page.</p>
        <OrganizationSwitcher />
      </>
    )
  }

  // To fetch the active organization server-side,
  // first initialize the JS Backend SDK.
  // This varies depending on the SDK you're using
  // https://clerk.com/docs/js-backend/getting-started/quickstart
  // Then use the `clerkClient()` to access the `getOrganization()` method
  const client = await clerkClient()
  const organization = await client.organizations.getOrganization({ organizationId: orgId })

  return <p>Hello {organization.name}</p>
}

You can protect content and even entire routes based on organization membership, roles, and permissions by performing .

In the following example, the page is restricted to authenticated users, users who have the org:admin role, and users who belong to the Acme Corp organization.

  • The AuthClerk Icon object is used to access the isSignedIn property and has() method.
  • The isSignedIn property is used to check if the user is signed in.
  • The has() method is used to check if the user has the org:admin role.
  • The useOrganization() hook is used to access the organization data.
  • The organization name is checked to ensure it matches the required organization name. If a user is not in the required organization, the page will display a message and the <OrganizationSwitcher /> component will be rendered to allow the user to switch to the required organization.
app/protected/page.tsx
'use client'
import { OrganizationSwitcher, useAuth, useOrganization } from '@clerk/nextjs'

export default function Page() {
  // The `useAuth()` hook gives you access to properties like `isSignedIn` and `has()`
  const { isSignedIn, has } = useAuth()
  const { organization } = useOrganization()

  // Check if the user is authenticated
  if (!isSignedIn) {
    return <p>You must be signed in to access this page.</p>
  }

  // Check if there is an active organization
  if (!organization) {
    return (
      <>
        <p>Set an active organization to access this page.</p>
        <OrganizationSwitcher />
      </>
    )
  }

  // Check if the user has the `org:admin` role
  if (!has({ role: 'org:admin' })) {
    return <p>You must be an admin to access this page.</p>
  }

  // Check if organization name matches (e.g., "Acme Corp")
  const requiredOrgName = 'Acme Corp'
  if (organization.name !== requiredOrgName) {
    return (
      <>
        <p>
          This page is only accessible in the <strong>{requiredOrgName}</strong> organization.
          Switch to the <strong>{requiredOrgName}</strong> organization to access this page.
        </p>
        <OrganizationSwitcher />
      </>
    )
  }

  return (
    <p>
      You are currently signed in as an <strong>admin</strong> in the{' '}
      <strong>{organization.name}</strong> organization.
    </p>
  )
}

For more examples on how to perform authorization checks, see the dedicated guide.

You can protect content and even entire routes based on organization membership, roles, and permissions by performing .

In the following example, the page is restricted to authenticated users, users who have the org:admin role, and users who belong to the Acme Corp organization.

  • The AuthClerk Icon object is used to access the isAuthenticated and orgId properties, as well as the has() method.
  • The isAuthenticated property is used to check if the user is authenticated.
  • The orgId property is used to check if there is an active organization.
  • The has() method is used to check if the user has the org:admin role.
  • To fetch the organization server-side, the clerkClient()Next.js Icon helper is used to access the getOrganization()Clerk Icon method.
  • The organization name is checked to ensure it matches the required organization name. If a user is not in the required organization, the page will display a message and the <OrganizationSwitcher /> component will be rendered to allow the user to switch to the required organization.

This example is written for Next.js App Router, but can be adapted to other frameworks by using the appropriate method for accessing the Auth objectClerk Icon, and the appropriate initialization for clerkClient().

app/protected/page.tsx
import { auth, clerkClient } from '@clerk/nextjs/server'
import { OrganizationSwitcher } from '@clerk/nextjs'

export default async function Page() {
  // The `Auth` object gives you access to properties like `isAuthenticated` and `userId`
  // Accessing the `Auth` object differs depending on the SDK you're using
  // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object
  const { isAuthenticated, orgId, has } = await auth()

  // Check if the user is authenticated
  if (!isAuthenticated) {
    return <p>You must be signed in to access this page.</p>
  }

  // Check if there is an active organization
  if (!orgId) {
    return (
      <>
        <p>Set an active organization to access this page.</p>
        <OrganizationSwitcher />
      </>
    )
  }

  // Check if the user has the `org:admin` role
  if (!has({ role: 'org:admin' })) {
    return <p>You must be an admin to access this page.</p>
  }

  // To fetch the active organization server-side,
  // first initialize the JS Backend SDK.
  // This varies depending on the SDK you're using
  // https://clerk.com/docs/js-backend/getting-started/quickstart
  // Then use the `clerkClient()` to access the `getOrganization()` method
  const client = await clerkClient()
  const organization = await client.organizations.getOrganization({ organizationId: orgId })

  // Check if organization name matches (e.g., "Acme Corp")
  const requiredOrgName = 'Acme Corp'
  if (organization.name !== requiredOrgName) {
    return (
      <>
        <p>
          This page is only accessible in the <strong>{requiredOrgName}</strong> organization.
          Switch to the <strong>{requiredOrgName}</strong> organization to access this page.
        </p>
        <OrganizationSwitcher />
      </>
    )
  }

  return (
    <p>
      You are currently signed in as an <strong>admin</strong> in the{' '}
      <strong>{organization.name}</strong> organization.
    </p>
  )
}

For more examples on how to perform authorization checks, see the dedicated guide.

It's time to build your B2B SaaS!

You've added Clerk organizations to your Next.js app 🎉. Ready to scale to enterprise customers?

  • Control access with custom roles and permissions: define granular permissions for different user types within organizations.

  • Onboard entire companies with verified domains: automatically invite users with approved email domains (e.g., @company.com) to join organizations without manual invitations.

  • Enable enterprise SSO with SAML and OIDC: let customers authenticate through their identity provider (Okta, Entra ID, Google Workspace) with unlimited connections, no per-connection fees.

Create and manage organizations

Learn how to create organizations, manage members, and switch between organizations.

Invite members to organizations

Learn how to invite team members to your organizations with role-based access.

Roles and permissions

Set up custom roles and permissions to control access within organizations.

Organization components

Learn more about Clerk's prebuilt organization components.

Feedback

What did you think of this content?

Last updated on