React Chatbot UI — Guide to build one from scratch

Kevin Wong
5 min readFeb 4, 2024

--

chatbot UI — Bing Image Creator Dall-E 3 generated

I have been building some chatbot UI over the past few months and I have gain much insight I want to share about how to build one that closely resembles a ChatGPT or Bard AI type of chat console on the web.

In this article, I will demonstrate the steps to archieve building a simple chatbot UI from scratch using ReactJS.

Requirements

Let’s first look at the breakdown of a chatGPT chat window on the front-end web side.

There are a few major components to identify:

  • The chat input and submission button
  • The chat conversation log and some loading state
  • The individual chat message that includes the avatar and name

Here we will ignore the saved conversation features for another article as we try to focus on the chat interaction here.

So from the requirements above we can deduce an API-first approach and design the props input to this component and strategize on how to do a decomposition exercise of the UI into separate reusable components.

/** defining data types **/

export type User = {
firstName: string;
lastName: string;
avatarUrl?: string;
};

export type Message = {
id: string;
role: MessageRole;
message: string;
userInfo?: User;
};

export type Conversations = Array<Message>;

/** defining component interfaces **/

export interface IChatUIProps {
isQuerying: boolean;
onSubmit: (value) => void;
placeholder: string;
disabled: boolean;
conversations: Conversations;
customSubmitIcon?: ReactNode;
}

export interface IChatInputProps {
disabled: boolean;
onSubmit: (value) => void;
placeholder: string;
customSubmitIcon?: ReactNode;
}

export interface IChatConversationsProps {
conversations: Conversations;
isQuerying: boolean;
}

export interface IChatMessageProps {
message: Message;
}

So to describe the types above:

MessageRole:

  • It is assumed that the chat conversation has 3 different type of messages. system, assistant and user messages. Although they might not be passed back with the same format from different AI conversational services, the system can transform and map it back into this structure.

User:

  • This is the avatar and the name part of the message to render the message header

Message:

  • A message consists of the message
  • User information of the message header as defined above with the user type

Conversations:

  • The conversation here is nothing more than a list of Messages
  • If it’s querying for data. An input is needed to know whether to show a loading indicator

IChatUIProps:

In order to make the the component generic and reusable for other developers, some inputs needs to be considered to have some configurability:

  1. a configurable placeholder text for the input field
  2. a callback function to process data when a message is submitted
  3. a custom submit icon for the submit button
  4. a list of messages to display
  5. a boolean value to tell if the chat UI is currently querying for an answer to show a loading state
  6. isQuerying property to block the user from further input until it is ready again

IChatInputProps:

This will be a subcomponent of the chat UI parent component. This component will be the bottom section where the user interacts to submit text input.

So this is just a transitive subset of input from the parent component

  1. a configurable placeholder text for the input field
  2. a callback function to process data when a message is submitted
  3. a custom submit icon for the submit button
  4. a disabled input property to whether allow for submission

IChatConversationsProps:

This will be be the conversational log section on the top section of the chat UI. It will need the following information:

  1. a boolean value to tell if the chat UI is currently querying for an answer to show a loading state
  2. The conversation list of all the messages.

IChatMessageProps:

This will be the subcomponent of the ChatConversations component. The ChatConversations component is just a composition of ChatMessage components to display all the results.

What it needs is to display individual messages:

  1. user first name and last name if avatar url doesn’t exist to construct the avatar circle indicator
  2. The user’s name to display
  3. The message text.

Building it

From here on it’s simple composition of CSS/HTML and ReactJS code to construct the final result. Defining the props and strategizing using an API-first approach makes the development part easier. I have enlisted some extra dependencies with TailwindCSS, DaisyUI and react-daisyui to abstract some of the UI complexity so we can focus on building a functional UI.

Demo

Live demo:

And the final result…. a ChatGPT wannabe UI.

A working chatbot UI

Source:

Final thoughts

Here we have a simple chatbot UI solution. It is by no means an in-depth comprehensive solution but it’s a base to start. There are many other enhancement to consider such as:

  1. Saved chat section mentioned above.
  2. Support for Markdown from assistant messages.
  3. Support user-experience improvements such as interactive typewriter assistant message output when the message or part of the message is ready to be displayed.
  4. Adjusting the input height as the user types lots of content in.
  5. Suggestions prompts
  6. Voice input as described using the Web SpeechRecognition API from my previous article
  7. Possibilities are endless.

I hope this guide has helped you understand how to get started building chatbot UIs. In future articles, I love to go deeper into other user-experience enhancement of chatbots and how to implement some cool feature ideas on top of this base implementation. This effort also did not include unit tests as well as I plan to write a separate article and use this mini-project to write unit-tests coverage with AI. Stay tuned.

--

--

Kevin Wong

Software Engineer and Technology Enthusiast based out of Vancouver, British Columbia. (https://www.linkedin.com/in/kevinkswong/)