Skip to main content

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

{}
Loading chatbot...
tip

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

LevelFieldsDescription
chatbotbackgroundColor, borderColor, borderRadiusOuter frame styles
chatbotcontentMaxWidth, width, heightSize controls
chatbotmainColor, secondaryColor, inactiveColorGlobal colors
chatbot.primaryComponentmainColor, secondaryColor, onMainColorPrimary interactive element colors
chatbot.headerstyle, title.style, actionButton.styleHeader styles
chatbot.bodystyleMessage area styles
chatbot.footerstyle, textArea.style, submitButton.style, speechInputButton.styleInput area styles
botMessagecolor, backgroundColor, linkColor, quickReplyBackgroundColorBot message bubble
userMessagecolor, backgroundColorUser message bubble
templatequickReplies.style, references.style, time.styleTemplate element styles
Colors propagate across the whole chat surface

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 fieldToken
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.