---
title: "Widget Previews"
description: "Show people what your widget looks like before they install it. Declare examples once and Hub keeps the images up to date."
canonical: https://glasshome.app/docs/widgets/widget-previews
section: "Build Widgets"
updated: 2026-07-29
---
# 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.

```ts
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.

> **Info:** 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:

```bash
bun widget preview
```

Images land in `preview/`, named `<widget>-<label>-<theme>.png`, one pair per
example. Pass a widget name to do just one:

```bash
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:

```bash
bun add -d playwright && bunx playwright install chromium
```

> **Info:** 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.

```bash
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.

> **Info:** 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. Three or four states that look meaningfully different. Best one first.
  2. So they render with real-looking data.
  3. Open `preview/` and check both themes.
  4. The images follow automatically.