Primary navigation

Legacy APIs

Theming and customization in ChatKit

Configure colors, typography, density, and component variants.

After following the ChatKit quickstart, learn how to change themes and add customization to your chat embed. Match your app’s aesthetic with light and dark themes, setting an accent color, controlling the density, and rounded corners.

Overview

At a high level, customize the theme by passing in an options object. If you followed the ChatKit quickstart to embed ChatKit in your frontend, use the React syntax below.

  • React: Pass options to useChatKit({...})
  • Advanced integrations: Set options with chatkit.setOptions({...})

In both integration types, the shape of the options object is the same.

Explore customization options

Visit ChatKit Studio to see working implementations of ChatKit and interactive builders. If you like building by trying things rather than reading, these resources are a good starting point.

Explore ChatKit UI

chatkit.world

Play with an interactive demo of ChatKit.

Widget builder

Browse available widgets.

ChatKit playground

Play with an interactive demo to learn by doing.

See working examples

Samples on GitHub

See working examples of ChatKit and get inspired.

Starter app repo

Clone a repo to start with a fully working template.

Change the theme

Match the look and feel of your product by specifying colors, typography, and more. Below, we set to dark mode, change colors, round the corners, adjust the information density, and set the font.

For all theming options, see the API reference.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const options: Partial<ChatKitOptions> = {
  theme: {
    colorScheme: "dark",
    color: {
      accent: {
        primary: "#2D8CFF",
        level: 2
      }
    },
    radius: "round",
    density: "compact",
    typography: { fontFamily: "'Inter', sans-serif" },
  },
};

Customize the start screen text

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

1
2
3
4
5
6
7
8
const options: Partial<ChatKitOptions> = {
  composer: {
    placeholder: "Ask anything about your data…",
  },
  startScreen: {
    greeting: "Welcome to FeedbackBot!",
  },
};

Show starter prompts for new threads

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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"
      },
    ],
  },
};

Add custom buttons to the header

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

1
2
3
4
5
6
7
8
9
10
11
12
const options: Partial<ChatKitOptions> = {
  header: {
    customButtonLeft: {
      icon: "settings-cog",
      onClick: () => openProfileSettings(),
    },
    customButtonRight: {
      icon: "home",
      onClick: () => openHomePage(),
    },
  },
};

Enable file attachments

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.

1
2
3
4
5
6
7
8
9
10
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

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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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);
    },
  },
};

Customize how entity tags appear

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.

Widget builder

Browse available widgets.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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" },
        ],
      },
    }),
  },
};

Add custom tools to the composer

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.

1
2
3
4
5
6
7
8
9
10
11
12
const options: Partial<ChatKitOptions> = {
  composer: {
    tools: [
      {
        id: 'add-note',
        label: 'Add Note',
        icon: 'write',
        pinned: true,
      },
    ],
  },
};

Toggle UI regions and features

Disable major UI regions and features if you need more customization over the options available in the header and want to implement your own instead. Disabling history can be useful when the concept of threads and history doesn’t make sense for your use case—e.g., in a support chatbot.

1
2
3
4
const options: Partial<ChatKitOptions> = {
  history: { enabled: false },
  header: { enabled: false },
};

Override the locale

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

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