Skip to content

Elements & slot overrides

The appearance.elements prop lets you attach a class name or an inline-style object to any named slot in the SDK’s component tree. Use this when a preset + a few token tweaks aren’t enough, e.g. you want the primary button to be fully rounded, or the card to have a specific shadow.

appearance={{
elements: {
card: 'my-card-class',
formButtonPrimary: { borderRadius: '9999px', fontWeight: 600 },
},
}}

Each slot accepts either:

  • string: appended to the element’s built-in torii-* class (so cascading stylesheets, Tailwind, CSS modules all work).
  • CSSProperties: applied as inline style (wins over stylesheets via specificity).

Apply one slot across every relevant component, e.g. formButtonPrimary styles the submit button on sign-in, sign-up, forgot-password, and profile save alike. That is intentional: consistency is the whole point of the slot system.

Slots are part of the public API: they won’t be removed or renamed across minor versions.

Slot Surface
card Any card container (sign-in, sign-up, forgot, profile)
headerTitle Main heading inside the card
headerSubtitle Secondary heading inside the card
formFieldLabel Each input’s label
formFieldInput Each text / email / password input
formFieldError Per-field validation error
formError Form-level error (e.g. bad credentials)
formButtonPrimary Primary submit / save button
socialButton Each OAuth / SSO button
dividerText The “or” divider between social and password
forgotPasswordLink “Forgot password?” link
footerActionLink “Sign up” / “Sign in” toggle at the bottom

Post-auth surfaces (user profile / dashboard)

Section titled “Post-auth surfaces (user profile / dashboard)”
Slot Surface
menuContent Popup / dropdown container (user button, language select)
menuItem Row inside a popup / dropdown
menuSeparator Visual separator between menu groups
tabList Tab strip (user dashboard)
tabTrigger Individual tab button
modalBackdrop Dimmed overlay behind a modal (UserProfile modal)
modalContent The centered modal panel
modalCloseButton The ✕ button on a modal
listItem Row in a list (connected accounts, sessions)
secondaryButton Non-primary actions (Cancel, Edit)
destructiveButton Dangerous actions (Sign out, Disconnect, Delete)
poweredBy “Powered by Torii.so” footer under auth cards (styling only, always rendered)
<ToriiProvider
publishableKey="pk_live_…"
appearance={{
elements: {
formButtonPrimary: 'rounded-full font-semibold',
socialButton: 'rounded-full',
},
}}
>
<SignIn />
</ToriiProvider>
appearance={{
elements: {
card: {
boxShadow: '0 20px 60px -20px rgba(0,0,0,0.18)',
border: '1px solid rgba(0,0,0,0.04)',
},
headerTitle: { letterSpacing: '-0.02em' },
},
}}

Use inline styles when the class path would be awkward (e.g. you don’t have a CSS framework set up); they win over the SDK’s stylesheet via standard CSS specificity rules.

Before reaching for a new slot, check the existing list. A few recurring patterns:

  • “I want to change all the cards.”card.
  • “…only the sign-in card.” → target the per-surface class in your CSS: .torii-sign-in-card { … } (see Per-surface card classes below). The card slot intentionally hits every card; the per-surface classes are the per-screen escape hatch.
  • “I want to restyle my SSO buttons.”socialButton applies to every OAuth / SSO button across sign-in and sign-up.
  • “I want one button in the profile to be red.”destructiveButton (it’s already wired for Sign out, Disconnect, Delete).

Every slot has a stable built-in class (e.g. torii-card, torii-btn-primary) that you can also target from a global stylesheet. Renaming one is treated as a breaking change, so it’s safe to rely on for CSS-only overrides if you don’t want to use the prop API.

The sandbox “Development mode” indicator (torii-dev-mode band + torii-dev-mode-stamp label, shown under auth surfaces in a sandbox environment) has no slot by design — it’s a safety signal, not a brandable surface. It themes automatically from the --torii-warning token, you can still target its stable classes from CSS, and it’s suppressed via appearance.hideDevelopmentBadge (see Server-controlled surfaces) rather than a styling override.

The <UserButton> account switcher (multi-session) has no dedicated slots; target its stable classes instead (the switcher rows also carry the menuItem slot class):

Class Element
torii-user-menu-account Switcher row in the menu (one per other account)
torii-user-menu-account-initials Initials badge on a switcher row
torii-user-menu-account-name Display name on a switcher row
torii-user-menu-account-email Email on a switcher row
torii-add-account-backdrop Dimmed overlay behind the “Add account” dialog
torii-add-account-panel The “Add account” dialog panel
torii-add-account-close The ✕ button on the “Add account” dialog

The card slot styles every card. When you want to restyle one specific card, each card also carries a stable per-surface class alongside the shared torii-card, so you can scope a plain CSS rule to it:

Surface Per-surface class
Sign-in card torii-sign-in-card
Sign-up card torii-sign-up-card
Forgot-password card torii-forgot-card
User profile card torii-profile-card
Organization list torii-org-list
Organization profile torii-org-profile
Create organization torii-create-org
/* Give only the sign-in card a tinted background; leave sign-up untouched. */
.torii-sign-in-card {
background: linear-gradient(180deg, #faf5ff, #ffffff);
}

These are additive: torii-card still applies the base styling, and the card slot override still layers on top. Like the slot classes, they’re stable across minor versions.

  • Theming: presets, variables, token list