Theming reference
This is the full token reference for theming <AppilotsChat/>. For a lighter, task-first walkthrough see Customization: Theming — this page is the canonical deep reference: the complete token table, default values, the Tailwind bridge, and AppilotsThemeProvider for custom components.
Token shape
Every color, font size, radius, and shadow the chat UI renders comes from a single token tree, AppilotsThemeTokens:
import type { AppilotsThemeTokens } from '@appilots/sdk';
colors
| Token | Used for |
|---|---|
primary | Brand color — send button, FAB, header dot, links, running-action tone. |
secondary | Secondary accent — the human-agent (operator) icon on escalated message rows. |
background | Chat sheet background. |
surface | Assistant message bubbles, input field, chips, action/confirm card background. |
text | Default text color. |
textSecondary | Muted text — placeholders, "Powered by" footer. |
border | Hairlines under the header, around chips and action cards. |
success | Completed-action checks in the action breadcrumb. |
warning | Pending (queued, not-yet-run) action tone in the breadcrumb. The default is deliberately a neutral gray, not amber — set an amber here to make queued actions louder. |
error | Failed-action rows and destructive accents — the destructive badge on confirm cards and the reject button. |
buttonText | Chip/button label text. Defaults to text. |
bubbleText | Assistant bubble text color. Defaults to text. |
userBubbleText | Text color inside the user's bubble (rendered on primary). Defaults to white — pick a dark value if your primary is light. |
typography
| Token | Used for |
|---|---|
fontFamily | Applies to all chat text. Falls back to the system font if unset. |
fontSizeXs | Smallest text — chip labels, footer. |
fontSizeSm | Secondary text. |
fontSizeBase | Message text. |
fontSizeLg | Header title. |
radii
| Token | Used for |
|---|---|
sm | Chips. |
md | Input field, buttons. |
lg | Chat sheet, message bubbles. |
shadows
| Token | Used for |
|---|---|
appearance | 'light' | 'dark' — informational only. Tells you which base theme is currently active so custom UI can branch on it; the built-in components style themselves from the other tokens, not this one. |
Default values
Light (defaultLightTheme)
{
colors: {
primary: '#6366f1',
secondary: '#8b5cf6',
background: '#ffffff',
surface: '#f3f4f6',
text: '#1f2937',
textSecondary: '#6b7280',
border: '#e5e7eb',
success: '#10b981',
warning: '#9ca3af',
error: '#ef4444',
buttonText: '#1f2937',
bubbleText: '#1f2937',
userBubbleText: '#ffffff',
},
typography: {
fontFamily: 'System',
fontSizeXs: 11,
fontSizeSm: 13,
fontSizeBase: 15,
fontSizeLg: 18,
},
radii: { sm: 8, md: 12, lg: 16 },
shadows: { appearance: 'light' },
}
Dark (defaultDarkTheme)
Mirrors the light theme — same hue family, inverted background/text, cooler border/surface tones. Typography and radii are identical to the light theme. success/warning/error keep the same values as the light theme (breadcrumb tones render identically in both modes), as does userBubbleText.
{
colors: {
primary: '#818cf8',
secondary: '#a78bfa',
background: '#0f172a',
surface: '#1e293b',
text: '#f1f5f9',
textSecondary: '#94a3b8',
border: '#334155',
success: '#10b981',
warning: '#9ca3af',
error: '#ef4444',
buttonText: '#f1f5f9',
bubbleText: '#f1f5f9',
userBubbleText: '#ffffff',
},
typography: { /* same as light */ },
radii: { /* same as light */ },
shadows: { appearance: 'dark' },
}
Choosing the base: themeMode
<AppilotsChat themeMode="auto" /> // follows useColorScheme() — default
<AppilotsChat themeMode="light" /> // forces the light base
<AppilotsChat themeMode="dark" /> // forces the dark base
auto (the default) tracks the device's color scheme via useColorScheme(). Explicit light/dark values force a base regardless of device setting — useful if your app itself is locked to one mode. Whatever theme overrides you pass apply on top of whichever base ends up active.
Overriding tokens
The theme prop accepts a PartialThemeTokens — every field optional, deep-merged onto the active base:
<AppilotsChat
theme={{
colors: {
primary: '#0070f3',
},
}}
/>
You only need to specify the tokens you want to change; everything else falls through to the resolved default (light or dark).
Legacy flat shape
For backward compatibility, a flat shape is also still accepted and auto-translated:
{
primaryColor: string;
backgroundColor: string;
textColor: string;
inputBackgroundColor: string;
borderRadius: number;
fontFamily: string;
}
New integrations should use the nested AppilotsThemeTokens shape above — the flat shape exists only so older configs keep working.
Tailwind bridge
If your app already has a Tailwind config, appilotsTheme.fromTailwind() (also exported as appilotsThemeFromTailwind) maps a resolved Tailwind config to a PartialThemeTokens. Mapping is best-effort: only fields with a clear semantic match get pulled across, and everything else stays on the Appilots defaults.
import resolveConfig from 'tailwindcss/resolveConfig';
import tailwindConfig from './tailwind.config';
import { appilotsTheme, AppilotsChat } from '@appilots/sdk';
const theme = appilotsTheme.fromTailwind(resolveConfig(tailwindConfig));
<AppilotsChat theme={theme} />;
The bridge expects the resolved shape — pass your raw config through tailwindcss/resolveConfig first so plugin expansions and default shades are filled in before the bridge reads it.
AppilotsThemeProvider / useAppilotsTheme()
<AppilotsChat/> already wraps itself in a theme provider internally — you don't need to add your own for the chat to be themed. Add an outer AppilotsThemeProvider only when you have custom components (built with useAppilotsTheme()) that need to match the chat's resolved palette — for example, a custom trigger button that should look like part of the same system.
import { AppilotsThemeProvider, useAppilotsTheme, AppilotsChat } from '@appilots/sdk';
function CustomTriggerButton() {
const { colors, radii } = useAppilotsTheme();
return (
<Pressable style={{ backgroundColor: colors.primary, borderRadius: radii.md }}>
<Text style={{ color: '#fff' }}>Ask Appilots</Text>
</Pressable>
);
}
<AppilotsThemeProvider theme={{ colors: { primary: '#0070f3' } }}>
<CustomTriggerButton />
<AppilotsChat />
</AppilotsThemeProvider>;
Both CustomTriggerButton and AppilotsChat resolve tokens from the same provider, so they stay visually consistent.
mergeThemeTokens(base, partial)
The merge utility the provider uses internally to layer a PartialThemeTokens onto a full AppilotsThemeTokens. Exported for advanced cases where you're composing tokens programmatically outside of a provider (e.g. resolving a theme once at app startup rather than per-render):
import { mergeThemeTokens, defaultDarkTheme } from '@appilots/sdk';
const tokens = mergeThemeTokens(defaultDarkTheme, { colors: { primary: '#0070f3' } });
This is a rare, advanced-use utility — most integrations only ever need the theme prop.
Next steps
- Customization: Theming — a shorter, task-first walkthrough of the same system.
- Customization: Branding — logo, name, and other branding surfaces beyond color tokens.
- SDK: Chat component — the full
<AppilotsChat/>prop reference, includingthemeandthemeMode.