Skip to content
Torii docs

Customizing Torii

Torii’s components are customized through a single prop, appearance on <ToriiProvider>, plus the labels system for text. Everything is consumer-driven: the SDK does not fetch theming from the server, so your provider props are the only source of truth.

There are no CSS imports, no Tailwind requirement, and no className plumbing. The SDK emits its own scoped <style> block under the .torii root and honours your app’s existing .dark class for dark mode.

Customization is layered, in order of increasing specificity. Reach for the lowest layer that does the job:

  1. Theme: pick a baseline palette. A preset name ('shadcn' | 'mui') or a full Theme object bundling light + dark token sets.
  2. Variables: override individual design tokens (a color, the radius, the font) on top of the theme. Applies to both light and dark modes.
  3. Elements: attach a class name or inline style to a named component slot when tokens aren’t enough (e.g. fully-rounded buttons, a custom shadow).
<ToriiProvider
publishableKey="pk_live_…"
appearance={{
theme: 'shadcn', // 1. baseline palette
variables: { primary: '262 83% 58%' }, // 2. token override
elements: { formButtonPrimary: 'rounded-full' }, // 3. per-slot class
}}
>
<App />
</ToriiProvider>

Resolution per render: preset baseline → variables layered on top → elements applied at render time.

LayerPropScopeWhen to use
Themeappearance.themeWhole paletteMatch your component library or ship a full custom theme.
Variablesappearance.variablesIndividual tokensTweak one or two colors / the radius without authoring a theme.
Elementsappearance.elementsNamed slotsPer-element class or inline-style overrides.

→ Full details: theming · elements & slots

Visual styling and copy are separate axes. All user-facing text flows through the labels system; no string is ever hardcoded. Pass a languages array to <ToriiProvider> for built-in en / da with browser auto-detection, or override any subset of keys per component via the labels prop.

Labels & i18n

A few things are deliberately not consumer-customizable, because the server enforces them per environment / billing tier:

  • The “Powered by Torii.so” footer is required on lower tiers. The appearance.hideFooter flag is honoured only when the server’s branding gate allows it (builder-tier orgs): a downgraded org can’t accidentally hide it. Its styling is still themeable via the poweredBy element slot.
  • Legal consent links (Terms / Privacy) come from the environment’s configured URLs, surfaced on the sign-up form.
  • MitID button copy is constrained to the wordings mandated by the Danish Agency for Digitalisation (see labels).