In this article
June 4, 2025
June 4, 2025

How to implement an organization switcher with WorkOS and React

Step-by-step tutorial on how to add an organization switcher to your app using React and WorkOS.

In modern SaaS applications, it's common for users to be part of multiple organizations, teams, or workspaces—whether they're consultants, admins, or simply active in different environments. To support this, apps need a way to let users switch between organizations without the friction of logging out and back in. This is where an organization switcher comes in.

An organization switcher provides a smooth, intuitive way for users to change context and access the data and settings relevant to a specific organization. It ensures that each view, resource, and action is properly scoped to the selected organization, helping maintain both usability and security.

In this tutorial, we'll walk through how to build a simple but effective organization switcher in a React application using WorkOS. With WorkOS handling SSO, user management, and organizational context, we can focus on implementing the frontend and backend logic needed to switch organizations cleanly and securely.

Prerequisites

To follow this tutorial, you will need the following:

  • A React app (or Node, if you won't be using AuthKit and frontend libraries).
  • A WorkOS account with at least 2 organizations.

!!An organization is a collection of users that also acts as a container for enterprise features (like SSO). By enabling an SSO connection for a specific organization, you enable the feature for all users who are members of this organization. This way, you can enable features like forcing all users that use a specific email domain to use a specific SSO connection. For more information on organizations and how to use them, see Model your B2B SaaS with organizations.!!

Step 1: Install the SDK

Install the WorkOS React library to your app:

Alternatively, you can use the authkit-js SDK, the Node SDK, or any other of our backend SDKs.

Step 2: Set secrets

To make calls to WorkOS, you must authenticate using the WorkOS API key and client ID. Copy these values from the WorkOS dashboard.

Store the values as managed secrets and pass them to the SDK either as environment variables or directly in your app’s configuration.

Environment variables example:

  
WORKOS_API_KEY='sk_example_123456789'
WORKOS_CLIENT_ID='client_123456789'
  

!!For more info on how to handle secrets safely, see Best practices for secrets management.!!

Step 3: Implement the org switching

We are ready to start adding code. We will present two different implementations.

The first option uses WorkOS Widgets: React components that provide complete functionality for common enterprise app workflows.

The <OrganizationSwitcher /> widget allows an organization admin to switch between organizations. There are no special permissions required to use this widget as users can switch between organizations they have access to. If an organization requires SSO or MFA, the user will be redirected to reauthorize with the new organization.

When you switch to another organization, the widget communicates with the WorkOS API to authenticate you into the new organization and retrieve a fresh authentication token. This ensures that you have valid access rights for the new organization.

For example, if you're logged into the Webflow organization through their SSO and decide to switch to Vercel, you’ll be prompted to authenticate with Vercel before the switch can be completed successfully. This additional authentication step ensures security and that you’re granted the proper permissions for the new organization, keeping the transition seamless and secure.

If you prefer to build and manage your own authentication UI, or you don’t want to use Widgets, follow the second option. It will show you how to implement this functionality via the User Management API.

Option 1: Use Widgets

1. Install the Widgets package

First, install the @workos-inc/widgets package from the npm registry, along with its peer dependencies:

	
npm install @workos-inc/widgets @radix-ui/themes @tanstack/react-query
	

2. Configure CORS

Because WorkOS widgets issue client-side requests to WorkOS, it is necessary to configure your site as an allowed web origin. Go to WorkOS dashboard> Authentication > Cross-Origin Resource Sharing (CORS) > Configure CORS and add your app’s URL.

3. Add the widget

If you are using either the authkit-js or authkit-react libraries, you can use the useAuth hook to get the current organization and pass it to the widget.

	
import { useAuth } from '@workos-inc/authkit-react';
import { OrganizationSwitcher, WorkOsWidgets } from '@workos-inc/widgets';

export function OrganizationSwitcherWrapper() {
  const { getAccessToken, switchToOrganization } = useAuth();

  return (
    <WorkOsWidgets>
      <OrganizationSwitcher
        authToken={getAccessToken}
        switchToOrganization={switchToOrganization}
      />
    </WorkOsWidgets>
  );
}
	

Notice the getAccessToken method. Widgets need to authenticate with the WorkOS API and for that they need a token. With AuthKit, you can use the provided access token, returned by getAccessToken.

If you are using one of the backend SDKs, you can build the organization switcher action in the backend and pass it in as a prop to the widget to be called when the user attempts to switch organizations. This can then be passed in as a prop to the widget.

	
import { useAuth } from '@workos-inc/authkit-react';
import { OrganizationSwitcher, WorkOsWidgets } from '@workos-inc/widgets';
import { redirect } from 'next/navigation';

// authToken is a widget token that was fetched in your backend. See the
// "Tokens" section of this guide for details on how to generate the token
export function OrganizationSwitcher({ authToken }) {
  const handleOrganizationSwitch = async (organizationId, pathname) => {
    try {
      // this is some API endpoint defined in your backend that would
      // call the WorkOS APIs to switch the organization or return a redirect URL
      // if the user needs to reauthorize with the new organization
      const response = await fetch('/api/organizations/switch', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ organizationId }),
      });

      if (!response.ok) {
        throw new Error('Failed to switch organization');
      }

      // if the backend returns a redirect URL to reauthorize the user, redirect the user to the new organization
      const { redirectUrl } = await response.json();
      if (redirectUrl) {
        redirect(redirectUrl);
      }

      revalidatePath(pathname);
      redirect(pathname);
    } catch (error) {
      console.error('Error switching organization:', error);
      // Handle error (show toast, etc.)
    }
  };

  return (
    <WorkOsWidgets>
      <OrganizationSwitcher
        authToken={authToken}
        switchToOrganization={handleOrganizationSwitch}
      />
    </WorkOsWidgets>
  );
}
	

In this case, to get a token (authToken), you need to use the get token method. You need to specify which widget you want the token for (using scopes) and who is the user using the widget (using userId and organizationId).

Use this code sample to get a token without the frontend libraries:

	
import { WorkOS } from '@workos-inc/node';

const workos = new WorkOS('sk_example_123456789');

const authToken = await workos.widgets.getToken({
  organizationId: org_id,
  userId: user.id,
  scopes: ['widgets:organization-switcher:manage'],
});
	

Note the following to avoid errors:

  • Widget tokens expire after one hour.
  • To successfully generate a token, the user must have the correct permissions. New WorkOS accounts are created with an “Admin” role that has all Widget permissions assigned, but existing accounts will need to be updated. This can be done on the “Roles” page of the WorkOS dashboard. For more info, see the Roles and Permissions docs.

That’s it, your organization switcher is ready to go!

4. Customize the UI (optional)

WorkOS Widgets are powered by Radix Themes, which are styled out-of-the box when you import its CSS in your app.

	
import '@radix-ui/themes/styles.css';
	

You can customize Widgets by passing a theme prop to WorkOSWidgets. This prop accepts an object with the same options as Radix themes.

	
function UsersTable({ authToken }) {
  return (
    <WorkOsWidgets
      theme={{
        appearance: 'dark',
        accentColor: 'green',
        radius: 'medium',
        fontFamily: 'Inter',
      }}
    >
      <UsersManagement authToken={authToken} />
    </WorkOsWidgets>
  );
}
	

You can also style Widgets using CSS. Start with the layout.css stylesheet from Radix Themes, as well as the base.css stylesheet from WorkOS Widgets, to get a base level of functional styling without opinionated design choices.

	
import '@radix-ui/themes/layout.css'; 
import '@workos-inc/widgets/base.css';
	

Individual elements in Radix themes are accessible via CSS class selectors prefixed with woswidgets-. For example, you can add your own button styles by selecting the woswidgets-button class.

	
.woswidgets-button {
  border-radius: 4px;
  color: hsl(0 0% 100%);
  background-color: hsl(272deg 81% 56%);
  background-image: linear-gradient(
    to top right,
    hsl(272deg 81% 56%),
    hsl(271deg 91% 65%)
  );
  /* ... */
}
	

Option 2: Manual implementation

Follow this section if you prefer to build and manage your own authentication UI, or you don’t want to use Widgets. We will not go into the frontend details but will see how to implement this functionality in the backend using the WorkOS API.

First, you will need a refresh token. This refresh token will be used to get a new access token for the organization you want to switch to, by passing the organization_id parameter to the authenticate with refresh token endpoint.

	
import { WorkOS } from '@workos-inc/node';

const workos = new WorkOS('sk_test_123');

const { refreshToken } =
  await workos.userManagement.authenticateWithRefreshToken({
    clientId: user.id,
    organizationId: org_to_switch_to,
    refreshToken: 'Xw0NsCVXMBf7svAoIoKBmkpEK',
    ipAddress: '192.0.2.1',
    userAgent:
      'Mozilla/5.0 (X11; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0',
  });
	

If the session for the refresh token is authorized to access the organization, then the org_id will be set to the given organization, along with the role and permissions claims matching the user’s membership in that organization. You will have to update the UI to reflect that.

Next steps

You have now built into your app a way to let users switch between organizations without the friction of logging out and back in. This might not seem exciting but it’s one of the things that add up to a great user experience.

The next steps can be things like implementing access control, provisioning users automatically, handling failed authentication events, and more. For details on any of these explore our docs, or use any of the following resources:

This site uses cookies to improve your experience. Please accept the use of cookies on this site. You can review our cookie policy here and our privacy policy here. If you choose to refuse, functionality of this site will be limited.