UserButton
<UserButton> renders the signed-in user’s initials as a button that
opens a dropdown menu containing a “Manage profile” item, an optional
language switcher, and sign-out. It’s the equivalent of the account menu
in the top-right of most apps.
By default, “Manage profile” opens the full <UserProfile>
widget in a modal, no wiring required. Switch to userProfileMode="navigation"
if you’d rather route to your own account page.
The dropdown’s open/close state, the profile modal, click-outside, and keyboard navigation are handled inside the SDK runtime; you just place the component.
When to use
Section titled “When to use”Place it inside <SignedIn>, since
it requires an authenticated session.
import { SignedIn, UserButton } from '@torii-js/torii-react';
function Header({ profile }) { return ( <SignedIn> {/* Default: clicking "Manage profile" opens the profile modal. */} <UserButton profile={profile} /> </SignedIn> );}To route to your own account page instead of the modal:
<UserButton profile={profile} userProfileMode="navigation" onManageProfile={() => navigate('/account')}/>| Prop | Type | Default | Description |
|---|---|---|---|
profile |
UserProfileData | null |
null |
Used for the display name and initials. Falls back to the first 8 chars of the user ID when omitted. |
userProfileMode |
'modal' | 'navigation' |
'modal' |
'modal' opens <UserProfile> in a dialog. 'navigation' fires onManageProfile instead. |
onManageProfile |
() => void |
n/a | Called when “Manage profile” is clicked, in 'navigation' mode only. The item is hidden when omitted and not in modal mode. |
showLanguage |
boolean |
auto | Forwarded to the profile modal’s <UserProfile showLanguage> (modal mode only). Controls the Language row on the Profile section; defaults to auto (shown when more than one language is configured). |
appearancePreference |
'light' | 'dark' | 'system' |
n/a | Forwarded to the profile modal’s Appearance preference; see <UserProfile>. |
onAppearancePreferenceChange |
(value) => void |
n/a | Forwarded alongside appearancePreference. |
onActiveOrganizationChange |
(organizationId: string) => void |
- | Forwarded to the profile modal’s Organizations section. Fires after the active organization changes from inside the modal, so a host with organization-scoped routes can leave a route that belonged to the previous one. |
onOrganizationLeft |
(organizationId: string) => void |
- | Forwarded to the profile modal’s Organizations section. Fires after the user leaves an organization. |
variant |
'icon' | 'expanded' |
'icon' |
'icon' shows just the avatar; 'expanded' shows an identity row (avatar plus display name and email) suited to sidebar footers and account bars. |
className |
string |
n/a | Extra class names for the trigger button. |
Language switching moved. Earlier versions had a language switcher in this dropdown. It now lives in the
<UserProfile>Profile section as a Language row, shown automatically when<ToriiProvider>is configured with more than onelanguagesentry.UserButtonno longer takeslanguages/currentLanguage/onLanguageChange.
Account switcher (multi-session)
Section titled “Account switcher (multi-session)”When the environment has Multi-session enabled (dashboard: Authentication → Sessions, see session configuration), the dropdown grows an account switcher. There are no new props; it activates automatically from the environment config:
- The menu lists the other accounts signed in on this browser (initials, display name, email); clicking one switches the active session.
- An Add account item opens the standard
<SignIn>card in a dialog. Signing in adds the account on this browser and makes it the active one; the previous account stays available in the switcher. The dialog carries the full card, so someone without an account can switch it to sign-up and finish there — that lands the same way a sign-in does. - A browser holds at most one session per account. Authenticating again as an account that is already signed in here replaces its session and makes it active rather than listing the person twice, so the switcher never offers a switch to the account you are already using. Other browsers and devices are unaffected.
- Sign-out ends only the current account’s session and automatically switches to the most recently used remaining account; when none remain, the user lands signed out.
Switching accounts (and adding one) changes who is signed in. Because your app
almost certainly cached data for the previous user, the SDK reloads the page
by default after a swap — to signInUrl if set, otherwise / — so a fresh load
rebuilds everything for the new account. To keep the swap in-page instead, set
onActiveSessionChange on
<ToriiProvider> and invalidate your own caches there. Initial sign-in and
sign-out are unaffected.
To build your own switcher instead, use the headless
useSessionList() hook.
Behaviour
Section titled “Behaviour”- Requires a provider: must be rendered within
<ToriiProvider>; it readssignOut,user, andlabelsfrom context. - Sign-out: the menu’s sign-out item calls the SDK’s own
signOut. Drive any post-sign-out routing offuseAuth().isSignedInflipping tofalse, orevents.onSessionExpired. With multi-session enabled it only ends the current account’s session (see Account switcher). - Initials: derived from
profile.name, thenprofile.email, then the fallback display name. - Powered by Torii: the dropdown shows a brand ribbon at its bottom
edge, with the same visibility gating as the sign-in card footer
(
appearance.hideFooter, available on paid plans).
Theming
Section titled “Theming”The trigger and menu slots (menuContent, menuItem, menuSeparator,
destructiveButton) are themable via the appearance.elements prop on
<ToriiProvider>. See elements.
TypeScript
Section titled “TypeScript”import type { UserButtonProps } from '@torii-js/torii-react';