Customization

You can fully customize almost any aspect of the look and behavior of your TalkJS chat UI. This page gives you an overview of ways to customize your chat.

Not sure where to start? Use the following table to choose the simplest customization approach that fits your use case.

If you want to ...Use this approach
Change built-in configuration optionsComponent props and events
Change default stylesCustom styles (CSS override)
Change the design or behavior of a single part of the UICustomize a single theme component
Change the design or behavior of the whole UICreate a custom theme
Add custom behavior without modifying a themeCustom behavior (plain JavaScript)

What's a theme?

A TalkJS theme is a collection of React components that make up the chat interface. The default theme works beautifully out of the box. Even though TalkJS themes are implemented with React components, you can easily customize them in any framework, as described in the following sections.

Component props and events

Many customizations are possible out of the box, just by passing different props and event handlers to TalkJS components. For an overview of available props, check out the reference docs for each top-level component:

Example

The following example uses the chat-header-visible prop on the t-chatbox to hide the ChatHeader component.

1<t-chatbox
2 app-id="<APP_ID>" // Use your own TalkJS app ID
3 user-id="sample_user_alice"
4 conversation-id="sample_conversation"
5 chat-header-visible="false">
6</t-chatbox>

Custom styles (CSS override)

You can inspect any component using your browser's developer tools to inspect the markup and see which styles are applied. You can add CSS to your own page to override the styles that are applied by the theme.

Make sure that your CSS selectors have the same or higher specificity as the selectors of the theme. The easiest way to do so is to just copy a selector from the developer tools, and load your custom styles after TalkJS components. When multiple CSS selectors have the same specificity, the last one wins.

Example

For example, if you want messages sent by the current user to have an orange background that matches your brand, inspect the message element in the developer tools. You’ll get something like the following:

The browser developer tools showing the styles for a message

You can now copy the selector, and modify the properties you want. For example, add some CSS to your page to set the message background and border:

1/* Add to a CSS stylesheet that's loaded after TalkJS styles */
2t-chatbox .t-theme-message[t-sender='currentUser'] .t-message-body {
3 background-color: rgb(255, 98, 0);
4 border-color: rgb(255, 98, 0);
5}

Customize a single theme component

You can create your own custom version of a theme component by overriding the corresponding default component. To override a single component, pass a theme option containing an object with the component you want to override.

Example

Theme components are written in Preact, a lightweight alternative to React featuring the same API but with a tiny bundle size. We also use the htm library through our html helper to use JSX-like syntax in plain JavaScript, without needing a build step.

The following example shows how to override a single theme component, in this case the ChatHeader. It also demonstrates how to use the html helper to specify markup. Take these steps:

  1. Define a custom chat header component.
  2. When rendering the chatbox, pass a theme option that contains your custom chat header. This overrides the default ChatHeader.

For example as follows:

1<head>
2 <link
3 rel="stylesheet"
4 href="https://cdn.jsdelivr.net/npm/@talkjs/[email protected]/default.css"
5 />
6 <style>
7 .my-chat-header {
8 display: flex;
9 justify-content: center;
10 padding: 25px;
11 background:
12 linear-gradient(to bottom, rgba(205, 248, 223, 1), rgba(255, 255, 255, 0));
13 font-size: 16px;
14 font-weight: bold;
15 }
16 </style>
17 <script type="importmap">
18 {
19 "imports": {
20 "@talkjs/web-components": "https://cdn.jsdelivr.net/npm/@talkjs/[email protected]",
21 "@talkjs/core": "https://cdn.jsdelivr.net/npm/@talkjs/[email protected]"
22 }
23 }
24 </script>
25 <script type="module">
26 import "@talkjs/web-components";
27 import { html } from "@talkjs/web-components";
28
29 // Custom theme components must be React components
30 // Use the `html` helper to create component functions
31 // that return React elements.
32 function MyChatHeader() {
33 return html`
34 <div class="my-chat-header">
35 Welcome to the chat!
36 </div>
37 `;
38 }
39
40 const chatbox = document.querySelector("t-chatbox");
41 chatbox.theme = { ChatHeader: MyChatHeader}
42 </script>
43</head>
44<body>
45 <t-chatbox
46 app-id="<APP_ID>"
47 user-id="sample_user_alice"
48 conversation-id="sample_conversation"
49 ></t-chatbox>
50</body>

In this example, replace <APP_ID> with your TalkJS app ID. You can find your app ID in the Settings tab of the TalkJS dashboard.

Add state and effects

To add state and effects to your component, you can import Preact from @talkjs/web-components. For example as follows:

1import { html, Preact } from "@talkjs/web-components";
2
3const { useState, useEffect } = Preact;
4
5function MyChatHeader(props) {
6 const [value, setValue] = useState(1);
7
8 useEffect(() => {
9 console.log("Current value:", value);
10 }, [value]);
11
12 return html`
13 ...
14 `;
15}

Adding state and effects works using Preact.

Custom theme

To make a theme to fully your own, you can grab a copy of the default theme, and copy it into your app.

If you're using VS Code, you might find the lit-html plugin helpful, which adds syntax highlighting and language support for html inside the theme template strings. This can make creating a custom theme a lot easier.

Take the following steps:

  1. Download the latest version's zip archive from GitHub, and copy the contents into your project.
  2. Find your current TalkJS default.css import, replace it with base.css, and then import your theme's styles and Javascript.
  3. Assign your custom theme object to the chatbox. In plain JS + HTML, do this in JavaScript. If you're using a framework, you can pass your theme via the theme prop when rendering the chatbox.

TalkJS now uses your own custom theme, instead of the default theme.

The theme folder contains a number of JavaScript files, each of which exports a React component. TalkJS exposes a html helper that lets you create component functions that return React elements, without having to set up build tooling for JSX, while still using readable markup. It's a slightly modified version of the htm library.

You can add state and effects to your component using Preact. For an example, see: Add state and effects.

Example

The following example starts from a basic chatbox setup from the Getting started guide, and assumes you've placed the theme files in a folder called my-theme.

1<head>
2 <link
3 rel="stylesheet"
4 href="https://cdn.jsdelivr.net/npm/@talkjs/[email protected]/base.css"
5 />
6 <link
7 rel="stylesheet"
8 href="my-theme/index.css"
9 />
10<script type="importmap">
11 {
12 "imports": {
13 "@talkjs/web-components": "https://cdn.jsdelivr.net/npm/@talkjs/[email protected]",
14 "@talkjs/core": "https://cdn.jsdelivr.net/npm/@talkjs/[email protected]"
15 }
16 }
17</script>
18<script type="module" async>
19 import "@talkjs/web-components";
20 import * as myTheme from './my-theme/index.js';
21
22 const chatbox = document.querySelector("t-chatbox");
23 chatbox.theme = myTheme;
24</script>
25</head>
26<body>
27 <t-chatbox
28 app-id="<APP_ID>"
29 user-id="sample_user_alice"
30 conversation-id="sample_conversation"
31></t-chatbox>
32</body>

Change behavior (plain JavaScript)

You can change the behavior of your chat UI in various ways. The recommended ways to change a chat UI component's behavior are:

That said, if these options don't work for your use case, you can use plain JavaScript to change the chat's behavior. This approach goes a bit against the spirit of most frontend frameworks, but it can be very effective for specific cases.

To change chat UI behavior with plain JavaScript, add a global event listener for clicks on the root UI element, and inside it, filter it down to the clicks you're interested in. The trick is to use event.target.matches() to narrow down which clicks you want to handle. This lets you listen for clicks on any matching element, even elements that appear later.

Example

For example, if you want to capture clicks on a message avatar picture, you can do something like the following:

1// Given HTML that looks like this:
2//
3// <t-chatbox conversation-id="..."></t-chatbox>
4
5const chatbox = document.querySelector('t-chatbox');
6chatbox.addEventListener('click', async (event) => {
7 if (event.target.matches('.t-theme-message .t-theme-avatar')) {
8 const messageEl = event.target.closest('.t-theme-message');
9 const messageId = messageEl.getAttribute('t-message-id');
10 console.log('Clicked on avatar for message ' + messageId);
11 // Do something with messageId, for example, fetch the sender with
12 // the JavaScript Data API, or perform another action.
13 }
14});

The trick is to use event.target.matches() to narrow down which clicks you want to handle. This lets you listen for clicks on any matching element, even elements that appear later.