Theme
Customize the chatbot appearance through the theme prop. Every color,
spacing, and radius value in the default theme can be overridden.
Presets
Current Theme Config
{}Try the Crazy preset to see every theming slot in action at once.
Code Example
import { Chatbot } from "@asgard-js/react";
import type { AsgardThemeContextValue } from "@asgard-js/react";
const myTheme: Partial<AsgardThemeContextValue> = {
chatbot: {
backgroundColor: "#3c1d3b",
borderColor: "#92ff8c",
primaryComponent: {
mainColor: "#ff0000",
secondaryColor: "#aba400",
},
},
botMessage: {
color: "#00f0ff",
backgroundColor: "#ff7a00",
},
userMessage: {
color: "#522801",
backgroundColor: "#060081",
},
};
<Chatbot theme={myTheme} {...rest} />;
Theme Structure
| Level | Fields | Description |
|---|---|---|
chatbot | backgroundColor, borderColor, borderRadius | Outer frame styles |
chatbot | contentMaxWidth, width, height | Size controls |
chatbot | mainColor, secondaryColor, inactiveColor | Global colors |
chatbot.primaryComponent | mainColor, secondaryColor, onMainColor | Primary interactive element colors |
chatbot.header | style, title.style, actionButton.style | Header styles |
chatbot.body | style | Message area styles |
chatbot.footer | style, textArea.style, submitButton.style, speechInputButton.style | Input area styles |
botMessage | color, backgroundColor, linkColor, quickReplyBackgroundColor | Bot message bubble |
userMessage | color, backgroundColor | User message bubble |
template | quickReplies.style, references.style, time.style | Template element styles |
These chatbot colors are wired to the SDK's --asg-color-* design tokens, so setting them recolors the newer surfaces too (the running indicator, composer input, channel-title bar, tool-call groups, thinking block, and Task / Subagent panels):
| Theme field | Token |
|---|---|
chatbot.primaryComponent.mainColor | --asg-color-primary (+ a derived darker hover) |
chatbot.backgroundColor | --asg-color-bg / --asg-color-surface (surface one step lighter) |
chatbot.borderColor | --asg-color-border / --asg-color-divider |
chatbot.inactiveColor | --asg-color-text-secondary / --asg-color-action-inactive (the muted text and icon tier: timestamps, placeholder, header icons) |
chatbot.primaryComponent.secondaryColor | --asg-color-text-primary (the primary text tier) |
A token is injected whenever the value is a non-empty string; leave it out to keep the built-in default.
Wire It to Your Own Design Tokens
Theme fields are not limited to hex. var(), oklch(), rgb() and color-mix() pass
through as-is, so the chat can be wired straight into your existing design system:
const myTheme = {
chatbot: {
backgroundColor: "var(--my-surface)",
borderColor: "var(--my-border)",
primaryComponent: {
mainColor: "var(--my-brand)",
},
},
};
The only difference is how derived shades are computed: a 6-digit hex (#rrggbb)
is darkened/lightened arithmetically, anything else derives its shades via CSS
color-mix(). Existing hex usage is unaffected.
onMainColor: Foreground on the Accent
primaryComponent.onMainColor is the color for content sitting on top of
mainColor — card and carousel button labels, the attachment icon glyph, and the
composer's submit icon.
It defaults to secondaryColor, which is also the primary text tier (header title,
input text). Those two only agree while mainColor is dark: if your brand accent is
light (a gold, say), the accent needs dark text on it while everything else needs
light text — and one field cannot be both.
Set onMainColor when mainColor is light.
const goldTheme = {
chatbot: {
primaryComponent: {
mainColor: "#e8c547", // light accent
secondaryColor: "#f5f5f5", // regular text: light
onMainColor: "#1a1a1a", // text on the gold: dark
},
},
};
Theming Outside the Chatbot
Consumer-placed panels (<TaskList>, <FileExplorerPanel> and friends) are not inside
<Chatbot>'s DOM subtree and miss all of the tokens above. Use
AsgardThemeScope to re-establish the same theme there.