HTML/CSS/JavaScript Implementation
This example demonstrates how to implement the ZeroinAI Chat Service API using plain HTML, CSS, and JavaScript without any frameworks or build tools.
Project Structure
Create a simple project structure with the following files:
zeroinai-chat-simple/
├── index.html
├── styles.css
├── script.js
└── config.js
Implementation
Configuration (config.js)
Create a config.js file to store your API key and base URL:
// IMPORTANT: In a production environment, never expose your API key in client-side code
// This is for demonstration purposes only. In production, use a backend proxy.
const CONFIG = {
API_URL: 'https://api.zeroinai.com/micro-apps/for-api-providers/chat-service',
API_KEY: 'YOUR_API_KEY_HERE'
};
HTML (index.html)
Create the basic HTML structure for the chat interface:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ZeroinAI Chat Example</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="chat-container">
<div class="chat-header">
<h1>ZeroinAI Chat</h1>
<div class="token-info" id="token-info">Tokens: 0 / 1000</div>
</div>
<div class="chat-messages" id="chat-messages">
<!-- Messages will be added here dynamically -->
</div>
<div class="chat-input">
<input type="text" id="message-input" placeholder="Type your message..." disabled>
<button id="send-button" disabled>Send</button>
</div>
<div class="chat-controls">
<button id="add-tokens-button">Add Tokens</button>
<button id="new-chat-button">New Chat</button>
</div>
</div>
<script src="config.js"></script>
<script src="script.js"></script>
</body>
</html>
CSS (styles.css)
Style the chat interface with CSS:
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: Arial, sans-serif;
background-color: #f5f5f5;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
padding: 20px;
}
.chat-container {
width: 100%;
max-width: 600px;
background-color: white;
border-radius: 10px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
overflow: hidden;
display: flex;
flex-direction: column;
height: 80vh;
}
.chat-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 20px;
background-color: #007BFF;
color: white;
}
.chat-header h1 {
font-size: 20px;
font-weight: normal;
}
.token-info {
font-size: 14px;
background-color: rgba(255, 255, 255, 0.2);
padding: 5px 10px;
border-radius: 15px;
}
.chat-messages {
flex: 1;
padding: 20px;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 10px;
}
.message {
padding: 10px 15px;
border-radius: 18px;
max-width: 80%;
word-wrap: break-word;
}
.user-message {
align-self: flex-end;
background-color: #007BFF;
color: white;
}
.ai-message {
align-self: flex-start;
background-color: #f0f0f0;
color: #333;
}
.system-message {
align-self: center;
background-color: #f8d7da;
color: #721c24;
font-size: 14px;
padding: 8px 12px;
border-radius: 10px;
text-align: center;
max-width: 90%;
}
.chat-input {
display: flex;
padding: 15px;
border-top: 1px solid #eee;
}
#message-input {
flex: 1;
padding: 10px 15px;
border: 1px solid #ddd;
border-radius: 20px;
outline: none;
font-size: 16px;
}
#message-input:focus {
border-color: #007BFF;
}
#message-input:disabled {
background-color: #f9f9f9;
cursor: not-allowed;
}
#send-button {
margin-left: 10px;
padding: 10px 15px;
background-color: #007BFF;
color: white;
border: none;
border-radius: 20px;
cursor: pointer;
}
#send-button:hover {
background-color: #0069d9;
}
#send-button:disabled {
background-color: #cccccc;
cursor: not-allowed;
}
.chat-controls {
display: flex;
justify-content: space-between;
padding: 10px 15px;
background-color: #f8f9fa;
border-top: 1px solid #eee;
}
.chat-controls button {
padding: 8px 12px;
background-color: #f8f9fa;
color: #495057;
border: 1px solid #ddd;
border-radius: 5px;
cursor: pointer;
}
.chat-controls button:hover {
background-color: #e9ecef;
}
.chat-controls button:disabled {
opacity: 0.6;
cursor: not-allowed;
}
JavaScript (script.js)
Implement the chat functionality with JavaScript:
// Chat state
let chatId = null;
let tokenLimit = 1000;
let tokenUsed = 0;
let isLoading = false;
// DOM elements
const chatMessages = document.getElementById('chat-messages');
const messageInput = document.getElementById('message-input');
const sendButton = document.getElementById('send-button');
const tokenInfo = document.getElementById('token-info');
const addTokensButton = document.getElementById('add-tokens-button');
const newChatButton = document.getElementById('new-chat-button');
// Initialize when the page loads
document.addEventListener('DOMContentLoaded', () => {
// Check if we have a stored chat ID
const storedChatId = localStorage.getItem('zeroinai_chat_id');
if (storedChatId) {
chatId = storedChatId;
loadChatHistory(chatId);
} else {
createNewChat();
}
// Set up event listeners
sendButton.addEventListener('click', sendMessage);
messageInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
sendMessage();
}
});
addTokensButton.addEventListener('click', addMoreTokens);
newChatButton.addEventListener('click', createNewChat);
});
// Create a new chat session
async function createNewChat() {
try {
setLoading(true);
addSystemMessage('Creating new chat session...');
const response = await fetch(`${CONFIG.API_URL}/chats/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': CONFIG.API_KEY
},
body: JSON.stringify({
token_limit: tokenLimit
})
});
if (!response.ok) {
throw new Error(`Error: ${response.status} ${response.statusText}`);
}
const data = await response.json();
// Update chat state
chatId = data.chat_id;
tokenLimit = data.token_limit;
tokenUsed = data.token_used;
// Save chat ID to localStorage
localStorage.setItem('zeroinai_chat_id', chatId);
// Update UI
updateTokenInfo();
clearMessages();
addSystemMessage('Chat session created. You can start chatting!');
enableInput();
} catch (error) {
console.error('Error creating chat:', error);
addSystemMessage('Error creating chat session. Please try again.');
} finally {
setLoading(false);
}
}
// Load chat history
async function loadChatHistory(chatId) {
try {
setLoading(true);
addSystemMessage('Loading chat history...');
const response = await fetch(`${CONFIG.API_URL}/chats/${chatId}/messages/?limit=50&offset=0`, {
method: 'GET',
headers: {
'X-API-Key': CONFIG.API_KEY
}
});
if (!response.ok) {
if (response.status === 404) {
// Chat not found, create a new one
localStorage.removeItem('zeroinai_chat_id');
createNewChat();
return;
}
throw new Error(`Error: ${response.status} ${response.statusText}`);
}
const data = await response.json();
// Clear existing messages
clearMessages();
// Display messages
if (data.items.length === 0) {
addSystemMessage('No messages found. Start a new conversation!');
} else {
data.items.forEach(message => {
addMessage(message.content, message.is_user);
});
// Set token usage (simplified - in a real app you'd get this from the API)
tokenUsed = 100; // Placeholder value
updateTokenInfo();
}
enableInput();
} catch (error) {
console.error('Error loading chat history:', error);
addSystemMessage('Error loading chat history. Please try again.');
} finally {
setLoading(false);
}
}
// Send a message and get AI response
async function sendMessage() {
const content = messageInput.value.trim();
if (!content || !chatId || isLoading) return;
try {
setLoading(true);
// Add user message to UI immediately
addMessage(content, true);
messageInput.value = '';
// Send message to API
const response = await fetch(`${CONFIG.API_URL}/chats/messages/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': CONFIG.API_KEY
},
body: JSON.stringify({
chat_id: chatId,
content: content
})
});
if (response.status === 402) {
// Token limit reached
addSystemMessage('Token limit reached. Adding more tokens...');
await addMoreTokens();
// Retry sending the message
sendMessage();
return;
}
if (!response.ok) {
throw new Error(`Error: ${response.status} ${response.statusText}`);
}
const data = await response.json();
// Add AI response to UI
addMessage(data.content, false);
// Update token usage (simplified)
tokenUsed += 20; // Simplified token counting
updateTokenInfo();
} catch (error) {
console.error('Error sending message:', error);
addSystemMessage('Error sending message. Please try again.');
} finally {
setLoading(false);
}
}
// Add more tokens to the chat
async function addMoreTokens() {
try {
setLoading(true);
const response = await fetch(`${CONFIG.API_URL}/chats/${chatId}/tokens/`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'X-API-Key': CONFIG.API_KEY
},
body: JSON.stringify({
additional_tokens: 500
})
});
if (!response.ok) {
throw new Error(`Error: ${response.status} ${response.statusText}`);
}
const data = await response.json();
// Update token info
tokenLimit = data.token_limit;
tokenUsed = data.token_used;
updateTokenInfo();
addSystemMessage('Added 500 more tokens to the conversation.');
return true;
} catch (error) {
console.error('Error adding tokens:', error);
addSystemMessage('Error adding tokens. Please try again.');
return false;
} finally {
setLoading(false);
}
}
// Helper functions
function addMessage(content, isUser) {
const messageElement = document.createElement('div');
messageElement.className = `message ${isUser ? 'user-message' : 'ai-message'}`;
messageElement.textContent = content;
chatMessages.appendChild(messageElement);
scrollToBottom();
}
function addSystemMessage(content) {
const messageElement = document.createElement('div');
messageElement.className = 'message system-message';
messageElement.textContent = content;
chatMessages.appendChild(messageElement);
scrollToBottom();
}
function clearMessages() {
chatMessages.innerHTML = '';
}
function scrollToBottom() {
chatMessages.scrollTop = chatMessages.scrollHeight;
}
function updateTokenInfo() {
tokenInfo.textContent = `Tokens: ${tokenUsed} / ${tokenLimit}`;
}
function enableInput() {
messageInput.disabled = false;
sendButton.disabled = false;
messageInput.focus();
}
function setLoading(loading) {
isLoading = loading;
sendButton.disabled = loading;
messageInput.disabled = loading;
addTokensButton.disabled = loading;
newChatButton.disabled = loading;
if (loading) {
sendButton.textContent = 'Sending...';
} else {
sendButton.textContent = 'Send';
}
}
Security Considerations
caution
This example exposes your API key in client-side code, which is not secure for production use. In a real application, you should:
- Create a backend proxy server that securely stores your API key
- Have your frontend code communicate with your proxy server instead of directly with the ZeroinAI API
- Implement proper authentication and authorization in your proxy server
Running the Example
To run this example:
- Create the four files (
index.html,styles.css,script.js, andconfig.js) with the code provided above - Replace
YOUR_API_KEY_HEREinconfig.jswith your actual ZeroinAI API key - Open
index.htmlin a web browser
Key Features
- Simple implementation using only HTML, CSS, and vanilla JavaScript
- No dependencies or build tools required
- Persistent chat sessions using localStorage
- Token management with automatic top-up
- Responsive design that works on mobile and desktop
Limitations
This simple implementation has some limitations:
- API key is exposed in client-side code (not secure for production)
- Limited error handling and retry logic
- Simplified token usage tracking
- No offline support or message queuing
For a production application, consider using a framework like React, Vue, or Angular, and implementing a secure backend proxy server.