Skip to content

Theming and customization

const { control } = useChatKit({
theme: {
colorScheme: "dark",
color: { accent: { primary: "#D7263D", level: 2 } },
radius: "round",
density: "normal",
typography: { fontFamily: "Open Sans, sans-serif" },
},
header: {
customButtonLeft: {
icon: "settings-cog",
onClick: () => alert("Profile settings"),
},
},
composer: {
placeholder: "Type your product feedback…",
tools: [{ id: "rate", label: "Rate", icon: "star", pinned: true }],
},
startScreen: {
greeting: "Welcome to FeedbackBot!",
prompts: [{ name: "Bug", prompt: "Report a bug", icon: "bolt" }],
},
entities: {
onTagSearch: async (query) => [
{ id: "user_123", title: "Jane Doe" },
],
onRequestPreview: async (entity) => ({
preview: {
type: "Card",
children: [
{ type: "Text", value: `Profile: ${entity.title}` },
{ type: "Text", value: "Role: Developer" },
],
},
}),
},
});

ChatKit is customized by passing in options object.

  • In React options are passed to useChatKit({...})
  • In a direct integration options are set with chatkit.setOptions({...})

In both cases the shape of the options object is the same. Below are some examples of how to customize ChatKit.


Match your app’s aesthetic by switching between light and dark themes, setting an accent color, controlling the density, rounding of corners, etc.

For all theming options, see the API reference.

const options: Partial<ChatKitOptions> = {
theme: {
colorScheme: "dark",
color: {
accent: {
primary: "#2D8CFF",
level: 2
}
},
radius: "round",
density: "compact",
typography: { fontFamily: "'Inter', sans-serif" },
},
};

Override text in the composer and start screen

Section titled “Override text in the composer and start screen”

Let users know what to ask or guide their first input by changing the composer’s placeholder text.

const options: Partial<ChatKitOptions> = {
composer: {
placeholder: "Ask anything about your data…",
},
startScreen: {
greeting: "Welcome to FeedbackBot!",
},
};

Guide users on what to ask or do by suggesting prompt ideas when starting a conversation.

const options: Partial<ChatKitOptions> = {
startScreen: {
greeting: "What can I help you build today?",
prompts: [
{
name: "Check on the status of a ticket",
prompt: "Can you help me check on the status of a ticket?",
icon: "search"
},
{
name: "Create Ticket",
prompt: "Can you help me create a new support ticket?",
icon: "write"
},
],
},
};

Custom header buttons help you add navigation, context, or actions relevant to your integration.

const options: Partial<ChatKitOptions> = {
header: {
customButtonLeft: {
icon: "settings-cog",
onClick: () => openProfileSettings(),
},
customButtonRight: {
icon: "home",
onClick: () => openHomePage(),
},
},
};

Attachments are disabled by default. To enable them, add attachments configuration. Unless you are doing a custom backend, you must use the hosted upload strategy. See the Python SDK docs for more information on other upload strategies work with a custom backend.

You can also control the number, size, and types of files that users can attach to messages.

const options: Partial<ChatKitOptions> = {
composer: {
attachments: {
uploadStrategy: { type: 'hosted' },
maxSize: 20 * 1024 * 1024, // 20MB per file
maxCount: 3,
accept: { "application/pdf": [".pdf"], "image/*": [".png", ".jpg"] },
},
},
}

Enable @mentions in the composer with entity tags

Section titled “Enable @mentions in the composer with entity tags”

Let users tag custom “entities” with @-mentions. This enables richer conversation context and interactivity.

  • Use onTagSearch to return a list of entities based on the input query.
  • Use onClick to handle the click event of an entity.
const options: Partial<ChatKitOptions> = {
entities: {
async onTagSearch(query) {
return [
{
id: "user_123",
title: "Jane Doe",
group: "People",
interactive: true,
},
{
id: "document_123",
title: "Quarterly Plan",
group: "Documents",
interactive: true,
},
]
},
onClick: (entity) => {
navigateToEntity(entity.id);
},
},
};

You can customize the appearance of entity tags on mouseover using widgets. Show rich previews such as a business card, document summary, or image when the user hovers over an entity tag.

Something about using widget studio should go here.

const options: Partial<ChatKitOptions> = {
entities: {
async onTagSearch() { /* ... */ },
onRequestPreview: async (entity) => ({
preview: {
type: "Card",
children: [
{ type: "Text", value: `Profile: ${entity.title}` },
{ type: "Text", value: "Role: Developer" },
],
},
}),
},
};

Enhance productivity by letting users trigger app-specific actions from the composer bar. The selected tool will be sent to the model as a tool preference.

Link to docs on tools.

const options: Partial<ChatKitOptions> = {
composer: {
tools: [
{
id: 'add-note',
label: 'Add Note',
icon: 'write',
pinned: true,
},
],
},
};

Disable major UI regions / features.

  • Disabling the header can be useful when you need more customization over the options that are available in the header and want to implement your own.
  • Disabling history can be useful when the concept of threads/history doesn’t make sense for your use case, e.g. a support chatbot.
const options: Partial<ChatKitOptions> = {
history: { enabled: false },
header: { enabled: false },
};

Override the default locale e.g. if you have an app-wide language setting. By default the locale is set to the browser’s locale.

const options: Partial<ChatKitOptions> = {
locale: 'de-DE',
};