Widget Previews
Someone browsing for a widget sees its name, its icon and a sentence. That is not much to decide on. Previews replace that with pictures of your widget doing its job, on the Hub page and in the dashboard’s widget browser, before anyone installs it.
You write a short list of showcase states. Everything else happens for you: each one is pictured in both light and dark, and the images refresh every time you publish a new version. There is nothing to upload and nothing to keep in sync.
Declare your examples
Add examples to your manifest in defineWidget. Each entry is a config to
render, the size to render it at, and a label for your own reference.
export default defineWidget<LightConfig>({
manifest: {
name: "Light",
minSize: { w: 1, h: 1 },
maxSize: { w: 4, h: 4 },
sdkVersion: "^1.7.0",
examples: [
{
label: "Single light",
size: { w: 2, h: 2 },
config: { title: "Reading Lamp", entityIds: ["light.bedroom_ceiling"] },
},
{
label: "Room group",
size: { w: 3, h: 2 },
config: {
title: "Living Room",
entityIds: ["light.living_room_main", "light.kitchen_counter"],
},
},
],
},
configSchema,
component: LightWidget,
});
configis a real config for your widget, the same shape a user would end up with. It has to satisfy yourconfigSchema.sizeis in grid tiles, the same units asminSizeandmaxSize. Picture each state at the size it actually looks good.labelis optional and for your own orientation while writing them.
The first example is the one used as your widget’s thumbnail, so lead with the state that best represents it.
Pick your best few
Three or four is usually right. You are showing range, not documenting every option: the states worth picturing are the ones that look meaningfully different from each other.
Up to 20 examples are pictured. If you declare more, the extras are not rendered, so keep the list to the states you actually want people to see.
Use the demo home
Your examples reference entities from GlassHome’s demo home, so they render with sensible data instead of empty states. Some of what is available:
| Domain | Examples |
|---|---|
light |
light.bedroom_ceiling, light.living_room_main, light.kitchen_counter, light.hallway, light.bathroom, light.studio_rgb, light.desk_rgb |
climate |
climate.living_room_thermostat, climate.bedroom_ac |
cover |
cover.garage_door, cover.kitchen_blinds, cover.living_room_blinds, cover.bedroom_curtains |
lock |
lock.front_door_lock, lock.back_door_lock |
switch |
switch.coffee_machine, switch.fan_living_room |
media_player |
media_player.living_room_speaker |
There are around 50 in total, including a generous set of sensor entities for
readouts and graphs. The demo home is the same one the dashboard’s demo mode
uses, so anything you can build against there works here.
light.studio_rgb and light.desk_rgb are colour-capable, which is handy if
your widget has anything to show off in colour.
See them before you publish
Render your examples locally and look at them:
bun widget preview
Images land in preview/, named <widget>-<label>-<theme>.png, one pair per
example. Pass a widget name to do just one:
bun widget preview light
This uses a real browser, which is not installed by default. If it is missing, the command tells you exactly this:
bun add -d playwright && bunx playwright install chromium
Iterate here, not by publishing. Local previews are rendered the same way as
the published ones, so what you see in preview/ is what people will see.
Publish
Nothing extra to do.
bun widget publish --name light --bump patch --scope your-scope
Your previews appear on the widget’s Hub page and in the dashboard’s widget browser shortly after. Each version keeps its own images, so an older version still shows what it looked like.
If a set of images cannot be produced, your version still publishes normally and simply shows its icon instead. Publishing never waits on previews and never fails because of them.
No previews is fine
Most widgets in the catalogue have none, and nothing marks them as incomplete.
Widgets published before examples existed cannot have them, since a published
version is frozen. Adding examples and publishing a new version is how any
widget gets them.
Checklist
- 1
Add examples to your manifest
Three or four states that look meaningfully different. Best one first.
- 2
Point their configs at demo entities
So they render with real-looking data.
- 3
Run bun widget preview
Open
preview/and check both themes. - 4
Publish
The images follow automatically.