Skip to content

Vue

The @saytv/chat-vue package provides a Vue 3 component and composable for integrating the chat widget.

Installation

bash
npm install @saytv/chat-vue

Peer dependency: Vue 3.2+.

Basic Usage

vue
<script setup lang="ts">
import { SayTVChat } from '@saytv/chat-vue';
</script>

<template>
  <SayTVChat
    app-id="your-app-id"
    theme="light"
    :height="700"
    width="100%"
  />
</template>

With External Auth

vue
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { SayTVChat } from '@saytv/chat-vue';

const token = ref<string>();

onMounted(async () => {
  token.value = await fetchUserToken();
});
</script>

<template>
  <SayTVChat
    app-id="your-app-id"
    :auth-token="token"
    :built-in-auth="false"
    theme="light"
    :height="700"
    width="100%"
  />
</template>

Props

PropTypeDefaultDescription
appIdstring-App identifier (resolves API URL automatically)
env'production' | 'staging''production'API environment
apiUrlstring-Direct API base URL (overrides appId/env)
authTokenstring-JWT access token for external auth
builtInAuthbooleantrueShow built-in login/register UI
fanzonebooleanfalseEnable the Fanzone feature
heightnumber850Widget height in pixels
widthstring'450px'Widget width (any CSS value)
mode'page-chat'-Enables page chat mode
pageIdstringwindow.location.hrefUnique identifier for page chat
pageNamestringdocument.titleDisplay name for page chat
customTabUrlstring-URL loaded in a custom tab iframe
customTabLabelstring-Label shown on the custom tab
customTabIconstring-Icon name for the custom tab
hideHeaderbooleanfalseHide the top title bar on every page
hideFooterbooleanfalseHide the bottom tab-bar navigation
hideAvatarbooleanfalseHide every entry point to the built-in avatar picker. Use when your app owns the user's avatar
hideGuestNoticebooleanfalseHide the read-only bar shown to guests in place of the composer
hideBadgesbooleanfalseHide the Badges card on the profile screen and its page
hideLeaderboardbooleanfalseHide the Leaderboard card on the profile screen and its page
hideEmojiStorebooleanfalseHide the Emojis card and the emoji store page. The emoji picker in the composer is unaffected
hideAvatarStorebooleanfalseHide the Avatars card and the avatar store page
hideUserProfilesbooleanfalseStop message authors and member-list names linking to that person's profile. Names and avatars still show; they stop being tappable. The signed-in user's own profile is unaffected
avatarUrlstring-Image URL applied as the signed-in user's avatar
theme'light' | 'dark''light'Color theme
localestring'en'BCP-47 UI language; RTL auto
translationsRecord<string, Record<string, string>>-Catalogs keyed by locale, merged over English
translationsUrlstring-URL of a hosted flat JSON catalog to fetch and apply for the active locale

All props are reactive - changing a prop updates the underlying <saytv-chat> element.

TIP

Use kebab-case for props in templates (app-id, auth-token, built-in-auth) and camelCase in script (appId, authToken, builtInAuth).

Events

EventPayloadDescription
@readyCustomEventWidget initialized
@user-loginCustomEventFired on successful login
@user-logoutCustomEventFired on logout
@message-sentCustomEventFired when user sends a message
@message-receivedCustomEventNew message from another user
@navigationCustomEventPage changed within widget
@episode-changedCustomEventUser selected an episode
@room-joinedCustomEventUser entered a chat room
@theme-changedCustomEventTheme switched
@page-chat-readyCustomEventPage chat episode is created or reconnected
@errorCustomEventFired on SDK errors
vue
<template>
  <SayTVChat
    app-id="your-app-id"
    @ready="() => console.log('Widget ready')"
    @user-login="(e) => console.log('Logged in:', e.detail.user)"
    @message-sent="(e) => console.log('Sent:', e.detail.message)"
    @message-received="(e) => console.log('Received:', e.detail.message)"
    @episode-changed="(e) => console.log('Episode:', e.detail.episode)"
    @error="(e) => console.error('Error:', e.detail.error)"
  />
</template>

useSayTVChat Composable

The useSayTVChat composable provides imperative access to the widget:

vue
<script setup lang="ts">
import { SayTVChat, useSayTVChat } from '@saytv/chat-vue';

const { chatRef, getElement, setToken, setTheme, setUsername } = useSayTVChat();
</script>

<template>
  <SayTVChat
    ref="chatRef"
    app-id="your-app-id"
    theme="light"
    :height="700"
    width="100%"
  />

  <button @click="setTheme('dark')">Dark Mode</button>
  <button @click="setToken(newToken)">Update Token</button>
</template>

Composable Return Values

PropertyTypeDescription
chatRefRef<{ element: HTMLElement | null }>Template ref for the component
getElement()() => HTMLElement | nullReturns the underlying <saytv-chat> element
setToken(token)(token: string) => voidUpdates the auth-token attribute
setTheme(theme)(theme: 'light' | 'dark') => voidSwitches the color theme
setUsername(name)(name: string) => Promise<User>Renames the signed-in user. Rejects with a 422 and errors.username when the name is taken, too short, or blocked by moderation. See Methods

Custom Theming

Pass CSS custom properties as inline styles:

vue
<template>
  <SayTVChat
    app-id="your-app-id"
    theme="light"
    :style="{
      '--stv-color-primary': '#4f46e5',
      '--stv-color-accent': '#10b981',
      '--stv-border-radius-md': '12px',
    }"
  />
</template>

See Theming for all available CSS variables.

Localization

Set the UI language with locale and supply your own translation catalogs via :translations. Catalogs are keyed by locale and merged over the built-in English, so untranslated keys fall back to English. RTL languages lay out automatically.

vue
<template>
  <SayTVChat
    app-id="your-app-id"
    locale="ar"
    :translations="{
      ar: {
        'auth.login.title': 'مرحبا بعودتك',
        'chat.input.placeholder': 'اكتب رسالة…',
      },
    }"
  />
</template>

Alternatively, point :translations-url at a hosted flat JSON catalog and the widget fetches and registers it for the active locale, no object needed. A failed fetch falls back to English.

vue
<template>
  <SayTVChat
    app-id="your-app-id"
    locale="ar"
    translations-url="https://your-cdn.com/locales/ar.json"
  />
</template>

See Localization for the full guide and available keys.

TypeScript

All types are exported from the package:

ts
import type { SayTVChatProps } from '@saytv/chat-vue';
import type { UseSayTVChatReturn } from '@saytv/chat-vue';

SayTV Chat SDK Documentation