Skip to content

Events Reference ​

The <saytv-chat> element dispatches custom events that you can listen to for integration with your application. All events are prefixed with stv: and use CustomEvent with a detail payload.

Available Events ​

EventFired WhenDetail
stv:readyWidget initialized, auth resolved-
stv:user-loginUser logs in (password, JWT, or registration){ user: { id, username } }
stv:user-logoutUser logs out-
stv:message-sentUser's message is confirmed by the API{ message: { id, text } }
stv:message-receivedNew message arrives from another user{ message: { id, text, userId, username } }
stv:navigationWidget page changes, forward or back{ page, previousPage }
stv:episode-changedUser selects an episode{ episode: { id, title } }
stv:room-joinedUser enters a chat room{ room: { id, name } }
stv:theme-changedTheme switches between light and dark{ theme: 'light' | 'dark' }
stv:page-chat-readyPage chat episode is created or reconnected{ episode: { id, title, externalId } }
stv:errorAn SDK error occurs{ error: { message, code? } }

Listening to Events ​

Vanilla JS ​

js
const chat = document.querySelector('saytv-chat');

chat.addEventListener('stv:ready', () => {
  console.log('Widget is ready');
});

chat.addEventListener('stv:user-login', (e) => {
  console.log('User logged in:', e.detail.user);
});

chat.addEventListener('stv:user-logout', () => {
  console.log('User logged out');
});

chat.addEventListener('stv:message-sent', (e) => {
  console.log('Message sent:', e.detail.message);
});

chat.addEventListener('stv:message-received', (e) => {
  const { id, text, username } = e.detail.message;
  console.log(`New message from ${username}: ${text}`);
});

chat.addEventListener('stv:navigation', (e) => {
  console.log(`Navigated from ${e.detail.previousPage} to ${e.detail.page}`);
});

chat.addEventListener('stv:episode-changed', (e) => {
  console.log('Episode selected:', e.detail.episode);
});

chat.addEventListener('stv:room-joined', (e) => {
  console.log('Joined room:', e.detail.room);
});

chat.addEventListener('stv:theme-changed', (e) => {
  console.log('Theme changed to:', e.detail.theme);
});

chat.addEventListener('stv:page-chat-ready', (e) => {
  console.log('Page chat ready:', e.detail.episode);
});

chat.addEventListener('stv:error', (e) => {
  console.error('SDK error:', e.detail.error);
});

React ​

Events are mapped to callback props:

tsx
<SayTVChat
  appId="your-app-id"
  onReady={() => console.log('Ready')}
  onUserLogin={(e) => console.log(e.detail.user)}
  onUserLogout={() => console.log('Logged out')}
  onMessageSent={(e) => console.log(e.detail.message)}
  onMessageReceived={(e) => console.log(e.detail.message)}
  onNavigation={(e) => console.log(e.detail.page)}
  onEpisodeChanged={(e) => console.log(e.detail.episode)}
  onRoomJoined={(e) => console.log(e.detail.room)}
  onThemeChanged={(e) => console.log(e.detail.theme)}
  onPageChatReady={(e) => console.log(e.detail.episode)}
  onError={(e) => console.error(e.detail.error)}
/>
DOM EventReact Prop
stv:readyonReady
stv:user-loginonUserLogin
stv:user-logoutonUserLogout
stv:message-sentonMessageSent
stv:message-receivedonMessageReceived
stv:navigationonNavigation
stv:episode-changedonEpisodeChanged
stv:room-joinedonRoomJoined
stv:theme-changedonThemeChanged
stv:page-chat-readyonPageChatReady
stv:erroronError

Vue ​

Events are emitted as camelCase Vue events:

vue
<SayTVChat
  app-id="your-app-id"
  @ready="() => console.log('Ready')"
  @user-login="(e) => console.log(e.detail.user)"
  @user-logout="() => console.log('Logged out')"
  @message-sent="(e) => console.log(e.detail.message)"
  @message-received="(e) => console.log(e.detail.message)"
  @navigation="(e) => console.log(e.detail.page)"
  @episode-changed="(e) => console.log(e.detail.episode)"
  @room-joined="(e) => console.log(e.detail.room)"
  @theme-changed="(e) => console.log(e.detail.theme)"
  @page-chat-ready="(e) => console.log(e.detail.episode)"
  @error="(e) => console.error(e.detail.error)"
/>
DOM EventVue Event
stv:ready@ready
stv:user-login@user-login
stv:user-logout@user-logout
stv:message-sent@message-sent
stv:message-received@message-received
stv:navigation@navigation
stv:episode-changed@episode-changed
stv:room-joined@room-joined
stv:theme-changed@theme-changed
stv:page-chat-ready@page-chat-ready
stv:error@error

Event Details ​

All events are standard CustomEvent objects that bubble up through the DOM. You can listen for them on the element itself or on any parent. Access the payload via event.detail:

ts
chat.addEventListener('stv:message-received', (event: CustomEvent) => {
  const { message } = event.detail;
  // message.id      - Comment ID (number)
  // message.text    - Message body (string)
  // message.userId  - Sender's user ID (number)
  // message.username - Sender's username (string)
});

Common Patterns ​

Show a notification badge for unread messages ​

js
let unreadCount = 0;

chat.addEventListener('stv:message-received', () => {
  unreadCount++;
  updateBadge(unreadCount);
});

chat.addEventListener('stv:navigation', (e) => {
  if (e.detail.page === 'episode-chat' || e.detail.page === 'room-chat') {
    unreadCount = 0;
    updateBadge(0);
  }
});

Sync theme with host application ​

js
chat.addEventListener('stv:theme-changed', (e) => {
  document.documentElement.setAttribute('data-theme', e.detail.theme);
});

Track user engagement ​

js
chat.addEventListener('stv:message-sent', (e) => {
  analytics.track('chat_message_sent', { messageId: e.detail.message.id });
});

chat.addEventListener('stv:episode-changed', (e) => {
  analytics.track('episode_viewed', { episodeId: e.detail.episode.id });
});

SayTV Chat SDK Documentation