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 options | Component props and events |
| Change default styles | Custom styles (CSS override) |
| Change the design or behavior of a single part of the UI | Customize a single theme component |
| Change the design or behavior of the whole UI | Create a custom theme |
| Add custom behavior without modifying a theme | Custom behavior (plain JavaScript) |
A TalkJS theme is a collection of React components that make up the chat interface. The default theme works beautifully out of the box. You can extend or replace parts of it to better fit your own styles and desired behavior.
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:
The following example uses the chatHeaderVisible prop on the Chatbox to hide the ChatHeader component.
1import { Chatbox } from '@talkjs/react-components';2import '@talkjs/react-components/default.css';34export default function App() {5 return (6 <Chatbox7 appId="<APP_ID>"8 userId="sample_user_alice"9 conversationId="sample_conversation"10 chatHeaderVisible={false}11 />12 );13}
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.
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:

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.t-chatbox .t-theme-message[t-sender='currentUser'] .t-message-body {2 background-color: rgb(255, 98, 0);3 border-color: rgb(255, 98, 0);4}
This approach works for all TalkJS React components, since they render into the regular DOM and can be styled with standard CSS overrides.
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.
The following example shows how to create a custom ChatHeader component with a gradient background, starting from a basic chatbox setup.
- Define a custom chat header component.
- When rendering the chatbox, pass a
themeoption that contains your custom chat header. This overrides the defaultChatHeader.
For example as follows:
1import { useMemo } from 'react';2import { Chatbox } from '@talkjs/react-components';3import '@talkjs/react-components/default.css';4import './chat-header.css';56function MyChatHeader() {7 return <div className="my-chat-header">Welcome to the chat!</div>;8}910export default function App() {11 // Use useMemo so the theme object stays stable between renders.12 const theme = useMemo(13 () => ({14 ChatHeader: MyChatHeader,15 }),16 []17 );1819 return (20 <Chatbox21 appId="<APP_ID>"22 userId="sample_user_alice"23 conversationId="sample_conversation"24 theme={theme}25 />26 );27}
You now have a custom chat header component for your theme. When you override a single theme component like this, all other theme components continue to use the default theme.
For a full interactive example, check out the custom ChatHeader example in the TalkJS Sandbox.
To fully customize your chat UI, you can create a custom theme. To create a custom theme:
- Download the latest version of the default theme's zip archive from GitHub, and copy the contents into your project.
- Find your current TalkJS
default.cssimport and replace it withbase.css, and then import your theme's styles and JavaScript. - Pass your theme to the
themeprop when rendering the chatbox.
You're now using your own custom theme in your chat.
If you're using VS Code, you might find the lit-html plugin helpful. lit-html adds syntax highlighting and language support for HTML inside the theme template strings, which can make creating a custom theme a lot easier.
The following example assumes you've placed the theme files in a folder called my-theme.
1import { Chatbox } from '@talkjs/react-components';2import '@talkjs/react-components/base.css';3import './my-theme/index.css';4import * as myTheme from './my-theme';56function MyChatbox() {7 // Now use the modified theme when rendering the chatbox.8 return (9 <Chatbox10 appId="<APP_ID>"11 theme={myTheme}12 userId="sample_user_alice"13 conversationId="sample_conversation"14 />15 );16}
The theme folder contains a number of JavaScript files. Each of these files exports a React component that represents a part of the chat interface. You can freely modify these components or add your own to create a fully customized theme.
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.
For example, if you want to capture clicks on a message avatar picture, you can do something like the following:
1function Chat({conversationId}) {2 const ref = useRef();34 useEffect(() => {5 async function click(event) {6 const target = event.target;7 if(target.matches(".t-theme-message .t-theme-avatar")) {8 const messageId = target9 .closest(".t-theme-message")10 .getAttribute("t-message-id");1112 console.log("Clicked on avatar for message " + messageId);13 // Do something with messageId, for example, fetch the sender with14 // the JavaScript Data API, or perform another action.15 }16 }17 ref.current.addEventListener("click", click);18 return () => ref.current.removeEventListener("click", click);19 }, []);2021 return <Chatbox ref={ref} conversationId={...}/>;22}
Do you have any questions about customizing your chat UI? Members of the TalkJS dev team are happy to support. Get in touch.
- Theme reference overview
- Code sandbox with custom theme components
- Code samples