Skip to content

Chat

RTCstack uses LiveKit's data channel for real-time chat. Messages are sent to all participants (or optionally, a subset).

Sending Messages

ts
// Broadcast to all participants
await call.sendMessage('Hello everyone!')

// Send to specific participants
await call.sendMessage('Hey Alice', { to: ['user-alice-identity'] })

Receiving Messages

ts
call.on('messageReceived', (message) => {
  console.log(message.from, ':', message.text)
})

Message Shape

ts
interface Message {
  id: string        // UUID
  from: string      // sender identity (userId from token)
  text: string
  timestamp: Date
  to?: string[]     // undefined = broadcast
}

Message History

The last 500 messages are kept in memory:

ts
call.messages  // Message[]

Messages are not persisted beyond the call session. If you need message history across sessions, store them in your own database using the messageReceived event.

Reactions

Reactions are emoji sent over the same data channel:

ts
await call.sendReaction('👏')

call.on('reactionReceived', (from, emoji) => {
  showFloatingEmoji(emoji, from)
})

Reactions are not stored in call.messages — they're ephemeral display events.

React

tsx
import { useMemo, useState } from 'react'
import { useMessages, useCall } from '@rtcstack/ui-react'

function Chat() {
  const messages = useMessages()
  const call = useCall()
  const [text, setText] = useState('')

  return (
    <div>
      {messages.map(m => (
        <div key={m.id}><strong>{m.from}:</strong> {m.text}</div>
      ))}
      <input value={text} onChange={e => setText(e.target.value)} />
      <button onClick={() => { call.sendMessage(text); setText('') }}>Send</button>
    </div>
  )
}

Or use the pre-built <ChatPanel /> component which includes auto-scroll, Ctrl+Enter send, and aria-live announcements.

Vue 3

vue
<script setup>
import { ref } from 'vue'
import { useMessages, useCall } from '@rtcstack/ui-vue'

const messages = useMessages()
const call = useCall()
const text = ref('')

function send() {
  call.sendMessage(text.value)
  text.value = ''
}
</script>