Theming & CSS Variables
Drive the widget's theme from embed config or override the --wx-* CSS variables directly
You can theme the widget two ways: from the dashboard (Appearance), or from code — by passing a theme object in the embed config, or by overriding the --wx-* CSS variables. This page covers the code path.
Theme via embed config
Pass a theme (and themeMode) in the config prop / injected settings:
<WexioWidget
publicKey="pk_live_..."
config={{
theme: {
light: {
background: "#ffffff",
text: "#1a1a1a",
primary: "#0070f3",
primaryHover: "#0060df",
primaryForeground: "#ffffff",
},
dark: {
background: "#0a0a0a",
text: "#fafafa",
primary: "#3b82f6",
},
radii: { sm: 6, md: 10, lg: 16, xl: 24 },
launcherPosition: "RIGHT_BOTTOM",
fontFamily: "'Inter', system-ui, sans-serif",
},
themeMode: "auto",
}}
/>Every palette key is optional — unset keys fall back to the default for that mode.
Palette → CSS variable mapping
The widget exposes its palette as --wx-* custom properties. These are the only supported override surface — there are no component class names to target.
| Palette key | CSS variable | Default (light) | Default (dark) |
|---|---|---|---|
background | --wx-bg | #ffffff | #121314 |
surface | --wx-bg-elevated | #f5f5f7 | #1e1f21 |
surfaceElevated | --wx-bg-elevated-2 | #ebebef | #2a2c2e |
text | --wx-fg | #121314 | #f4f4f5 |
textMuted | --wx-fg-muted | #6b7280 | #a1a1aa |
textSubtle | --wx-fg-subtle | #9ca3af | #71717a |
border | --wx-border | #e4e4e7 | #2a2c2e |
borderStrong | --wx-border-strong | #d1d5db | #3f3f46 |
primary | --wx-primary | #121314 | #ffffff |
primaryHover | --wx-primary-hover | #2a2c2e | #e4e4e7 |
primaryForeground | --wx-primary-fg | #ffffff | #121314 |
launcherBackground | --wx-launcher-bg | #121314 | #ffffff |
launcherForeground | --wx-launcher-fg | #ffffff | #121314 |
success | --wx-success | #10b981 | #10b981 |
danger | --wx-danger | #ef4444 | #ef4444 |
Radii (theme-invariant)
| Key | CSS variable | Default |
|---|---|---|
sm | --wx-radius-sm | 8px |
md | --wx-radius | 12px |
lg | --wx-radius-lg | 20px |
xl | --wx-radius-xl | 28px |
How overrides are applied
The widget injects the operator palette as two selector blocks — base values under :root, :host, and dark-mode values under [data-theme="dark"]:
:root, :host {
--wx-bg: #ffffff;
--wx-fg: #121314;
/* … */
--wx-radius-sm: 8px;
}
[data-theme="dark"] {
--wx-bg: #121314;
--wx-fg: #f4f4f5;
/* … */
}useThemeMode() always resolves to a concrete light or dark and writes data-theme onto the widget root. For Shadow DOM embeds (React, Web Component) the variables live on the shadow host; for the iframe embed they live on the document.
Theme mode resolution
The active mode is resolved in this priority order:
- A
?theme=URL parameter (dashboard preview links). - A dashboard live-edit message (preview mode only).
- The visitor's saved preference — only when the operator allows visitors to change the theme.
- The operator's
themeMode. - The visitor's cached
localStoragevalue (when allowed). - The OS
prefers-color-scheme.
If you save light or dark explicitly, visitors can't override it. Save auto to let the visitor's system (and the Profile tab toggle) decide.
Launcher position & font
launcherPosition: "RIGHT_BOTTOM" | "LEFT_BOTTOM" // default RIGHT_BOTTOM
fontFamily: "'Inter', system-ui, -apple-system, sans-serif" // any CSS font stackBoth are theme-invariant. For the iframe embed, launcherPosition also flips which side the iframe is pinned to.