Event bindings
A binding subscribes your widget to a live stream event. Bindings are how a widget reacts to your stream — flashing on a follow, counting up your bit total, scrolling chat, tracking a goal.
Using an event takes two steps:
- Declare it on the Bindings surface (toggle the event on). This tells Community to deliver that event to your widget.
- Consume it in your code or template.
The editor keeps these two in sync for you. Use an event in code that you didn't declare and the console warns you (and the event won't arrive live). Declare an event nothing consumes and it warns too. Watch the console.
Two kinds of event
- Moment events happen at a point in time — a follow, a sub, a cheer. Your handler runs each time one occurs.
- Live values are always-current readings — the viewer count, the current goal, the stream title. They carry a value at all times and update as it changes.
Consuming a moment event
In your core code, register a handler:
import { onLoad, registerBinding, Event, showTemplate, Template } from '@widget';
onLoad(() => {
showTemplate(Template.Main);
registerBinding(Event.Follow, (payload) => {
console.log(`${payload.user.displayName} just followed!`);
// trigger an animation, play a sound, etc.
});
});
Or react to it inside a template with a hook:
import { useLatestEvent, Event } from '@widget';
export default function Main() {
const last = useLatestEvent(Event.Follow); // the most recent follow, or undefined
return <div>Latest follower: {last?.user.displayName ?? '—'}</div>;
}
Consuming a live value
Read it with a hook and your template re-renders when it changes:
import { useLatestEvent, Event } from '@widget';
export default function Main() {
const stats = useLatestEvent(Event.Stats);
return <div>{stats?.viewers ?? 0} watching</div>;
}
Live values are also published as CSS variables, so simple displays need no code at all.
Moment events
| Event | Event. key | Payload highlights |
|---|---|---|
| Follow | Follow | user |
| Subscription | Sub | user, tier (1–3), months, message?, isGift |
| Gift Sub | GiftSub | gifter, recipient, tier, quantity, isAnonymous |
| Cheer | Cheer | user, bits, message, isAnonymous |
| Raid | Raid | user, viewers |
| Shoutout Sent | ShoutoutCreate | toBroadcaster, moderator, viewerCount |
| Shoutout Received | ShoutoutReceive | fromBroadcaster, viewerCount |
| Channel Points | ChannelPoints | user, rewardId, rewardTitle, rewardCost, userInput? |
| Hype Train | HypeTrain | phase, level, total, goal?, progress? |
| Ad Break | AdBreak | durationSeconds, isAutomated |
| Stream Status | StreamStatus | online |
| Poll | Poll | phase, title, choices[] |
| Chat Message | Chat | author, text, fragments, emotes, badges, color, and gif when the sender attached one |
| Chat Removed | ChatRemoved | scope (message/user/all), messageId?, user? |
| Super Cheer | SuperCheer | user, bits, message, imageUrl? |
| Power-Up | PowerUp | user, id, title, bits, prompt |
| Storage Update | KvUpdate | key, value — fires when your widget's stored data changes |
There's also an Event.Alert used by the built-in Alert primitive — a fully-resolved alert payload. It's specialised for that container, so most widgets use the individual events (Follow, Sub, Cheer…) instead.
Live values
| Live value | Event. key | Carries |
|---|---|---|
| Channel Stats | Stats | followers, subscribers, viewers, bitsThisStream, and …ThisStream counts |
| Stream Info | StreamInfo | online, title, category, startedAt |
| Ad Schedule | AdSchedule | nextAdAt, snoozesRemaining |
| Goals | Goal | every running goal with current, target, progress (0–1, by the leading option for first-to-post races), milestones, timer |
| Stream Credits | Credits | session followers, subs, gift-subs, cheers and raids — for end-of-stream rolls |
| Streamer Variables | StreamerVariables | your custom channel variables as a { name: value } map, plus endsAt, a { name: ISO time } map of when each running degrading-number variable reaches its resting value |
| Alerts Paused | SuperCheersPaused | paused — whether the channel's alerts are currently paused (the member name is historical) |
| Channel Emotes | ChannelEmotes | the channel's Twitch + 7TV + BTTV + FFZ emotes, kept current |
The runtime ships helpers for the richer live values — parseChatMessage, useChannelEmotes, the ChatMessage component for chat, and useCountdown for ad/goal timers. See The @widget runtime.
A note on identity
Person-bearing payloads carry public Twitch identity only — a display name, and sometimes a login, public Twitch id, avatar and chat flair. Widgets never receive private account data. Build with what's in the payload.
Viewer flair
When a viewer has a chat flair on your channel, their user (the chat author, a gift's gifter) carries flair with everything needed to draw it the way chat does. Anonymous cheers and gifts never carry one.
| Field | Meaning |
|---|---|
text | The flair, e.g. Warrior |
shortText | Its abbreviation, e.g. WAR, or null |
color | #rrggbb, or null for an uncoloured flair |
style | fill (a coloured pill) or text (coloured text) |
foreground | Black or white, whichever reads on color: the text colour for fill |
id | Stable when the flair is renamed, null for custom text. Match flairs on this, never on the text |
function Flair({ flair }) {
if (!flair) return null;
if (!flair.color) return <span>{flair.text}</span>;
if (flair.style === 'text') return <span style={{ color: flair.color }}>{flair.text}</span>;
return (
<span style={{ background: flair.color, color: flair.foreground, padding: '0.15em 0.4em', borderRadius: '0.3em' }}>
{flair.text}
</span>
);
}
// e.g. inside a Follow handler: <Flair flair={payload.user.flair} />
The Simulate panel's sample viewer has a flair, so you can style it before a real viewer with one shows up.
Viewer achievements
A chat author also carries achievementIds: the ids of the achievements that chatter has earned on your channel. It is absent when they have earned none. It is on chat messages only, not on alerts such as cheers and gifts.
const earned = payload.author.achievementIds ?? [];
const isFounder = earned.includes(42); // an id from your achievements list
The Simulate panel's sample viewer has achievements, so you can try a check before a real viewer earns one.
Next
- The @widget runtime — every hook and helper, including the chat and emote utilities.
- React to live events — a hands-on walkthrough.