Skip to content

<OrganizationSwitcher />

Organization switcher popover listing the active organization with a settings button, other organizations and Create Organization

<OrganizationSwitcher /> shows the user’s active organization and lets them switch to another one, create a new one, or open the active organization’s settings. It also rewrites organization slugs in the current URL, so organization-scoped routes follow the switch. It needs organizations: true in src/convex/auth.constants.ts (see Organizations).

Quick start

The base registry item already mounts it in the header of the root layout, behind the organizations flag. To place it elsewhere, render it inside the same providers:

src/routes/+layout.svelte
src/app/layout.tsx

In SvelteKit, the component reads api and authConstants from an <AuthProvider> ancestor, which the base src/routes/+layout.svelte provides.

In Next.js, the component needs the ConvexClientProvider that the base src/app/layout.tsx mounts.

The settings entry opens a dialog only while <OrganizationProfileHost /> is mounted, which the base layouts also do.

What it does

The trigger shows the active organization’s logo and name. Selecting it opens a popover:

  • The active organization comes first. Owners and admins see a settings icon on it that opens <OrganizationProfile />. Members see a Leave organization action instead, shown when the organization has more than one member.
  • Other organizations follow. Selecting one makes it active.
  • Create Organization opens <CreateOrganization /> in a dialog.

The component renders differently by state:

StateRenders
organizations is not trueAn inline error asking you to turn organizations on, also logged to the console.
Signed outNothing.
Loading, with no data yetA placeholder bar.
No organizationsA Create Organization button that opens the create dialog.
One or more organizationsThe switcher.

New users rarely see the empty state: with organizations on, sign-up creates a personal organization for them.

URL behavior

Switching rewrites the slug

When the current path contains the active organization’s slug as a segment, switching replaces it with the new organization’s slug:

  • /acme/products/42 becomes /umbrella/products/42

The navigation replaces the current history entry. When the path has no slug, SvelteKit navigates to the current URL againNext.js calls router.refresh().

The /active-organization placeholder

Links can use active-organization, or its alias active-org, as a path segment wherever the slug belongs. Once the active organization is known, the segment is replaced with its slug:

  • /active-organization becomes /acme
  • /docs/active-org/getting-started becomes /docs/acme/getting-started

Use it in emails, onboarding checklists and support links that can’t know the slug. How the replacement runs differs by framework:

  • SvelteKit ships no route for it. The mounted <OrganizationSwitcher /> rewrites the URL in the browser, so the placeholder only resolves on pages that render the switcher. A dynamic route such as src/routes/[slug]/+page.svelte first loads with active-organization as its slug, so its load function has to tolerate that value until the rewrite.
  • Next.js ships src/app/active-organization/[[...all]]/page.tsx in the organizations/routes item. It resolves a path that starts with /active-organization on the server and redirects to /organization/create?redirectTo=<original path> when the user has no active organization. The active-org alias, and the placeholder later in a path, are rewritten in the browser by the mounted switcher.

Props

  • popoverPlacement sets where the popover opens relative to the trigger.
  • initialData takes the organization data loaded on the server, so the switcher renders on first paint instead of after its queries. The types come from #lib/auth/types.js; the base/ssr item’s src/routes/+layout.server.ts returns this data as data.initialData.

Behavior

Switching calls the Convex mutation api.organizations.mutations.setActiveOrganization, rewrites or reloads the page as described above, and closes the popover. When the user has organizations but no active one, the switcher sets one by calling the same mutation without an id.

The settings entry adds ?dialog=organization-profile to the URL as a new history entry, so a reload keeps the dialog open and the browser’s back button closes it.

Owner and admin checks come from useRoles, described on Organizations. They only decide what the UI shows. The Convex mutations call Better Auth’s organization plugin, which enforces the role on the server.