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{ 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