Skip to main content

Property schema

A property is a control a streamer configures when they add your widget — a colour, a number, a font, a toggle. You define your widget's properties on the Properties surface, and Streamerly generates the configuration form from them automatically. There's nothing to wire up: define a property, and it appears in the panel beside the widget.

Each property you read in two places:

  • In code as props.<name> (or the useProp('<name>') hook in a template).
  • In CSS as a variable, var(--<name>).

Defining a property

On the Properties surface, click Add property and fill in:

FieldMeaning
KeyThe stable identifier (e.g. accent-colour). Everything else derives from it. Don't rename it after release — it's how saved configurations are matched.
TypeThe kind of control (see below).
LabelWhat the streamer sees above the control.
DescriptionOptional helper text under the control.
Default valueThe value used until the streamer changes it.
GroupOptional section heading to organise a long form.
RequiredMark the field as required.

Field types

TypeControlNotable options
textText boxmultiline, placeholder, maxLength
numberNumber inputmin, max, step, suffix (e.g. px), slider to render as a slider
rangeSlidermin, max, step (required), suffix
booleanSwitchdisplay: 'checkbox' for a checkbox instead
selectDropdownselectOptions (the choices); display: 'segmented' for inline buttons
colorColour pickeralpha for transparency; swatches for suggested colours
swatchPreset colour pickerswatches — the locked set the streamer picks from
extended-colorRich fill editorA solid colour, gradient or image fill. Normally an object — read it off props, not CSS — but it arrives as a bare CSS string (#f00, linear-gradient(...)) when the streamer binds the field to live data, so handle both.
imageAsset pickerPicks an image from the streamer's library.
audioAsset pickerPicks a sound from the streamer's library.
fontFont pickerPicks one of the platform fonts.
directionAngle dialDegrees 0360.
channel-point-redeemChannel-point reward pickerThe streamer picks one of their own Twitch rewards; the value is the reward's Twitch id.
power-upPower-up pickerThe streamer picks one of their Twitch Power-Ups; the value is its id.
twitch-categoryTwitch category searchThe value is a { id, name } object.
tip

The channel-point-redeem, power-up and twitch-category pickers pair naturally with bindings. Add a channel-point-redeem property and match its value against the rewardId on a Channel Points event to fire only for that reward.

Reading a property in code

A property's key becomes a camelCase name on the props object. So accent-colourprops.accentColour:

import { onLoad, props } from '@widget';

onLoad(() => {
console.log(props.accentColour); // the configured value, or the default
});

Inside a template, use the useProp hook so the template re-renders when the streamer changes the value:

import { useProp } from '@widget';

export default function Main() {
const colour = useProp('accentColour');
return <div style={{ color: colour }}>Hello</div>;
}

Reading a property in CSS

The same key becomes a kebab-case CSS variable. So accent-colourvar(--accent-colour):

.title {
color: var(--accent-colour);
}

This is the easiest way to wire a colour or size straight into your styles — no code needed.

Naming

The two names are derived from the key automatically (accent-colourprops.accentColour and var(--accent-colour)). If you need a different name, set an explicit JS name or CSS variable on the property to override the derived one.

Show a field only when it's relevant

A property can declare a visibility condition so its control only appears when another property has a certain value. Write a small boolean expression that references sibling properties by their JS name:

showLogo === true && logoOpacity > 50

The logo-opacity control then only shows when Show logo is on and opacity is above 50. If the expression can't be evaluated, the field is shown anyway — a bad condition never hides a control by mistake. Hidden fields still resolve to their value in code and CSS; this only affects the form.

Next