How to Create Working Chatbot in HTML CSS and JavaScript
You may have seen chatbots on multiple websites, as they are now essential components for modern websites and apps. If you are unfamiliar, a chatbot is a computer program that serves as a virtual assistant and is capable of understanding user queries and providing relevant responses.
Building a botchat is a very practical way for beginner web developers to gain hands-on experience with HTML, CSS, and JavaScript, as these skills are crucial for creating real-world projects.
This chatbot has an elegant and responsive user interface, ensuring a seamless experience across various devices. Keep in mind that to generate a response to the user query, this chatbot uses the OpenAI API, which is free.
Steps To Create Working Chatbot in HTML & JavaScript
To create your own working chatbot using HTML, CSS, and JavaScript, follow these step-by-step instructions:
- Create a folder. You can name this folder whatever you want, and inside this folder, create the mentioned files.
- Create an
index.html
file. The file name must be index and its extension .html
- Create a
style.css
file. The file name must be style and its extension .css - Create a
script.js
file. The file name must be script and its extension .js
Index.html File
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Chatbot in JavaScript | CodingNepal</title>
<link rel="stylesheet" href="style.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Google Fonts Link For Icons -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@48,400,0,0" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@48,400,1,0" />
<script src="script.js" defer></script>
</head>
<body>
<button class="chatbot-toggler">
<span class="material-symbols-rounded">mode_comment</span>
<span class="material-symbols-outlined">close</span>
</button>
<div class="chatbot">
<header>
<h2>Chatbot</h2>
<span class="close-btn material-symbols-outlined">close</span>
</header>
<ul class="chatbox">
<li class="chat incoming">
<span class="material-symbols-outlined">smart_toy</span>
<p>Hi there 👋<br>How can I help you today?</p>
</li>
</ul>
<div class="chat-input">
<textarea placeholder="Enter a message..." spellcheck="false" required></textarea>
<span id="send-btn" class="material-symbols-rounded">send</span>
</div>
</div>
</body>
</html>
Styles.css File
/* Import Google font - Poppins */
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Poppins", sans-serif;
}
body {
background: #E3F2FD;
}
.chatbot-toggler {
position: fixed;
bottom: 30px;
right: 35px;
outline: none;
border: none;
height: 50px;
width: 50px;
display: flex;
cursor: pointer;
align-items: center;
justify-content: center;
border-radius: 50%;
background: #724ae8;
transition: all 0.2s ease;
}
body.show-chatbot .chatbot-toggler {
transform: rotate(90deg);
}
.chatbot-toggler span {
color: #fff;
position: absolute;
}
.chatbot-toggler span:last-child,
body.show-chatbot .chatbot-toggler span:first-child {
opacity: 0;
}
body.show-chatbot .chatbot-toggler span:last-child {
opacity: 1;
}
.chatbot {
position: fixed;
right: 35px;
bottom: 90px;
width: 420px;
background: #fff;
border-radius: 15px;
overflow: hidden;
opacity: 0;
pointer-events: none;
transform: scale(0.5);
transform-origin: bottom right;
box-shadow: 0 0 128px 0 rgba(0,0,0,0.1),
0 32px 64px -48px rgba(0,0,0,0.5);
transition: all 0.1s ease;
}
body.show-chatbot .chatbot {
opacity: 1;
pointer-events: auto;
transform: scale(1);
}
.chatbot header {
padding: 16px 0;
position: relative;
text-align: center;
color: #fff;
background: #724ae8;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.chatbot header span {
position: absolute;
right: 15px;
top: 50%;
display: none;
cursor: pointer;
transform: translateY(-50%);
}
header h2 {
font-size: 1.4rem;
}
.chatbot .chatbox {
overflow-y: auto;
height: 510px;
padding: 30px 20px 100px;
}
.chatbot :where(.chatbox, textarea)::-webkit-scrollbar {
width: 6px;
}
.chatbot :where(.chatbox, textarea)::-webkit-scrollbar-track {
background: #fff;
border-radius: 25px;
}
.chatbot :where(.chatbox, textarea)::-webkit-scrollbar-thumb {
background: #ccc;
border-radius: 25px;
}
.chatbox .chat {
display: flex;
list-style: none;
}
.chatbox .outgoing {
margin: 20px 0;
justify-content: flex-end;
}
.chatbox .incoming span {
width: 32px;
height: 32px;
color: #fff;
cursor: default;
text-align: center;
line-height: 32px;
align-self: flex-end;
background: #724ae8;
border-radius: 4px;
margin: 0 10px 7px 0;
}
.chatbox .chat p {
white-space: pre-wrap;
padding: 12px 16px;
border-radius: 10px 10px 0 10px;
max-width: 75%;
color: #fff;
font-size: 0.95rem;
background: #724ae8;
}
.chatbox .incoming p {
border-radius: 10px 10px 10px 0;
}
.chatbox .chat p.error {
color: #721c24;
background: #f8d7da;
}
.chatbox .incoming p {
color: #000;
background: #f2f2f2;
}
.chatbot .chat-input {
display: flex;
gap: 5px;
position: absolute;
bottom: 0;
width: 100%;
background: #fff;
padding: 3px 20px;
border-top: 1px solid #ddd;
}
.chat-input textarea {
height: 55px;
width: 100%;
border: none;
outline: none;
resize: none;
max-height: 180px;
padding: 15px 15px 15px 0;
font-size: 0.95rem;
}
.chat-input span {
align-self: flex-end;
color: #724ae8;
cursor: pointer;
height: 55px;
display: flex;
align-items: center;
visibility: hidden;
font-size: 1.35rem;
}
.chat-input textarea:valid ~ span {
visibility: visible;
}
@media (max-width: 490px) {
.chatbot-toggler {
right: 20px;
bottom: 20px;
}
.chatbot {
right: 0;
bottom: 0;
height: 100%;
border-radius: 0;
width: 100%;
}
.chatbot .chatbox {
height: 90%;
padding: 25px 15px 100px;
}
.chatbot .chat-input {
padding: 5px 15px;
}
.chatbot header span {
display: block;
}
}
Script.js File
const chatbotToggler = document.querySelector(".chatbot-toggler");
const closeBtn = document.querySelector(".close-btn");
const chatbox = document.querySelector(".chatbox");
const chatInput = document.querySelector(".chat-input textarea");
const sendChatBtn = document.querySelector(".chat-input span");
let userMessage = null; // Variable to store user's message
const API_KEY = "PASTE-YOUR-API-KEY"; // Paste your API key here
const inputInitHeight = chatInput.scrollHeight;
const createChatLi = (message, className) => {
// Create a chat <li> element with passed message and className
const chatLi = document.createElement("li");
chatLi.classList.add("chat", `${className}`);
let chatContent = className === "outgoing" ? `<p></p>` : `<span class="material-symbols-outlined">smart_toy</span><p></p>`;
chatLi.innerHTML = chatContent;
chatLi.querySelector("p").textContent = message;
return chatLi; // return chat <li> element
}
const generateResponse = (chatElement) => {
const API_URL = "https://api.openai.com/v1/chat/completions";
const messageElement = chatElement.querySelector("p");
// Define the properties and message for the API request
const requestOptions = {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${API_KEY}`
},
body: JSON.stringify({
model: "gpt-3.5-turbo",
messages: [{role: "user", content: userMessage}],
})
}
// Send POST request to API, get response and set the reponse as paragraph text
fetch(API_URL, requestOptions).then(res => res.json()).then(data => {
messageElement.textContent = data.choices[0].message.content.trim();
}).catch(() => {
messageElement.classList.add("error");
messageElement.textContent = "Oops! Something went wrong. Please try again.";
}).finally(() => chatbox.scrollTo(0, chatbox.scrollHeight));
}
const handleChat = () => {
userMessage = chatInput.value.trim(); // Get user entered message and remove extra whitespace
if(!userMessage) return;
// Clear the input textarea and set its height to default
chatInput.value = "";
chatInput.style.height = `${inputInitHeight}px`;
// Append the user's message to the chatbox
chatbox.appendChild(createChatLi(userMessage, "outgoing"));
chatbox.scrollTo(0, chatbox.scrollHeight);
setTimeout(() => {
// Display "Thinking..." message while waiting for the response
const incomingChatLi = createChatLi("Thinking...", "incoming");
chatbox.appendChild(incomingChatLi);
chatbox.scrollTo(0, chatbox.scrollHeight);
generateResponse(incomingChatLi);
}, 600);
}
chatInput.addEventListener("input", () => {
// Adjust the height of the input textarea based on its content
chatInput.style.height = `${inputInitHeight}px`;
chatInput.style.height = `${chatInput.scrollHeight}px`;
});
chatInput.addEventListener("keydown", (e) => {
// If Enter key is pressed without Shift key and the window
// width is greater than 800px, handle the chat
if(e.key === "Enter" && !e.shiftKey && window.innerWidth > 800) {
e.preventDefault();
handleChat();
}
});
sendChatBtn.addEventListener("click", handleChat);
closeBtn.addEventListener("click", () => document.body.classList.remove("show-chatbot"));
chatbotToggler.addEventListener("click", () => document.body.classList.toggle("show-chatbot"));
Please note that your chatbot is currently unable to retrieve responses to your questions because you have not provided your API key in the AP_KEY
variable. To get a free API key from OpenAI, sign up for an account at https://platform.openai.com/account/api-keys.
The above code provided follows a simple flow. First, it displays the user’s message in the chatbox and uses the OpenAI API to generate an appropriate response to the message. While waiting for the API response, a “Thinking…” message is shown. Once the response is received, it replaces the “Thinking…” message in the chatbox.