Build AI ChatBot App in ReactJS | ChatBot Like ChatGPT & Gemini AI


Welcome to my website U-GINE MEDIA. In this website I teach tutorials and share source code on some programming (HTML, CSS, JavaScript, React) tutorials. 

Before we get started, do well to subscribe to my channel to never miss out on any update that I post every single day.

You can also visit my GitHub where I upload all the code I have.

In this tutorial topic "Build AI ChatBot App in ReactJS | ChatBot Like ChatGPT & Gemini AI", we will learn how to create it following these simple easy steps.

Share this to your programmer friends. If y'all learnt something today, make sure to let me in the comments. 

Get Source Code.

If interested in watching the video before running the code below, you can click the play button to get started.



Setting Up the Project

Before building the "ChatBot App" with React.js and CSS, ensure Node.js is installed on your computer. If not, download and install it from the official Node.js website.

Create a Project Folder:

  1. Make a new folder, for instance, “”.
  2. Open this folder in your VS Code editor.

Initialize the Project:

Open your terminal by pressing Ctrl + J and then use Vite to create a new React app with this command:

  npm create vite@latest ./ -- --template react


Install necessary dependencies and start the development server:

npm install
npm run dev

If your project is running in your browser, congratulations! You’ve successfully set up your weather app. Now, let’s move on to modifying folders and files.

Modify folder and CSS Files:

  1. Remove the default assets folder and App.css file.
  2. Replace the content of index.css with the provided CSS code.

  @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap");

/* Global Styles */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: "Poppins", sans-serif;
}

body {
  background: #f3f4f6; /* Soft gray background */
}

.chat-container {
  display: flex;
  height: 100vh;
}

/* Sidebar */
.sidebar {
  width: 250px;
  background: linear-gradient(-90deg, #6366f1, #4338ca); /* Purple gradient */
  color: #fff;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.logo {
  margin: 20px;
  font-size: 1.5rem;
  margin-bottom: 2rem;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 0.2em;
}

.logo img {
  width: 35px;
}

.logo span {
  background: linear-gradient(to right, #cf94e9, #61bcd5);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.channels {
  flex: 1;
  margin: 20px;
}

.channel {
  margin: 10px 0;
  cursor: pointer;
  opacity: 0.8;
  padding: 10px 20px;
  border-radius: 8px;
  transition: 0.3s ease;
}

.channel:hover {
  opacity: 0.5;
  color: #111827;
  background: #f9fafb;
}

.channel.active {
  font-weight: 600;
  opacity: 1;
  color: #111827;
  background: #f9fafb;
}

.user-profile {
  display: flex;
  align-items: center;
  gap: 0.4em;
  padding: 10px 20px;
  margin: 20px;
  cursor: pointer;
  border-radius: 8px;
  transition: 0.5s ease;
}

.avatar {
  filter: invert(100%);
  transition: 0.3s ease;
}

.username {
  font-weight: 500;
  font-size: 1.1em;
}

.user-profile:hover {
  color: #111827;
  background: #f9fafb;
}

.user-profile:hover .avatar {
  filter: none;
}

/* Main Chat Area */
.chat-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: #fff;
  box-shadow: -2px 0 10px rgba(0, 0, 0, 0.05);
}

/* Chat Header */
.chat-header {
  padding: 20px;
  border-bottom: 1px solid #e5e7eb;
  background-color: #f9fafb;
}

.chat-header h2 {
  margin: 0;
  font-size: 1.4rem;
}

.topic {
  margin: 5px 0 0;
  font-size: 0.9rem;
  color: #6b7280;
}

/* Chat Messages */
.chat-messages {
  position: relative;
  flex: 1;
  padding: 20px;
  overflow-y: auto;
  background: #f3f4f6;
}

.message-bubble {
  max-width: 60%;
  padding: 10px 15px;
  margin-bottom: 15px;
  border-radius: 10px;
  line-height: 1.4;
}

.my-message {
  margin-left: auto;
  background: linear-gradient(135deg, #6366f1, #4338ca);
  color: #fff;
  text-align: right;
}

.other-message {
  background-color: #e2e8f0;
  color: #111827;
}

.message-user {
  font-weight: 600;
  margin-bottom: 5px;
}

.message-text {
  margin: 0;
}

.chat-messages button {
  position: sticky;
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);
  background: transparent;
  border: none;
  width: 40px;
  height: 40px;
  background: #979da8;
  border-radius: 50%;
  cursor: pointer;
  display: none;
  justify-content: center;
  align-items: center;
}

.chat-messages button img {
  width: 35px;
  filter: invert(100%);
}

/* Chat Input */
.chat-input {
  display: flex;
  padding: 10px 20px;
  border-top: 1px solid #e5e7eb;
  background-color: #f9fafb;
}

.chat-input input {
  flex: 1;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  padding: 12px 10px;
  outline: none;
  margin-right: 10px;
  font-size: 0.9em;
}

.chat-input button[disabled] {
  background: gray;
  opacity: 0.4;
  cursor: not-allowed;
}

.chat-input button {
  background: linear-gradient(135deg, #6366f1, #4338ca);
  border: none;
  color: #fff;
  padding: 10px 20px;
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.3s ease;
}

.footer-message {
  text-align: center;
  font-size: 0.8em;
  padding: 2px 0;
}
  
  

Creating the Components

Within the src directory of your project, organize your files by creating a “components” folder. Inside the components folder, create the following files:
  1. Chat.jsx

Adding the Codes

Add the respective code to each newly created file to define the layout and functionality of your chatbot.

In src/Component.jsx, add the code.

import React, { useEffect, useState, useRef } from "react";
import logo from "../assets/logo.png";
import user from "../assets/user.png";
import arrowDownImg from "../assets/arrow-down.png";

const Chat = () => {
  // Chat messages (some initial sample messages)
  const [messages, setMessages] = useState([]);
  //Text Input Value
  const [inputValue, setInputValue] = useState("");
  //Set Is Loading State
  const [loading, setIsLoading] = useState(false);

  const handleAIResponse = async (userMessage) => {
    setIsLoading(true);
    try {
      //Replace Key with your own API Key
      const response = await fetch(
        `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=${
          import.meta.env.VITE_API_KEY
        }`,
        {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify({
            contents: [
              {
                parts: [
                  {
                    text: `${userMessage}`,
                  },
                ],
              },
            ],
          }),
        }
      );

      const data = await response.json();

      // Hypothetical AI-generated text from the Gemini API
      const aiMessage =
        data.candidates[0].content.parts[0].text ??
        "Sorry, I couldn't process that.";

      let index = 0;
      let tempText = "";
      const interval = setInterval(() => {
        tempText += aiMessage.charAt(index);
        setMessages((prev) => {
          const newMessages = [...prev];
          if (newMessages[newMessages.length - 1]?.type === "bot") {
            newMessages[newMessages.length - 1].text = tempText;
          } else {
            newMessages.push({
              id: prev.length + 1,
              type: "bot",
              user: "SkylineGPT",
              text: tempText,
            });
          }
          return newMessages;
        });
        index++;
        if (index >= aiMessage.length) clearInterval(interval);
      }, 10);
    } catch (error) {
      setMessages((prev) => [
        ...prev,
        {
          id: prev.length + 1,
          type: "bot",
          user: "SkylineGPT",
          text: "Oops! Something went wrong.",
        },
      ]);
    } finally {
      setIsLoading(false);
    }
  };

  //Send message and get AI response;
  const handleSend = async () => {
    if (inputValue.trim() === "") return;

    const newMessage = {
      id: messages.length + 1,
      type: "user",
      user: "Me",
      text: inputValue,
    };

    //Add user message to chat;
    setMessages((prev) => [...prev, newMessage]);
    setInputValue("");

    //Call AI response function
    await handleAIResponse(inputValue);
  };

  //Make a reference to the chat Message
  const chatMessages = useRef(null);

  // Scrolls the chat container to the bottom smoothly.
  // This is useful for keeping the latest messages in view
  // when a new message is added.
  const handleChatScroll = () => {
    chatMessages.current.scrollTo({
      top: chatMessages.current.scrollHeight,
      behavior: "smooth",
    });
  };

  useEffect(() => {
    // Adds a scroll event listener to the chatMessages container.
    // When the user scrolls, it displays the "arrowDown" element,
    // which could be used as a scroll-to-bottom indicator.
    if (chatMessages.current) {
      chatMessages.current.addEventListener("scroll", (e) => {
        document.getElementById("arrowDown").style.display = "flex";
      });
    }
  }, []);

  return (
    <div className="chat-container">
      {/* Sidebar */}
      <aside className="sidebar">
        <h2 className="logo">
          <img src={logo} alt="logo" /> <span>SkylineGPT</span>
        </h2>
        <div className="channels">
          <p className="channel active">General</p>
          <p className="channel">Tech Talk</p>
          <p className="channel">Design</p>
        </div>
        <div className="user-profile">
          <img src={user} alt="User Avatar" className="avatar" />
          <span className="username">You</span>
        </div>
      </aside>

      {/* Main Chat Area */}
      <main className="chat-main">
        <header className="chat-header">
          <h2>General</h2>
          <p className="topic">Chat about anything and everything!</p>
        </header>

        <section className="chat-messages" ref={chatMessages}>
          {messages.map((msg) => (
            <div
              key={msg.id}
              className={`message-bubble ${
                msg.user === "Me" ? "my-message" : "other-message"
              }`}
            >
              <p className="message-user">{msg.user}</p>
              <p className="message-text">{msg.text}</p>
            </div>
          ))}
          {loading && (
            <div className="message-bubble other-message">
              <p className="message-user">SkylineGPT</p>
              <p className="message-text">Generating Response...</p>
            </div>
          )}

          <button id="arrowDown" onClick={handleChatScroll}>
            <img src={arrowDownImg} alt="" />
          </button>
        </section>

        <footer className="chat-input">
          <input
            type="text"
            placeholder="Type your message..."
            value={inputValue}
            onChange={(e) => setInputValue(e.target.value)}
            onKeyDown={(e) => e.key === "Enter" && handleSend()}
          />
          <button disabled={!inputValue.trim()} onClick={handleSend}>
            Send
          </button>
        </footer>
        <p className="footer-message">
          SkylineGPT can make mistakes. Check important info.
        </p>
      </main>
    </div>
  );
};

export default Chat;



In App.jsx, add the code.

import React from "react";
import Chat from "./components/Chat";

const App = () => {
  return <Chat />;
};

export default App; 


Conclusion and Final word

Now, we have reached the end of our code, for any information, you can comment any problem or code-not-working issues to resolve it, am always with you. You can also visit my YouTube Channel for more updates on HTML, CSS & JavaScript Designs. I believe you can create "Build AI ChatBot App in ReactJS | ChatBot Like ChatGPT & Gemini AI". and do so much more with codes. Go extremely far in exploring the world of HTML, CSS & JavaScript, its gonna be fun, trust me 😃.

Keep experimenting! You can add other cool features. Try improving error handling and adding other cool updates to make your chatbot even better.

If you run into any issues, you can download the source code for this AI chatbot project by clicking the “Download” button. Don’t forget to check the README.md file for setup and usage instructions. If you need help, you’ll also find support information there.

Happy Coding Journey 🚀







Post a Comment

0 Comments

Close Menu