✅ Sample Frontend with HTML/JS for Your Custom AI Chatbot (DeepSeek Edition)
🔍 Introduction
As the adoption of local and API-based LLMs like DeepSeek grows, developers are increasingly building their own chatbot APIs using tools like FastAPI, Ollama, and llama.cpp. But a backend is only half the battle—the frontend experience is what users actually see.

In this in-depth guide, you’ll learn how to create a clean, responsive, and functional chatbot interface using just HTML, JavaScript, and CSS, designed to connect with your chatbot_api.py or any local LLM.
We’ll walk through:
Frontend structure (HTML + JS)
Sending and receiving chat messages via fetch()
Rendering conversation history
Adding typing indicators, themes, error handling
Bonus: voice input and Markdown formatting
✅ Table of Contents
Why Use Plain HTML/JS for a Chatbot?
Project Structure Overview
Basic HTML Chat Template
Styling with CSS (Dark Mode + Mobile Friendly)
JavaScript: Connecting to the Chatbot API
Message Rendering and History Management
Handling Errors and Loading States
Optional: Streaming Responses via SSE/WebSockets
Optional: Voice Input + Audio Output
Security Tips and Production Best Practices
Deployment and Hosting
Conclusion + Download the Full Template
1. ⚙️ Why Use Plain HTML/JS?
✅ No frameworks required
✅ Loads instantly in any browser
✅ Great for MVPs, internal tools, mobile-friendly apps
✅ Easy to embed in other systems (WordPress, Shopify, admin panels)
2. 📁 Project Structure
markdown chatbot-frontend/ ├── index.html ├── style.css ├── script.js └── assets/ └── logo.png
3. 🧱 Basic HTML Chat Template
html <!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>DeepSeek Chat</title> <link rel="stylesheet" href="style.css" /></head> <body> <div class="chat-container"> <header><h1>🤖 DeepSeek Chat</h1></header> <div id="chat-box"></div> <form id="chat-form"> <input type="text" id="user-input" placeholder="Type your message..." autocomplete="off" /> <button type="submit">Send</button> </form> </div> <script src="script.js"> </script> </body> </html>
4. 🎨 Styling with CSS
css
/* style.css */body
{ margin: 0; font-family: Arial, sans-serif;
background: #121212; color: #eee; display: flex;
justify-content: center; align-items: center; height: 100vh;
}.chat-container { width: 100%; max-width: 600px; border: 1px solid #333;
background: #1e1e1e; padding: 1rem; border-radius: 10px;
}#chat-box { height: 400px; overflow-y: auto; border: 1px solid #444;
padding: 1rem; margin-bottom: 1rem; background: #111; font-size: 14px;
}.user-msg { text-align: right; color: #1fa2ff; margin: 0.5rem 0;
}.bot-msg { text-align: left; color: #ffffff; margin: 0.5rem 0;
}#chat-form { display: flex; gap: 10px;
}#user-input { flex: 1; padding: 0.5rem; font-size: 1rem;
}button { padding: 0.5rem 1rem; background: #1fa2ff; color: #fff;
border: none; cursor: pointer; font-weight: bold;
}
5. 🧠 JavaScript: Connecting to Your API
js
// script.jsconst form = document.getElementById('chat-form');
//const input = document.getElementById('user-input');
//const chatBox = document.getElementById('chat-box');
form.addEventListener('submit', async (e) => {
e.preventDefault(); const message = input.value.trim();
if (!message) return; appendMessage(message, 'user-msg');
input.value = ''; appendMessage("...", 'bot-msg', true); // Typing indicator
try { const response = await fetch('http://localhost:8000/chat',
{ method: 'POST', headers: {'Content-Type': 'application/json'},
body: JSON.stringify({user_id: "frontend_user", message})
}); const data = await response.json();
removeTypingIndicator(); appendMessage(data.reply, 'bot-msg');
} catch (err) { removeTypingIndicator();
appendMessage("⚠️ Error connecting to the bot.", 'bot-msg');
}
});function appendMessage(text, className, isTyping = false)
{ const p = document.createElement('p');
p.className = className;
p.textContent = text; if (isTyping) p.classList.add('typing');
chatBox.appendChild(p);
chatBox.scrollTop = chatBox.scrollHeight;
}function removeTypingIndicator()
{ const el = document.querySelector('.typing'); if (el) el.remove();
}
6. 🧾 Message History
This basic interface does not store messages beyond session, but:
You can store messages in
localStorageBackend should store chat history per
user_id
js
// Optional: localStorage to persist chatwindow.addEventListener("beforeunload",
() => { localStorage.setItem("chat_history", chatBox.innerHTML);
});window.addEventListener("load", () => {
chatBox.innerHTML = localStorage.getItem("chat_history") || "";
});
7. ⚠️ Handling Errors and Edge Cases
Improve UX with:
Button disabling during loading
Auto-focus on input
Retry logic
Connection error popups
8. 🔁 Streaming Responses (Advanced)
If your backend supports Server-Sent Events (SSE) or WebSockets, you can render the bot’s reply word-by-word.
Sample with SSE:
js
const evtSource = new EventSource("/stream");
evtSource.onmessage = function(e) { appendToLastMessage(e.data);
}
9. 🎤 Voice Input and Audio Output (Optional)
Add voice-to-text:
html <button onclick="record()">🎙️</button>
js
function record() { const recognition = new webkitSpeechRecognition();
recognition.lang = 'en-US';
recognition.onresult = (e) => {
input.value = e.results[0][0].transcript;
};
recognition.start();
}
And for text-to-speech reply:
js
function speak(text) { const utter = new SpeechSynthesisUtterance(text);
speechSynthesis.speak(utter);
}
10. 🔐 Security Tips
Use HTTPS in production
Sanitize user input on backend
Implement token-based authentication (optional)
Set proper CORS headers
Log rate limits or abuse detection (optional)
11. 🚀 Deployment
Options:
| Method | Tool |
|---|---|
| Static Hosting | GitHub Pages, Netlify, Vercel |
| Docker + NGINX | For local + API hosting |
| Embedded App | Electron, React Native WebView |
12. ✅ Conclusion + Template Download
You’ve now created a fully functional, responsive AI chatbot frontend using just HTML, CSS, and JavaScript. It connects to any local or cloud-based API—like one powered by DeepSeek—and can be deployed anywhere, even on your own laptop.
📥 Want the Full Template?
Includes:
index.htmlstyle.cssscript.jsAssets folder
Dockerized local server (optional)
React + Tailwind upgrade pack (bonus)
Let me know if you'd like it as a ZIP file, GitHub repo, or Notion workspace.
Would you like a follow-up guide on turning this into a PWA (Progressive Web App) or adding LangChain-based tools like document search?