Générer des widgets pilotés par PWA
Différents systèmes d’exploitation ont des tableaux de bord de widgets qui permettent aux utilisateurs de lire du contenu et d’effectuer des tâches. Les widgets Écran d’accueil Android, le tableau de bord macOS et le panneau aujourd’hui, la barre tactile Apple, les cartes quotidiennes Samsung, les widgets mini-application et les compagnons d’application de montre intelligente en sont des exemples.
Sur Windows 11, les widgets apparaissent dans le tableau widgets, que vous ouvrez à gauche de la barre des tâches :
Dans Windows 11, les applications web progressives (PWA) peuvent définir des widgets, les mettre à jour et gérer les interactions utilisateur qu’ils contiennent.
Nécessite la création d’un widget personnalisé pour le PWA
Une PWA existante ne peut pas simplement être placée dans le tableau de bord du widget en l’état, comme vous le pouvez avec la barre latérale Microsoft Edge. Au lieu de cela, vous devez créer une expérience de widget personnalisée appropriée pour l’hôte du widget, qui est actuellement le tableau des widgets Windows 11. (Il peut y avoir d’autres hôtes de widgets à l’avenir.) Le tableau des widgets Windows 11 exige que les widgets soient générés à l’aide de modèles de carte adaptative au lieu de HTML et JavaScript. Par conséquent, le widget doit être conçu séparément du reste de l’interface utilisateur de l’application.
Voir aussi :
Pour créer un widget piloté par PWA et le remettre via le Microsoft Store, aucun code C++/C# n’est requis. Une fois que vous avez produit le widget et que vous pouvez l’installer et l’exécuter correctement à partir d’un point de terminaison public, vous pouvez empaqueter l’application à l’aide de PWABuilder.com et expédier l’application au Microsoft Store sans nécessiter de code supplémentaire. Le widget PWA de sauvegarde doit être installable à partir d’un point de terminaison public, car PWABuilder.com ne prend pas en charge l’empaquetage des applications à partir de localhost.
Voir aussi :
Installer WinAppSDK et activer le mode développeur
Pour activer le développement et le test de widgets sur votre ordinateur local :
Installez WinAppSDK 1.2.
Activer le mode développeur dans Windows 11 :
Ouvrez Paramètres.
Dans la zone de texte Rechercher un paramètre , entrez
developer
, puis cliquez sur Utiliser les fonctionnalités de développement.Activer le mode développeur :
Définir des widgets
Les widgets sont définis dans votre fichier manifeste PWA, à l’aide du membre de widgets
manifeste. Ce membre de manifeste est un tableau qui peut contenir plusieurs définitions de widget.
{
"name": "PWAmp",
"description": "A music player app",
"icons": [
{ "src": "img/icon-96.png", "sizes": "96x96" },
{ "src": "img/icon-128.png", "sizes": "128x128" },
{ "src": "img/icon-256.png", "sizes": "256x256" },
{ "src": "img/icon-512.png", "sizes": "512x512" }
],
"widgets": [
/* widget definitions go here */
]
}
Chaque entrée du widgets
tableau contient plusieurs champs, comme indiqué ci-dessous :
{
...
"widgets": [
{
"name": "PWAmp mini player",
"description": "widget to control the PWAmp music player",
"tag": "pwamp",
"template": "pwamp-template",
"ms_ac_template": "widgets/mini-player-template.json",
"data": "widgets/mini-player-data.json",
"type": "application/json",
"screenshots": [
{
"src": "./screenshot-widget.png",
"sizes": "600x400",
"label": "The PWAmp mini-player widget"
}
],
"icons": [
{
"src": "./favicon-16.png",
"sizes": "16x16"
}
],
"auth": false,
"update": 86400
}
]
}
Dans l’exemple ci-dessus, une application de lecteur de musique définit un widget de mini-lecteur. Une définition de widget dans le manifeste de l’application web comporte les champs obligatoires et facultatifs suivants :
Champ | Description | Obligatoire |
---|---|---|
name |
Titre du widget, présenté aux utilisateurs. | Oui |
short_name |
Autre version courte du nom. | Non |
description |
Description de ce que fait le widget. | Oui |
icons |
Tableau d’icônes à utiliser pour le widget. S’il est manquant, le membre de icons manifeste est utilisé à la place. Les icônes supérieures à 1024 x 1024 sont ignorées. |
Non |
screenshots |
Tableau de captures d’écran qui montrent à quoi ressemble le widget. Analogue au membre de screenshot manifeste. Le platform champ d’un élément de capture d’écran prend en charge les Windows valeurs et any . Les images d’une taille supérieure à 1024 x 1024 pixels sont ignorées. Pour connaître les exigences de capture d’écran spécifiques au tableau des widgets Windows 11, consultez Configuration requise pour les images de capture d’écran dans Intégrer au sélecteur de widgets. |
Oui |
tag |
Chaîne utilisée pour référencer le widget dans le worker du service PWA. | Oui |
template |
Modèle à utiliser pour afficher le widget dans le tableau de bord des widgets du système d’exploitation. Remarque : cette propriété est actuellement uniquement informative et n’est pas utilisée. Voir ms_ac_template ci-dessous. |
Non |
ms_ac_template |
URL du modèle cartes adaptatives personnalisé à utiliser pour afficher le widget dans le tableau de bord des widgets du système d’exploitation. Consultez Définir un modèle de widget ci-dessous. | Oui |
data |
URL où se trouvent les données avec lesquelles remplir le modèle. Si elle est présente, cette URL est requise pour retourner un JSON valide. | Non |
type |
Type MIME pour les données du widget. | Non |
auth |
Valeur booléenne indiquant si le widget nécessite une authentification. | Non |
update |
Fréquence, en secondes, à laquelle le widget sera mis à jour. Le code de votre worker de service doit effectuer la mise à jour ; le widget n’est pas mis à jour automatiquement. Consultez Accéder aux instances de widget au moment de l’exécution. | Non |
multiple |
Valeur booléenne indiquant s’il faut autoriser plusieurs instances du widget. La valeur par défaut est true . |
Non |
Définir un modèle de widget
Pour faciliter la création et l’adaptation des widgets à différents tableaux de bord de widgets de système d’exploitation, ils sont affichés à l’aide de modèles. Il existe deux types de modèles :
- Modèles génériques, définis par leur nom à l’aide du
template
champ . - Modèles personnalisés, définis par leurs URL à l’aide d’un champ de modèle personnalisé.
Pour le moment, seuls les modèles de cartes adaptatives personnalisés sont pris en charge. Les cartes adaptatives sont un format d’échange de carte ouvert qui peut être utilisé pour échanger le contenu de l’interface utilisateur de manière commune et cohérente. Consultez Vue d’ensemble des cartes adaptatives.
Pour définir un modèle de cartes adaptatives personnalisé sur Windows 11, utilisez le ms_ac_template
champ dans la définition de widget qui se trouve dans le manifeste de votre application web. Bien qu’il ne soit template
pas utilisé actuellement, il s’agit d’un champ obligatoire.
{
...
"template": "pwamp-template",
"ms_ac_template": "widgets/mini-player.json",
...
}
La ms_ac_template
valeur du champ doit être une URL valide d’un fichier de modèle.
Voici un exemple de modèle de cartes adaptatives :
{
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"size": "Medium",
"text": "Now playing...",
"horizontalAlignment": "Center"
},
{
"type": "TextBlock",
"spacing": "Large",
"weight": "Bolder",
"horizontalAlignment": "Center",
"text": "${song}, by ${artist}",
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.5"
}
Pour plus d’informations, consultez Création de modèles de cartes adaptatives.
Ensuite, vous devez lier les données à votre modèle.
Lier des données à votre modèle
Le modèle déclare l’interface utilisateur d’un widget. Les données remplissent ensuite cette interface utilisateur.
Pour lier des données à votre modèle, utilisez le data
champ dans votre définition de widget. Ce champ doit être défini sur une URL qui retourne des données JSON valides.
Le modèle défini dans la section précédente contient deux variables : song
et artist
, qui sont incluses dans la syntaxe d’expression de liaison : ${}
. Les données retournées par l’URL dans votre data
définition de widget doivent contenir des valeurs pour ces variables.
Voici un exemple de ce que l’URL data
peut retourner :
{
"song": "I Will Always Love You",
"artist": "Whitney Houston"
}
Définir des actions de widget
Si vous souhaitez que votre widget permet aux utilisateurs d’effectuer des tâches, définissez un modèle qui prend en charge les actions.
Voici un exemple d’action définie dans un modèle de cartes adaptatives personnalisé :
{
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"size": "Medium",
"text": "Now playing...",
"horizontalAlignment": "Center"
},
{
"type": "TextBlock",
"spacing": "Large",
"weight": "Bolder",
"horizontalAlignment": "Center",
"text": "${song}, by ${artist}",
}
],
"actions": [
{
"type": "Action.Execute",
"title": "Previous",
"verb": "previous-song"
},
{
"type": "Action.Execute",
"title": "Next",
"verb": "next-song"
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.5"
}
Notez le verb
champ dans le modèle JSON ci-dessus. Il sera utilisé lors de la gestion des actions de widget dans votre code worker de service. Consultez Gérer les actions de widget.
Accéder aux instances de widget au moment de l’exécution
Vous pouvez accéder aux widgets et les mettre à jour à partir du code worker du service PWA. L’accès aux widgets au moment de l’exécution est utile dans les cas suivants :
- Widgets de rendu lors de l’installation.
- Mise à jour des widgets sur les mises à jour du Service Worker.
- Gestion des actions de l’utilisateur sur les widgets.
- Mise à jour des widgets lorsque l’application change.
Un worker de service a accès à l’objet self.widgets
et à plusieurs événements de widget qui, ensemble, constituent une API que vous utilisez pour réagir aux modifications et accéder aux widgets au moment de l’exécution.
Les sections suivantes fournissent des exemples de code. Pour obtenir une référence de l’API, consultez les informations de référence sur l’API de travail de service.
Afficher les widgets lors de l’installation
Lorsqu’une PWA est installée, les widgets que l’application définit dans son manifeste sont ajoutés au tableau de bord des widgets, mais pas encore installés. Un widget est installé uniquement lorsque l’utilisateur choisit d’ajouter le widget à partir du tableau de bord.
Lorsqu’un widget est installé, il n’est pas automatiquement affiché à l’aide des ms_ac_template
champs et data
de la définition du widget.
Pour afficher le widget, écoutez l’événement widgetinstall
dans votre service Worker et mettez à jour le widget à l’aide de la widgets.updateByTag
fonction :
// Listen to the widgetinstall event.
self.addEventListener("widgetinstall", event => {
// The widget just got installed, render it using renderWidget.
// Pass the event.widget object to the function.
event.waitUntil(renderWidget(event.widget));
});
async function renderWidget(widget) {
// Get the template and data URLs from the widget definition.
const templateUrl = widget.definition.msAcTemplate;
const dataUrl = widget.definition.data;
// Fetch the template text and data.
const template = await (await fetch(templateUrl)).text();
const data = await (await fetch(dataUrl)).text();
// Render the widget with the template and data.
await self.widgets.updateByTag(widget.definition.tag, {template, data});
}
Mettre à jour les widgets sur les mises à jour du Service Worker
Lorsque le code du Service Worker change dans une PWA, le navigateur détecte cette modification, installe le nouveau Service Worker, puis active ultérieurement le Service Worker.
Dans ce cas, il est important de mettre à jour toutes les instances de widget qui sont peut-être déjà en cours d’exécution. Les widgets ont peut-être été installés avant l’émission de l’événement service Worker activate
. Pour éviter d’afficher des widgets vides, mettez à jour vos widgets lorsque l’événement activate
se produit
// Update the widgets to their initial states
// when the service worker is activated.
self.addEventListener("activate", event => {
event.waitUntil(updateWidgets());
});
async function updateWidgets() {
// Get the widget that match the tag defined in the web app manifest.
const widget = await self.widgets.getByTag("pwamp");
if (!widget) {
return;
}
// Using the widget definition, get the template and data.
const template = await (await fetch(widget.definition.msAcTemplate)).text();
const data = await (await fetch(widget.definition.data)).text();
// Render the widget with the template and data.
await self.widgets.updateByTag(widget.definition.tag, {template, data});
}
Gérer les actions de widget
Si le modèle de widget contient des actions, les utilisateurs peuvent exécuter ces actions en cliquant sur des boutons dans le widget rendu. Pour plus d’informations sur la définition d’actions dans un modèle, consultez Définir des actions de widget.
Lorsqu’un utilisateur exécute une action de widget, un widgetclick
événement est déclenché dans le worker du service PWA. Pour gérer l’action de l’utilisateur, écoutez l’événement :
self.addEventListener('widgetclick', (event) => {
switch (event.action) {
case 'previous-song':
// Application logic to play the previous song...
break;
case 'next-song':
// Application logic to play the next song...
break;
}
});
Par souci de concision, le code d’application réel n’est pas affiché dans l’extrait de code ci-dessus. Lorsque les previous-song
actions ou next-song
sont reçues, un message doit probablement être envoyé à l’application à l’aide de Client.postMessage pour informer l’application qu’elle doit commencer à lire les chansons précédentes ou suivantes.
Notez que la action
propriété de l’objet widgetEvent
passé à l’écouteur d’événements ci-dessus correspond à la chaîne définie dans le action.verb
champ du modèle de widget.
Pour plus d’informations sur l’événement et sur les widgetclick
informations accessibles à partir de celui-ci, consultez Informations de référence sur l’API Service Worker, ci-dessous.
Mettre à jour les widgets sur les modifications apportées à l’application
Dans les sections précédentes, vous avez appris à mettre à jour des widgets lorsque des événements de widget, des actions de widget et des mises à jour de travail de service spécifiques se sont produits. Il peut également être utile de mettre à jour les widgets lorsqu’un événement se produit dans l’application, ou lorsqu’une notification Push se produit, ou régulièrement.
Dans cette section, vous allez apprendre à utiliser l’API synchronisation périodique en arrière-plan pour mettre à jour régulièrement les widgets. Pour plus d’informations sur l’API synchronisation périodique en arrière-plan, consultez Utiliser l’API de synchronisation en arrière-plan périodique pour obtenir régulièrement du contenu actualisé.
Dans l’extrait de code suivant, un écouteur d’événements est utilisé pour réagir à différents événements de cycle de vie du widget d’application. Lorsqu’une installation de widget est détectée, une synchronisation périodique est inscrite et lorsqu’une suppression de widget est détectée, la synchronisation périodique est annulée.
Lorsque des événements de synchronisation périodiques se produisent, les instances de widget sont mises à jour à l’aide de la widgets.updateByTag
fonction .
self.addEventListener("widgetinstall", event => {
event.waitUntil(onWidgetInstall(event.widget));
});
self.addEventListener("widgetuninstall", event => {
event.waitUntil(onWidgetUninstall(event.widget));
});
async function onWidgetInstall(widget) {
// Register a periodic sync, if this wasn't done already.
// We use the same tag for the sync registration and the widget to
// avoid registering several periodic syncs for the same widget.
const tags = await self.registration.periodicSync.getTags();
if (!tags.includes(widget.definition.tag)) {
await self.registration.periodicSync.register(widget.definition.tag, {
minInterval: widget.definition.update
});
}
// And also update the instance.
await updateWidget(widget);
}
async function onWidgetUninstall(widget) {
// On uninstall, unregister the periodic sync.
// If this was the last widget instance, then unregister the periodic sync.
if (widget.instances.length === 1 && "update" in widget.definition) {
await self.registration.periodicSync.unregister(widget.definition.tag);
}
}
// Listen to periodicsync events to update all widget instances
// periodically.
self.addEventListener("periodicsync", async event => {
const widget = await self.widgets.getByTag(event.tag);
if (widget && "update" in widget.definition) {
event.waitUntil(updateWidget(widget));
}
});
async function updateWidget(widget) {
// Get the template and data URLs from the widget definition.
const templateUrl = widget.definition.msAcTemplate;
const dataUrl = widget.definition.data;
// Fetch the template text and data.
const template = await (await fetch(templateUrl)).text();
const data = await (await fetch(dataUrl)).text();
// Render the widget with the template and data.
await self.widgets.updateByTag(widget.definition.tag, {template, data});
}
Application de démonstration
PWAmp est une application de démonstration PWA de lecteur de musique qui définit un widget. Le widget PWAmp permet aux utilisateurs de visualiser la chanson actuelle et de lire les chansons précédentes ou suivantes.
Si ce n’est pas encore fait, installez WinAppSDK 1.2 et activez le mode développeur dans Windows 11.
Accédez à PWAmp et installez l’application sur Windows 11.
Ouvrez la carte des widgets Windows 11 en appuyant sur la touche de logo Windows + W.
Cliquez sur Ajouter des widgets pour ouvrir l’écran des paramètres des widgets , faites défiler jusqu’au widget de mini-lecteur PWAmp et ajoutez-le.
Fermez l’écran des paramètres des widgets . Le mini-lecteur PWAmp s’affiche désormais dans le tableau widgets.
Le widget PWAmp affiche la chanson actuelle et les boutons pour lire la chanson précédente ou suivante.
Informations de référence sur l’API Service Worker
L’objet global Service Worker (ou ServiceWorkerGlobalScope) contient un widgets
attribut qui expose les méthodes basées sur promise suivantes :
Méthode | Description | Paramètres | Valeur renvoyée |
---|---|---|---|
getByTag(tag) |
Obtient un widget par étiquette. | Balise de widget | Promesse qui se résout en objet widget qui correspond à la balise, ou undefined . |
getByInstanceId(id) |
Obtient un widget par ID d’instance. | ID de l’instance de widget | Promesse qui se résout en objet widget correspondant, ou undefined . |
getByHostId(id) |
Obtient les widgets par ID d’hôte. | ID d’hôte | Tableau d’objets widget trouvés dans cet hôte. |
matchAll(options) |
Obtient les widgets en mettant en correspondance les options. | Objet widgetOptions | Promesse qui se résout en tableau d’objets de widget qui correspondent aux options critères. |
updateByInstanceId(id, payload) |
Met à jour un widget par ID d’instance. | ID d’instance et objet widgetPayload | Promesse qui se résout en undefined ou Error . |
updateByTag(tag, payload) |
Met à jour un widget par étiquette. | Balise de widget et objet widgetPayload | Promesse qui se résout en undefined ou Error . |
L’objet global service Worker définit également les événements suivants :
-
widgetinstall
: déclenché lorsque l’hôte du widget installe un widget. -
widgetuninstall
: déclenché lorsque l’hôte du widget désinstalle un widget. -
widgetresume
: déclenché lorsque l’hôte du widget reprend le rendu des widgets installés, ce qui peut se produire après que l’hôte a suspendu le rendu des widgets pour préserver les ressources. -
widgetclick
: déclenché lorsque l’utilisateur exécute l’une des actions du widget.
Pour plus d’informations sur les objets fournis avec ces événements, consultez l’objet widgetEvent et l’objet widgetClickEvent ci-dessous.
objet widget
Chaque widget est représenté sous la forme d’un widget
objet, qui contient les propriétés suivantes :
-
installable
: valeur booléenne indiquant si le widget est installable. -
definition
: objet widgetDefinition. -
instances
: tableau d’objets widgetInstance représentant l’état actuel de chaque instance du widget.
objet widgetOptions
Lorsque vous utilisez matchAll(options)
pour obtenir plusieurs widgets, un widgetOptions
objet est nécessaire pour filtrer les widgets à retourner. L’objet widgetOptions
contient les propriétés suivantes, toutes facultatives :
-
installable
: valeur booléenne indiquant si les widgets retournés doivent être installables. -
installed
: valeur booléenne indiquant si les widgets retournés sont installés dans l’hôte du widget. -
tag
: chaîne utilisée pour filtrer les widgets retournés par balise. -
instanceId
: chaîne utilisée pour filtrer les widgets retournés par ID d’instance. -
hostId
: chaîne utilisée pour filtrer les widgets retournés par ID d’hôte de widget.
objet widgetPayload
Lors de la création ou de la mise à jour d’une instance de widget, le service Worker doit envoyer le modèle et les données nécessaires pour remplir le widget. Le modèle et les données sont appelés charge utile. L’objet widgetPayload
contient les propriétés suivantes :
-
template
: modèle, sous forme de chaîne, à utiliser pour afficher le widget. Il s’agit du json stringifié d’un modèle de carte adaptative. -
data
: données, sous forme de chaîne, à utiliser avec le modèle de widget. Ces données peuvent être des données JSON stringifiées.
objet widgetInstance
Cet objet représente une instance donnée d’un widget dans un hôte de widget et contient les propriétés suivantes :
-
id
: chaîne GUID interne utilisée pour référencer l’instance. -
host
: pointeur interne vers l’hôte de widget qui a installé cette instance. -
updated
Date
: objet qui représente la dernière fois que les données ont été envoyées à l’instance. -
payload
: objet widgetPayload qui représente la dernière charge utile envoyée à cette instance.
objet widgetDefinition
Cet objet représente la définition d’origine du widget, qui se trouve dans le fichier manifeste PWA. Les propriétés de cet objet correspondent aux propriétés répertoriées dans Définir des widgets, ci-dessus.
objet widgetEvent
Cet objet est passé en tant qu’argument aux écouteurs des événements de widget de travail de service de type widgetinstall
, widgetuninstall
et widgetresume
.
Pour les widgetinstall
types d’événements , widgetuninstall
et widgetresume
, l’objet widgetEvent
a les propriétés suivantes :
Propriété | Description | Type |
---|---|---|
widget |
Instance de widget qui a déclenché l’événement. | widget |
instanceId |
ID d’instance de widget. | String |
hostId |
ID d’hôte du widget. | String |
objet widgetClickEvent
Cet objet est passé en tant qu’argument aux écouteurs des événements de widget de travail de service de type widgetclick
. Vous pouvez ouvrir la fenêtre de votre application en réponse à l’événement, à l’aide widgetclick
clients.openWindow()
de .
L’objet widgetClickEvent
a les propriétés suivantes :
Propriété | Description | Type |
---|---|---|
action |
Action qui a déclenché l’événement, telle que définie dans les actions.verb champs du modèle de widget. Consultez Définir des actions de widget. |
String |
widget |
Instance de widget qui a déclenché l’événement. | widgetInstance |
hostId |
ID d’hôte du widget. | String |
instanceId |
ID d’instance de widget. | String |