# Manifest widgets: PWA content on the OS widgets board

> How the manifest widgets member declares OS-widget-board entries for a PWA — the tag, template/ms_ac_template, data, icons and screenshots fields, the service-worker widgetinstall flow, and current Microsoft Edge/Windows 11 support.

**In one line:** the manifest `widgets` member lets an installed PWA register one or more
widgets for the operating system's widgets dashboard; a service worker then renders and
updates each widget in response to widget lifecycle events.

## What a widget entry declares

`widgets` is an array of `WidgetDefinition` objects on the manifest. Per the PWA-driven
Widgets explainer and Microsoft's widgets how-to, a widget definition's fields include:

- **`name`** — the title of the widget presented to users.
- **`description`** — a description of what the widget does.
- **`tag`** — a string used to reference the widget from the PWA's service worker,
  analogous to a `Notification` tag.
- **`template`** — currently informational and not used to render the widget. Microsoft's
  docs state that only custom **Adaptive Cards** templates are currently supported,
  supplied via the required **`ms_ac_template`** field, which gives the URL of that
  Adaptive Cards template.
- **`data`** — a URL pointing to the JSON data used to populate the template.
- **`icons`** — an array of alternative icons for the widget; if undefined, the icon
  chosen from the manifest's `icons` array is used instead.
- **`screenshots`** — an array of `ImageResource` objects showing what the widget looks
  like, analogous to the manifest's `screenshots` member.

## Rendering a widget from the service worker

Per Microsoft's docs, installing the PWA adds its manifest widgets to the widgets
dashboard, but a widget is not installed — and not rendered — until the user adds it from
that dashboard. The service worker must listen for the `widgetinstall` event and call
`self.widgets.updateByTag()` to render it using the widget's `ms_ac_template` and `data`:

```js
self.addEventListener("widgetinstall", (event) => {
  event.waitUntil(renderWidget(event.widget));
});

async function renderWidget(widget) {
  const template = await fetch(widget.definition.msAcTemplate).then((r) => r.text());
  const data = await fetch(widget.definition.data).then((r) => r.text());
  await self.widgets.updateByTag(widget.definition.tag, { template, data });
}
```

## Browser & ecosystem support

| Engine | Where it ships |
| --- | --- |
| Microsoft Edge (Windows 11) | Implemented, integrating with the Windows 11 Widgets Board, per Microsoft's PWA widgets how-to guide |

The PWA-driven Widgets explainer documents this as a proposal and standards-incubation
starting point; Microsoft's how-to guide documents the shipping Edge/Windows 11
implementation. Always feature-detect before relying on it, since support outside
Edge/Windows 11 is not documented by these sources.

## Minimal example

```json
{
  "widgets": [
    {
      "name": "Task list",
      "description": "Your open tasks, at a glance",
      "tag": "task-list",
      "template": "task-list-template",
      "ms_ac_template": "widgets/task-list-template.json",
      "data": "widgets/task-list-data.json",
      "icons": [{ "src": "widgets/icon-96.png", "sizes": "96x96" }],
      "screenshots": [
        {
          "src": "widgets/screenshot-wide.png",
          "sizes": "600x400",
          "platform": "Windows",
          "label": "Task list widget showing three open tasks"
        }
      ]
    }
  ]
}
```

## Feature detection and fallback

```js
// Inside the service worker (ServiceWorkerGlobalScope).
self.addEventListener("widgetinstall", (event) => {
  if (!("widgets" in self)) {
    // No widgets API here — nothing to render.
    return;
  }
  event.waitUntil(renderWidget(event.widget));
});
```

## Practical checklist

- [ ] Give every widget a unique `tag` — the service worker uses it to identify which
      widget an update, `widgetinstall`, or other lifecycle event belongs to.
- [ ] Supply `name` and `description` — Microsoft's widget-definition example lists both
      as populated fields, alongside `tag`, `template`, and `data`.
- [ ] Don't rely on `template` to render the widget — only a custom Adaptive Cards
      template, given via `ms_ac_template`, is currently supported.
- [ ] Listen for `widgetinstall` in the service worker and call
      `self.widgets.updateByTag()` — a widget added to the manifest is not rendered until
      the service worker does this.
- [ ] If a widget omits `icons`, confirm the manifest's top-level `icons` array is
      appropriate for the widgets dashboard — it is used as the fallback.
- [ ] Don't assume widgets render outside Microsoft Edge on Windows 11 — only that shipping
      implementation is documented by these sources.

## Where to go next

- [Manifest icons](/reference/manifest/icons/) — the fallback icon source for widgets that
  omit their own `icons`.
- [Manifest screenshots](/reference/manifest/screenshots/) — the top-level member sharing
  its shape with a widget's `screenshots`.