Skip to Content

Getting Started

In this example, we are going to walk through setting up reachat in your project and creating your first chatbot. This guide assumes you’ve already followed the steps in Setup to install the package.

By now, you should have the basic building blocks for the chat component with minimal styling, and no functionality. Let’s add some basic functionality to the chat component. For now, we’ll just use state variables to simulate creating and deleting sessions as well as starting conversations.

Creating a new session

We’ll start by adding the ability to create a new session by adding a onNewSession handler:

const [sessions, setSessions] = useState<Session[]>([]); const handleNewSession = () => { const newId = (sessions.length + 1).toString(); setSessions([ ...sessions, { id: newId, title: `New Session #${newId}`, createdAt: new Date(), updatedAt: new Date(), conversations: [], }, ]); }; return ( <Chat sessions={sessions} onNewSession={handleNewSession}> <SessionsList> <NewSessionButton /> <SessionGroups /> </SessionsList> <SessionMessagePanel> <SessionMessagesHeader /> <SessionMessages /> <ChatInput /> </SessionMessagePanel> </Chat> );

Selecting a session

Now we want to be able to select the new session that we created. Again, we’ll handle this with a state variable - activeSessionId.

const [activeSessionId, setActiveSessionId] = useState<string>(); ... return ( <Chat sessions={sessions} activeSessionId={activeSessionId} onNewSession={handleNewSession} onSelectSession={setActiveSessionId} > <SessionsList> <NewSessionButton /> <SessionGroups /> </SessionsList> <SessionMessagePanel> <SessionMessagesHeader /> <SessionMessages /> <ChatInput /> </SessionMessagePanel> </Chat> );

Deleting a session

Let’s handle deleting the session that we created by passing an onDeleteSession prop to the Chat component. We’ll also check to see if we need to reset the activeSessionId if the session we are deleting is the one that is currently active.

const handleDeleteSession = (id: string) => { setSessions(sessions.filter((session) => session.id !== id)); if (id === activeSessionId) { setActiveSessionId(undefined); } }; ... return ( <Chat sessions={sessions} activeSessionId={activeSessionId} onNewSession={handleNewSession} onSelectSession={setActiveSessionId} onDeleteSession={handleDeleteSession} > <SessionsList> <NewSessionButton /> <SessionGroups /> </SessionsList> <SessionMessagePanel> <SessionMessagesHeader /> <SessionMessages /> <ChatInput /> </SessionMessagePanel> </Chat> );

Handling session conversations

Now that we can create, select, and delete sessions, let’s add the ability to start a new conversation. We’ll need to add an onSendMessage handler here to handle adding conversations to the active session. We’ll just use a simple example response for now, but in a real application, you would likely be making a request to a backend service here.

Note: you can also optionally add an onStopMessage handler to handle stopping a message that is currently being sent.

We can also handle loading state here and pass isLoading prop to the component.

const [loading, setLoading] = useState<boolean>(false); const handleNewMessage = (message: string) => { setLoading(true); const current = sessions.find((s) => s.id === activeSessionId); if (current) { const newMessage: Conversation = { id: `${current.id}-${current.conversations.length}`, question: message, response: "this is an example response", createdAt: new Date(), updatedAt: new Date(), }; const updated = { ...current, conversations: [...current.conversations, newMessage], }; setSessions([ ...sessions.filter((s) => s.id !== activeSessionId), updated, ]); } setLoading(false); }; ... return ( <Chat sessions={sessions} activeSessionId={activeSessionId} onNewSession={handleNewSession} onSelectSession={setActiveSessionId} onDeleteSession={handleDeleteSession} onSendMessage={handleNewMessage} isLoading={loading} > <SessionsList> <NewSessionButton /> <SessionGroups /> </SessionsList> <SessionMessagePanel> <SessionMessagesHeader /> <SessionMessages /> <ChatInput /> </SessionMessagePanel> </Chat> );

Styling

Besides functionality, of course, styling would be one of the first things that comes to mind. There is a default theme that you can customize with basic colors by defining design tokens in your CSS with Tailwind v4’s @theme directive.

For example, if we wanted to change the default blue to a purple, we could override the primary color tokens like this:

@theme { --color-primary: #a855f7; /* purple-500 */ --color-primary-hover: #9333ea; /* purple-600 */ --color-secondary: #d8b4fe; /* purple-300 */ }

To customize chat specific styles, add a theme.ts file which extends the chatTheme object.

import { chatTheme as defaultTheme, ChatTheme } from "reachat"; import { twMerge } from "tailwind-merge"; export const chatTheme: ChatTheme = { ...defaultTheme, sessions: { ...defaultTheme.sessions, console: twMerge(defaultTheme.sessions.console, "min-w-[300px]"), session: { ...defaultTheme.sessions.session, delete: "[&>svg]:w-4 [&>svg]:h-4 opacity-70 hover:opacity-100 transition-opacity", }, }, messages: { ...defaultTheme.messages, base: "py-4 pr-4", message: { ...defaultTheme.messages.message, question: twMerge( defaultTheme.messages.message.question, "text-purple-300 text-lg", ), response: "border-l border-purple-300 pl-4", }, }, };

Then pass the exported chatTheme to your <Chat /> component.

<Chat sessions={sessions} activeSessionId={activeSessionId} onNewSession={handleNewSession} onSelectSession={setActiveSessionId} onDeleteSession={handleDeleteSession} onSendMessage={handleNewMessage} isLoading={loading} theme={chatTheme} > <SessionsList> <NewSessionButton /> <SessionGroups /> </SessionsList> <SessionMessagePanel> <SessionMessagesHeader /> <SessionMessages /> <ChatInput /> </SessionMessagePanel> </Chat>

…and that’s it!

That’s the basics of getting things off the ground. But there’s plenty more you can do with the Reachat building blocks. It handles the hard bits for you:

  • Markdown display with custom remark plugins
  • Multi-file uploads with type-aware renderers (images, CSV, PDF, etc.)
  • Source citations
  • Auto-scroll and scroll-to-bottom interactions
  • @ mentions and / slash commands
  • LLM-driven UI via the Component Catalog
  • Mobile/companion mode

so you can focus on building out a chat experience tailored to your users.

Example repo

We’ve created a example repo  that demonstrates the previous example that you can clone and run locally to get you started.

Advanced options

Most components in the chat tree are slot-based — you can swap them out for your own React components without giving up the rest of reachat’s behavior. See the Custom Components guide and the matching storybook demo  for examples.