Skip to Content

Custom Components

reachat is completely customizable. You can change the look and feel of the chat by customizing the theme or by providing your own components. Components can even be overriden using slots .

Custom Components Example

Below is example markup that creates a custom session empty message and also provides a custom session list item.

const CustomMessageQuestion: FC<any> = ({ question, files }) => ( <> <span className="text-lg font-semibold text-blue-500"> This is my question: {question} </span> <MessageFiles files={files}> <CustomMessageFile /> </MessageFiles> </> ); const CustomMessageResponse: FC<any> = ({ response }) => ( <blockquote className="border-l border-blue-500 pl-2"> This is the response: {response} </blockquote> ); const CustomMessageFile: FC<any> = ({ name, type }) => ( <Chip size="small" className="rounded-full border border-gray-700"> {name || type} </Chip> ); const CustomMessageSource: FC<any> = ({ title, url, image }) => { const { theme } = useContext(ChatContext); return ( <Chip size="small" className="rounded-full border border-blue-500 border-opacity-50" onClick={() => alert('take me to ' + url)} start={ image && ( <img src={image} alt={title} className={cn(theme.messages.message.sources.source.image)} /> ) } > {title || url} </Chip> ); }; const CustomSessionListItem: FC<SessionListItemProps> = ({ session, children, ...rest }) => { const [open, setOpen] = useState(false); const btnRef = useRef(null); return ( <> <ListItem {...rest} end={ <IconButton ref={btnRef} size="small" variant="text" onClick={e => { e.stopPropagation(); setOpen(true); }} > <MenuIcon /> </IconButton> } > <span className="truncate">{session.title}</span> </ListItem> <Menu open={open} onClose={() => setOpen(false)} reference={btnRef} appendToBody={false} > <Card disablePadding> <List> <ListItem onClick={() => alert('rename')}>Rename</ListItem> <ListItem onClick={() => alert('delete')}>Delete</ListItem> </List> </Card> </Menu> </> ); };

Then in the master component you can leverage them like:

export const CustomComponents = () => { return ( <div style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, padding: 20, margin: 20, background: '#02020F', borderRadius: 5 }} > <Chat sessions={[ ...fakeSessions, ...sessionsWithFiles, ...sessionWithSources ]} activeSessionId="1" > <SessionsList> <NewSessionButton> <button className="text-blue-500">New Session</button> </NewSessionButton> <Divider variant="secondary" /> <SessionGroups> {groups => groups.map(({ heading, sessions }) => ( <SessionsGroup heading={heading} key={heading}> {sessions.map(s => ( <SessionListItem key={s.id} session={s}> <CustomSessionListItem session={s} /> </SessionListItem> ))} </SessionsGroup> )) } </SessionGroups> </SessionsList> <SessionMessagePanel> <SessionMessagesHeader> <CustomMessagesHeader /> </SessionMessagesHeader> <SessionMessages> {conversations => conversations.map((conversation, index) => ( <SessionMessage conversation={conversation} isLast={index === conversations.length - 1} key={conversation.id} > <MessageQuestion question={conversation.question} files={conversation.files} > <CustomMessageQuestion /> </MessageQuestion> <MessageResponse response={conversation.response}> <CustomMessageResponse /> </MessageResponse> <MessageSources sources={conversation.sources}> <CustomMessageSource /> </MessageSources> <MessageActions question={conversation.question} response={conversation.response} /> </SessionMessage> )) } </SessionMessages> <ChatInput /> </SessionMessagePanel> </Chat> </div> ); };

Using SessionContext

The SessionContext hook provides access to the current session state and methods to interact with it. Here’s how you can use it:

import { useSessionContext } from 'reachat'; const CustomSendButton = () => { const { sendMessage } = useSessionContext(); const handleSend = () => { sendMessage('Hello, AI!'); return <button onClick={handleSend}>Send Custom Message</button>; }; };

The SessionContext hook provides the following properties and methods:

export interface SessionContextProps { sessions: Session[]; activeSessionId: string | null; theme?: ChatTheme; isLoading?: boolean; activeSession?: Session | null; remarkPlugins?: PluggableList[]; selectSession?: (sessionId: string) => void; deleteSession?: (sessionId: string) => void; createSession?: () => void; }

By using these overrides and the SessionContext hook, you can create a fully customized chat experience while still leveraging the core functionality of reachat.

Last updated on