Skip to content

Widgets (Win10+)

Warning

Experimental Feature: Windows Widgets for PWAs is currently an experimental feature primarily supported in Microsoft Edge on Windows 11+. The API and behavior may change.

Windows Widgets allow your PWA to provide mini-applications displayed on the Windows widgets dashboard. Users can interact with your app content without opening the full application.

Overview

PWA Widgets use the Adaptive Cards template format to render content in the Windows widget panel. The bundle handles:

  • Manifest configuration: Declaring widgets in the Web App Manifest
  • Service worker integration: Automatic widget lifecycle management (install, update, uninstall)
  • Periodic updates: Background data refresh via Periodic Sync

Configuration

Widgets are configured in the manifest section:

config/packages/pwa.yaml
pwa:
    manifest:
        widgets:
            - name: "Weather Widget"
              short_name: "Weather"
              description: "Current weather conditions at a glance"
              tag: "weather"
              ms_ac_template: 'app_widget_weather_template'  # Symfony route name
              data: 'app_widget_weather_data'                 # Symfony route name
              type: "application/json"
              auth: false
              update: 3600          # Update every hour (in seconds)
              multiple: false       # Only one instance allowed
              screenshots:
                  - src: 'images/widget-weather.png'
                    label: 'Weather widget preview'
              icons:
                  - src: 'images/widget-weather-icon.svg'

Configuration reference

Property Type Required Description
name string Yes Widget title displayed to users
description string Yes Description of the widget
tag string Yes Unique identifier for the widget
ms_ac_template URL/route Yes URL or route name returning the Adaptive Cards template
data URL/route Yes URL or route name returning widget data (JSON)
screenshots array Yes At least one screenshot showing the widget
short_name string No Shorter version of the widget name
type string No MIME type for widget data (default: application/json)
auth boolean No Whether the widget requires authentication
update integer No Update frequency in seconds
multiple boolean No Allow multiple widget instances (default: true)
icons array No Widget-specific icons (falls back to manifest icons)

Server-side implementation

Adaptive cards template

Create a controller that returns an Adaptive Cards template:

src/Controller/WidgetController.php
<?php

declare(strict_types=1);

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Attribute\Route;

final class WidgetController extends AbstractController
{
    #[Route('/widget/weather/template', name: 'app_widget_weather_template')]
    public function template(): JsonResponse
    {
        return $this->json([
            'type' => 'AdaptiveCard',
            '$schema' => 'http://adaptivecards.io/schemas/adaptive-card.json',
            'version' => '1.5',
            'body' => [
                [
                    'type' => 'TextBlock',
                    'text' => '${city}',
                    'size' => 'Large',
                    'weight' => 'Bolder',
                ],
                [
                    'type' => 'TextBlock',
                    'text' => '${temperature}°C - ${condition}',
                    'size' => 'Medium',
                ],
            ],
        ]);
    }

    #[Route('/widget/weather/data', name: 'app_widget_weather_data')]
    public function data(): JsonResponse
    {
        // Fetch actual weather data from your service
        return $this->json([
            'city' => 'Paris',
            'temperature' => 22,
            'condition' => 'Sunny',
        ]);
    }
}

How the service worker works

The bundle automatically generates service worker code that:

  1. On widget install (widgetinstall event):
  2. Fetches the Adaptive Cards template from ms_ac_template
  3. Fetches data from the data URL
  4. Renders the widget using self.widgets.updateByTag()
  5. Registers periodic sync if update is configured

  6. On periodic sync (periodicsync event):

  7. Refreshes the template and data
  8. Updates the widget with fresh content

  9. On widget uninstall (widgetuninstall event):

  10. Unregisters periodic sync when the last widget instance is removed

  11. On service worker activation:

  12. Updates all registered widgets with fresh data

Multiple widgets

You can configure multiple widgets:

config/packages/pwa.yaml
pwa:
    manifest:
        widgets:
            - name: "Weather Widget"
              tag: "weather"
              ms_ac_template: 'app_widget_weather_template'
              data: 'app_widget_weather_data'
              update: 3600
              screenshots:
                  - src: 'images/widget-weather.png'
                    label: 'Weather'

            - name: "News Headlines"
              tag: "news"
              ms_ac_template: 'app_widget_news_template'
              data: 'app_widget_news_data'
              update: 1800   # Every 30 minutes
              multiple: true
              screenshots:
                  - src: 'images/widget-news.png'
                    label: 'News headlines'

Requirements and limitations

  • Platform: Microsoft Edge on Windows 11+ only
  • Template format: Must use Adaptive Cards JSON format
  • Data format: Widget data endpoints must return valid JSON
  • URLs: Template and data URLs must be within the service worker scope
  • Update intervals: Subject to browser/OS scheduling policies (minimum interval may be enforced)
  • Icon size: Icons larger than 1024x1024 are ignored

Resources