Skip to Content

Shell

A component with a collapsible sidebar, theme and language toggles, and optional OAuth2 authentication.

Minimal Header Variant

Use the variant="minimal" prop to render a horizontal header layout instead of the default sidebar.

Features

  • Optional OAuth2 Authentication: Plug-and-play authorization code flow with PKCE
  • Theme Toggle: Built-in light/dark mode support
  • Language Toggle: Built-in language switcher for internationalization
  • User Profile: Dropdown menu with user information and sign-out

Installation

npx shadcn@latest add @uipath/shell

Usage

The shell works out of the box without authentication. Just provide layout props:

import { Home, Settings } from 'lucide-react'; import { ApolloShell } from '@/components/ui/shell'; const navItems = [ { path: '/dashboard', label: 'dashboard', icon: Home }, { path: '/settings', label: 'settings', icon: Settings }, ]; function App() { return ( <ApolloShell companyName="Your Company" productName="Your Product" navItems={navItems} > <YourApp /> </ApolloShell> ); }

Adding Authentication

To enable built-in OAuth2 authentication with PKCE, wrap the shell with ShellAuthProvider. Both ShellAuthProvider and ApolloShell must be inside a QueryClientProvider from @tanstack/react-query.

When a ShellAuthProvider is present, the shell automatically shows a login screen until the user is authenticated.

import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { Home, Settings } from 'lucide-react'; import { ApolloShell } from '@/components/ui/shell'; import { ShellAuthProvider } from '@/components/ui/shell-auth-provider'; const queryClient = new QueryClient(); const navItems = [ { path: '/dashboard', label: 'dashboard', icon: Home }, { path: '/settings', label: 'settings', icon: Settings }, ]; function App() { return ( <QueryClientProvider client={queryClient}> <ShellAuthProvider clientId="your-client-id" scope="openid profile email offline_access" baseUrl={window.location.origin} > <ApolloShell companyName="Your Company" productName="Your Product" navItems={navItems} > <YourApp /> </ApolloShell> </ShellAuthProvider> </QueryClientProvider> ); }

Gating access by group membership

Use GroupMembershipGuard to restrict the application to members of one or more UiPath Identity groups. The guard fetches each configured group in parallel, compares the signed-in user’s email against the combined member list, and renders either a loading indicator or an access-denied screen with a sign-out action. When the user is a member of any of the listed groups, the children render unchanged. An empty groupIds array denies access. Fetch failures bubble up to the nearest error boundary.

The toggle below switches between the loading, denied, and granted states using stubbed authentication and pre-populated query data.

Place GroupMembershipGuard inside ShellAuthProvider so it can read the authenticated user from useAuth. The baseUrl, orgName, orgId, and each groupId in groupIds compose the Identity API URL ({baseUrl}/{orgName}/identity_/api/Group/{orgId}/{groupId}):

import { GroupMembershipGuard } from '@/components/ui/shell/group-membership-guard'; function App() { return ( <QueryClientProvider client={queryClient}> <ShellAuthProvider clientId="your-client-id" scope="openid profile email offline_access" baseUrl={window.location.origin} > <GroupMembershipGuard baseUrl="https://staging.uipath.com" orgName="your-org" orgId="your-org-id" groupIds={['admins-group-id', 'editors-group-id']} > <ApolloShell companyName="Your Company" productName="Your Product" navItems={navItems} > <YourApp /> </ApolloShell> </GroupMembershipGuard> </ShellAuthProvider> </QueryClientProvider> ); }