Skip to main content
Docs

Get started with Organizations and Next.js

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.

Note

Haven't set up Clerk auth yet? Head over to the Next.js quickstart!

Add <OrganizationSwitcher/> to your app

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 to your users. For example:

app/layout.tsx
import type { Metadata } from 'next'
import {
  ClerkProvider,
  SignInButton,
  SignUpButton,
  SignedIn,
  SignedOut,
  UserButton,
  OrganizationSwitcher,
} from '@clerk/nextjs'
18 lines collapsedimport { Geist, Geist_Mono } from 'next/font/google' import './globals.css' const geistSans = Geist({ variable: '--font-geist-sans', subsets: ['latin'], }) const geistMono = Geist_Mono({ variable: '--font-geist-mono', subsets: ['latin'], }) export const metadata: Metadata = { title: 'Clerk Next.js Quickstart', description: 'Generated by create next app', }
export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode }>) { return ( <ClerkProvider> <html lang="en"> <body className={`${geistSans.variable} ${geistMono.variable} antialiased`}> <header className="flex justify-end items-center p-4 gap-4 h-16"> <OrganizationSwitcher /> <SignedOut> <SignInButton /> <SignUpButton> <button className="bg-[#6c47ff] text-white rounded-full font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 cursor-pointer"> Sign Up </button> </SignUpButton> </SignedOut> <SignedIn> <UserButton /> </SignedIn> </header> {children} </body> </html> </ClerkProvider> ) }

Access Organization data

Use Clerk's useOrganization() hook to access information about the currently active Organization. Use Clerk's useOrganizationList() hook to access information about the current user's Organization memberships.

app/page.tsx
'use client'

import { useOrganization, useOrganizationList } from '@clerk/nextjs'

export default function Home() {
  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>
          {
            userMemberships?.data?.find(
              (membership) => membership.organization.id === organization?.id,
            )?.role
          }
        </strong>
      </p>
    </div>
  )
}

Visit your app

Run your project with the following command:

terminal
npm run dev
terminal
pnpm run dev
terminal
yarn dev
terminal
bun run dev

Visit your app locally at localhost:3000.

Enable Organizations

When prompted, select Enable Organizations.

Create first user and Organization

You must sign in to use Organizations. When prompted, select Sign in to continue. Then, authenticate to create your first user.

Since you selected disabled Personal Accounts when you enabled Organizations, every user must be in at least one Organization. to create an Organization for your user.

Create and switch Organizations

At this point, Clerk should have redirected you to a page with the <OrganizationSwitcher /> component. This component allows you to create, switch between, and manage organizations.

  1. Select the <OrganizationSwitcher /> component, then Create an organization.
  2. Enter Acme Corp as the Organization name.
  3. Invite users to your Organization and select their Role.

Protect routes by Organization and Roles

You can protect content and even entire routes based on Organization membership, Roles, and Permissions by performing .

In the following example, the page is protected from unauthenticated users, users that don't have the org:admin Role, and users that are not in the Acme Corp Organization.

  • The AuthClerk Icon object is used to access the isSignedIn and has() properties.
  • The isSignedIn property is used to check if the user is signed in.
  • The has() helper 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>
  )
}

Navigate to localhost:3000/protected. You should see a green message confirming you are an admin in Acme Corp. Use the <OrganizationSwitcher/> to switch Organizations or rename the Organization to show the red message.

Learn more about protecting routes and checking Organization Roles in the authorization guide.

It's time to build your B2B SaaS!

You've added Clerk Organizations to your Next.js app 🎉. If your app needs to scale to enterprise customers, here's what you can do next:

To make configuration changes to your Clerk development instance, claim the Clerk keys that were generated for you by selecting Claim your application in the bottom right of your app. This will associate the application with your Clerk account.

  • 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.

Feedback

What did you think of this content?

Last updated on