Custom Widget
Custom widgets let you build an OBS browser source with React, TypeScript and CSS. Use the Synchra API for chat messages, activities, settings and stored values.
Quick setup
Section titled “Quick setup”- Open the Synchra Dashboard.
- Go to Widgets and create a Custom widget.
- Edit the project files, then choose Apply to update the preview.
- Use Test event below the preview to send sample chat messages or activities while editing.
- Click Widget URL and add it to OBS as a Browser Source.
Use Save to keep applied changes.
Chat example
Section titled “Chat example”Set font-size on a wrapper to change the logo size:
Activity example
Section titled “Activity example”See Activity data for activity fields and provider-independent filtering with activity and contribution groups.
KV value example
Section titled “KV value example”Convert currencies
Section titled “Convert currencies”Fetch API data
Section titled “Fetch API data”Project files
Section titled “Project files”index.html is the project entry. It selects the widget module and styles:
Add external scripts or stylesheets to index.html with normal absolute URLs. Use relative imports for your own components and helpers.
Available packages:
react@tanstack/react-queryzustand
Custom font
Section titled “Custom font”See Custom fonts for loading and applying a custom font.
Live event callbacks
Section titled “Live event callbacks”Use callbacks when code outside a React component needs new events.
React API
Section titled “React API”Normal React hook rules apply: call hooks at the top level of a React component, not inside conditions or callbacks.
React hooks, useQuery, useMutation and Zustand’s create are available directly.
| API | Behavior |
|---|---|
synchra.render(node) | Renders the widget’s root React element. |
synchra.mode | preview in the editor and live in the browser source. |
synchra.settings | Values declared by the settings schema. |
synchra.useChatMessages({ limit?, types? }) | Recent messages. Defaults to message types. |
synchra.useLatestChatMessage({ types? }) | Latest message. Defaults to message types. |
synchra.useActivities({ limit?, types?, activityGroups?, contributionGroups? }) | Recent activities, optionally filtered by type or group. |
synchra.useLatestActivity({ types?, activityGroups?, contributionGroups? }) | Latest matching activity. |
synchra.useKvValue(key) | Returns a channel KV value and its updates. |
synchra.kv.get({ key }) | Reads a channel KV key. |
synchra.kv.set({ key, value, ttl? }) | Writes a JSON value with an optional TTL in seconds. |
synchra.kv.delete({ key }) | Deletes a channel KV value. |
synchra.kv.inc({ key, amount?, ttl? }) | Atomically increments an integer value. |
synchra.convertCurrency({ amount, from, to }) | Converts an amount using the current currency rates. |
synchra.assembleParts(parts) | Renders message parts, including emotes and links. |
synchra.providerLogo(provider) | Renders a provider logo. Its size follows font-size. |
synchra.partsToText(parts) | Converts chat or activity message parts to readable text. |
User-editable settings
Section titled “User-editable settings”Open settings.schema.json in the Explorer to define the controls shown under Settings.
Read the values from synchra.settings.
Settings are also CSS custom properties. For example, accent_color becomes --accent-color.
New widgets include canvas_scale. It affects the browser source, not the editor preview, and can be removed from the schema.
Supported types: string, number, integer, and boolean.
title,description,default: labels and defaultsenum,enumItemLabels: select optionsminimum,maximum,multipleOf: number constraintsformat:color,textarea, orslider
Preview-only controls
Section titled “Preview-only controls”Use synchra.mode for controls that should appear in the editor preview but not in OBS.