Customization
You can fully customize almost any aspect of the look and behavior of your TalkJS chat. This page gives you an overview of different ways to customize your chat when using React components, such as Chatbox
and ConversationList
.
Method | Description |
---|---|
Component props and events | Use the props and events that components expose to customize the component’s styling and behavior. |
Custom styles | Change the look and feel of your chat with custom styles. |
Custom theme components | Modify the styles, markup, and behavior of individual theme components. |
Custom theme | Take complete control over how your chat looks and behaves. You can fork the default theme as a starting point and change anything you want. |
Change behavior without modifying themes | Attach plain JavaScript event handlers to change a theme's behavior. |
A TalkJS theme is a collection of React components that make up the chat interface. The default theme works beautifully out of the box, but you can extend or replace parts of it to better fit your own styles and desired behavior.
The easiest way to customize TalkJS is using the props and events that the components expose. See each component’s reference documentation for a list of available props:
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.
You'll want to ensure 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 then ensure that these styles are loaded 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.
The components let you pass in a theme. You can import the default theme, and then override just the components you want to customize. A theme is just an object mapping component names to React components.
Customizing a theme component allows you to override specific parts of the UI without forking the entire theme.
Here's an example that shows how to override a single theme component, in this case the ChatHeader
component:
1import { useMemo } from 'react';2import { Chatbox, defaultTheme } from '@talkjs/react-components';3import '@talkjs/react-components/default.css';45function MyChatbox() {6 // Create an object with components to override, memoized so that it doesn't cause unnecessary re-renders.7 const theme = useMemo(() => ({ ChatHeader: MyChatHeader }), []);89 // Now use the modified theme when rendering the chatbox.10 return (11 <Chatbox12 appId="YOUR_APP_ID"13 theme={theme}14 userId="sample_user_alice"15 conversationId="sample_conversation"16 />17 );18}1920// Your own ChatHeader component. You can also style this with CSS, just like you would any other component in your app.21function MyChatHeader(props) {22 // You can grab other components from the default theme, and use them in your own component.23 const { ConversationImage } = defaultTheme;24 return (25 <div className="my-chat-header">26 <ConversationImage common={props.common} />27 {/* ... any other markup you want */}28 </div>29 );30}
If you'd like to make extensive changes to the theme, to fully make it your own, you can grab a copy of the default theme, and copy it into your app.
Download the latest version's zip archive from GitHub, and copy the contents into your project.
Assuming you've placed the theme files in a folder called my-theme
, you can import it and pass it to the theme
prop when rendering the chatbox:
1import { Chatbox } from '@talkjs/react-components';2import '@talkjs/react-components/default.css';34import * as myTheme from './my-theme';56function MyChatbox() {7 // Now use the modified theme when rendering the chatbox.8 return (9 <Chatbox10 appId="YOUR_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.
The recommended ways to change a component's behavior are to modify its external props and events, customize specific theme components, or to fork and customize the theme entirely. However, if that doesn't work for your use case, you can use plain JavaScript to change a theme's behavior. This approach goes a bit against the spirit of most frontend frameworks, but it can be very effective for specific cases.
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. 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}
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.