Skip to content

Updated

View MarkdownOpen in ChatGPTOpen in Claude

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,
});
  • config is a real config for your widget, the same shape a user would end up with. It has to satisfy your configSchema.
  • size is in grid tiles, the same units as minSize and maxSize. Picture each state at the size it actually looks good.
  • label is 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. 1

    Add examples to your manifest

    Three or four states that look meaningfully different. Best one first.

  2. 2

    Point their configs at demo entities

    So they render with real-looking data.

  3. 3

    Run bun widget preview

    Open preview/ and check both themes.

  4. 4

    Publish

    The images follow automatically.