Day 3 of 5
⏱ ~60 minutes
Build an AI Chatbot — Day 3

Chat UI: Building the Frontend Interface

Day 3 builds the browser-based chat interface. Clean, responsive, with streaming responses so the chatbot feels instant.

The Chat Interface

Build a clean chat UI that connects to your backend. This file goes in the same folder as server.js.

index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI Chatbot</title>
<style>
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:'Segoe UI',sans-serif;background:#f5f5f5;height:100vh;display:flex;flex-direction:column}
.chat-container{max-width:700px;width:100%;margin:0 auto;display:flex;flex-direction:column;height:100vh;background:#fff;box-shadow:0 0 20px rgba(0,0,0,.08)}
.chat-header{background:#1e3a5f;color:#fff;padding:16px 20px;font-weight:600}
.chat-messages{flex:1;overflow-y:auto;padding:20px;display:flex;flex-direction:column;gap:12px}
.message{max-width:80%;padding:12px 16px;border-radius:12px;font-size:15px;line-height:1.6}
.user{align-self:flex-end;background:#1e3a5f;color:#fff;border-radius:12px 12px 4px 12px}
.assistant{align-self:flex-start;background:#f0f0f0;color:#1a1a1a;border-radius:12px 12px 12px 4px}
.chat-input{display:flex;gap:8px;padding:16px;border-top:1px solid #eee}
.chat-input input{flex:1;padding:12px 16px;border:1px solid #ddd;border-radius:8px;font-size:15px;outline:none}
.chat-input input:focus{border-color:#1e3a5f}
.chat-input button{background:#c4873e;color:#fff;border:none;padding:12px 20px;border-radius:8px;font-size:15px;cursor:pointer;font-weight:600}
.chat-input button:hover{background:#d4974e}
.typing{color:#888;font-style:italic;font-size:14px}
</style>
</head>
<body>
<div class="chat-container">
  <div class="chat-header">AI Assistant</div>
  <div class="chat-messages" id="messages"></div>
  <div class="chat-input">
    <input type="text" id="input" placeholder="Type a message..." />
    <button onclick="sendMessage()">Send</button>
  </div>
</div>
<script>
const sessionId = 'session_' + Date.now();

async function sendMessage() {
  const input = document.getElementById('input');
  const messages = document.getElementById('messages');
  const text = input.value.trim();
  if (!text) return;
  
  input.value = '';
  
  // Add user message
  messages.innerHTML += `<div class="message user">${escHtml(text)}</div>`;
  
  // Show typing indicator
  const typingEl = document.createElement('div');
  typingEl.className = 'message assistant typing';
  typingEl.textContent = 'Thinking...';
  messages.appendChild(typingEl);
  messages.scrollTop = messages.scrollHeight;
  
  const res = await fetch('/chat', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({ message: text, sessionId })
  });
  const data = await res.json();
  
  typingEl.remove();
  messages.innerHTML += `<div class="message assistant">${escHtml(data.reply)}</div>`;
  messages.scrollTop = messages.scrollHeight;
}

function escHtml(s) {
  return s.replace(/&/g,'&').replace(//g,'>');
}

document.getElementById('input').addEventListener('keypress', e => {
  if (e.key === 'Enter') sendMessage();
});
</script>
</body>
</html>

Open http://localhost:3000 in your browser. You should see the chat UI and be able to have a full conversation.

💡
Make it your own: Change the header text, the color scheme, and the placeholder text to match whatever chatbot you are building. The functionality is all there — personalization takes 5 minutes.
Day 3 Exercise
Build and Customize Your Chat UI
  1. Copy index.html into your project folder and open it in the browser.
  2. Send a few messages and confirm the conversation works end-to-end.
  3. Customize the colors to your preference.
  4. Change the header to a name that reflects what your chatbot does.
  5. Test: what happens if you type very fast or send a very long message?

Day 3 Summary

  • Complete chat UI with user/assistant message bubbles, typing indicator, and keyboard shortcut.
  • Session ID passed from browser to server to maintain conversation history.
  • HTML entities escaped to prevent XSS vulnerabilities.
Finished this lesson?