Usage with Svelte

Rendering emoteTTV parsed results with Svelte

First of all, we recommend using TMI.js to handle Twitch chat messages. Svelte will help you render messages more effectively.

Introduction

For starters, let's consider the following Svelte component with some basic TMI.js implementation:

<script>
  import { onMount } from "svelte";
  import tmi from "tmi.js";

  let messages = [];

  onMount(() => {
    const client = new tmi.Client({
      channels: [ "doceazedo911" ]
    });

    client.connect();

    client.on("message", (channel, tags, text, self) => {
      messages = [...messages, text];
    });
  });
</script>

{#each messages as message}
  <div>{message}</div>
{/each}

The component above will connect to the Twitch chat, and for every message we receive we added it to a messages array. Then we simply render all messages in that array.

At this point, text is yet to be parsed and that tags hold some very valuable information for us such as emote offsets and badges information. So when we receive a message let's call emoteTTV and parse the emotes and badges:

// ...
import { parseBadges, parseEmotes } from "emotettv";
​
const options = {
    channelId: "98776633"
};

​onMount(() => {
    // ...
    client.on("message", async (channel, tags, text, self) => {
        const badges = await parseBadges(tags.badges, tags.username, options);
        const message = await parseEmotes(text, tags.emotes, options);
    });
});

With the message and badges parsed, we have to decide if we want to render them with the default HTML that emoteTTV provides or if we want to go trough each word and emote and render them with Svelte.

The easy way: {@html}

Using {@html} to render the message is the quickest and easiest way to do it. In counterpart, if we want to style the messages with custom CSS, we will have to use global styles which may cause unwanted side effects and it might expose your users to XSS and other vulnerabilities.

emoteTTV will escape HTML characters by default, but you should still use {@html} with caution. If you specifically want to allow for HTML in user messages, you can disable HTML escaping entirely.

With that in mind, we can get the parsed HTML and use other TMI tags to format our message as we want and add a limit to the last 20 messages as such:

<script>
  import { onMount } from "svelte";
  import tmi from "tmi.js";
  import { parseBadges, parseEmotes } from "emotettv";

  let messages = [];
  const options = {
    channelId: "98776633",
  };

  onMount(() => {
    const client = new tmi.Client({
      channels: [ "doceazedo911" ]
    });

    client.connect();

    client.on("message", async (channel, tags, text, self) => {
      const badges = await parseBadges(tags.badges, tags.username, options);
      const badgesHTML = badges.toHTML();
      const message = await parseEmotes(text, tags.emotes, options);
      const messageHTML = message.toHTML();
      const newMessage = `<div>${badgesHTML} <b style="color:${color}">${name}</b>: ${messageHTML}</div>`;
      messages = [...messages, newMessage].slice(-20);
    });
  });
</script>

{#each messages as message}
  <div>{@html message}</div>
{/each}

The advanced way: {#each}

Last updated