Building a Custom UI (TypeScript)
This page shows how to wire up a simple DOM-based chat UI using vanilla TypeScript.
Example HTML
<div id="status">Disconnected</div>
<button id="connect">Connect</button>
<div id="chat"></div>
<input id="input" type="text" placeholder="Type message..." disabled />
<button id="send" disabled>Send</button>TypeScript Implementation
import {
ConvaiClient,
type ConvaiClientState,
type ChatMessage
} from '@convai/web-sdk/vanilla';
const client = new ConvaiClient();
const statusEl = document.getElementById('status') as HTMLDivElement;
const connectBtn = document.getElementById('connect') as HTMLButtonElement;
const chatEl = document.getElementById('chat') as HTMLDivElement;
const inputEl = document.getElementById('input') as HTMLInputElement;
const sendBtn = document.getElementById('send') as HTMLButtonElement;
// State updates
client.on('stateChange', (state) => {
updateStatus(state);
updateControls(state);
});
// New messages
client.on('message', (msg) => {
if (msg.type === 'user-transcription' || msg.type === 'bot-llm-text') {
addMessageToUI(msg);
}
});
function updateStatus(state: ConvaiClientState) {
if (!state.isConnected) return statusEl.textContent = 'Disconnected';
statusEl.textContent = state.agentState;
}
function updateControls(state: ConvaiClientState) {
const connected = state.isConnected;
connectBtn.disabled = connected;
inputEl.disabled = !connected;
sendBtn.disabled = !connected;
}
function addMessageToUI(msg: ChatMessage) {
const div = document.createElement('div');
div.className = msg.type === 'user-transcription' ? 'user' : 'bot';
div.textContent = msg.content;
chatEl.appendChild(div);
chatEl.scrollTop = chatEl.scrollHeight;
}
// Connect logic
connectBtn.addEventListener('click', async () => {
await client.connect({
apiKey: 'your-api-key',
characterId: 'your-character-id',
// endUserId: 'user-uuid', // Optional for memory
});
});
// Send message
function sendMessage() {
const text = inputEl.value.trim();
if (text) {
client.sendUserTextMessage(text);
inputEl.value = '';
}
}
sendBtn.addEventListener('click', sendMessage);
inputEl.addEventListener('keypress', (e) => {
if (e.key === 'Enter') sendMessage();
});Adding Audio/Video Controls
await client.audioControls.toggleAudio();
await client.videoControls.toggleVideo();
await client.screenShareControls.toggleScreenShare();Last updated
Was this helpful?