Skip to content

Commit 9cb2571

Browse files
committed
Merged main into live
2 parents 4f37052 + 1c6302b commit 9cb2571

File tree

5 files changed

+197
-0
lines changed

5 files changed

+197
-0
lines changed

hub/apps/develop/widgets/implement-widget-provider-cs.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ public static Dictionary<string, CompactWidgetInfo> RunningWidgets = new Diction
8080

8181
This example will declare some static strings to define the JSON templates for each widget. For convenience, these templates are stored in the member variables of the **WidgetProvider** class. If you need a general storage for the templates - they can be included as part of the application package: [Accessing Package Files](/windows/uwp/app-resources/uri-schemes#ms-appx-and-ms-appx-web). For information on creating the widget template JSON document, see [Create a widget template with the Adaptive Card Designer](../../design/widgets/widgets-create-a-template.md).
8282

83+
In the latest release, apps that implement Windows widgets can customize the header that is displayed for their widget in the Widgets Board, overriding the default presentation. For more information, see [Customize the widget header area](widget-header-customization.md).
84+
85+
> [!NOTE]
86+
> In the latest release, apps that implement Windows widgets can choose to populate the widget content with HTML served from a specified URL instead of supplying content in the Adaptive Card schema format in the JSON payload passed from the provider to the Widgets Board. Widget providers must still provide an Adaptive Card JSON payload, so the implementation steps in this walkthrough are applicable to web widgets. For more information, see [Web widget providers](web-widget-providers.md).
87+
8388
```csharp
8489
// WidgetProvider.cs
8590

hub/apps/develop/widgets/implement-widget-provider-win32.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,11 @@ struct WidgetProvider : winrt::implements<WidgetProvider, winrt::Microsoft::Wind
160160
161161
This example will declare some static strings to define the JSON templates for each widget. For convenience, these templates are stored in the local variables declared outside of the **WidgetProvider** class definition. If you need a general storage for the templates - they can be included as part of the application package: [Accessing Package Files](/windows/uwp/app-resources/uri-schemes#ms-appx-and-ms-appx-web). For information on creating the widget template JSON document, see [Create a widget template with the Adaptive Card Designer](../../design/widgets/widgets-create-a-template.md).
162162
163+
In the latest release, apps that implement Windows widgets can customize the header that is displayed for their widget in the Widgets Board, overriding the default presentation. For more information, see [Customize the widget header area](widget-header-customization.md).
164+
165+
> [!NOTE]
166+
> Starting with Windows Build [TBD - Build number], apps that implement Windows widgets can choose to populate the widget content with HTML served from a specified URL instead of supplying content in the Adaptive Card schema format in the JSON payload passed from the provider to the Widgets Board. Widget providers must still provide an Adaptive Card JSON payload, so the implementation steps in this walkthrough are applicable to web widgets. For more information, see [Web widget providers](web-widget-providers.md).
167+
163168
```cpp
164169
// WidgetProvider.h
165170
const std::string weatherWidgetTemplate = R"(
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
---
2+
title: Web widget providers
3+
description: Learn how to implement a widget that displays content from a web source
4+
ms.topic: article
5+
ms.date: 11/19/2024
6+
ms.localizationpriority: medium
7+
---
8+
9+
# Web widget providers
10+
11+
In the latest release, apps that implement Windows widgets can choose to populate the widget content with HTML served from a remote URL. Previously, the widget content could only be supplied in the Adaptive Card schema format in the JSON payload passed from the provider to the Widgets Board. Because web widget providers must still provide an Adaptive Card JSON payload, you should follow the steps for implementing a widget provider in [Implement a widget provider in a C# Windows App](implement-widget-provider-cs.md) or [Implement a widget provider in a win32 app (C++/WinRT)](implement-widget-provider-win32.md).
12+
13+
## Specify the content URL
14+
15+
Widget providers pass a JSON payload to the Widgets Board with a call to [WidgetManager.UpdateWidget](/windows/windows-app-sdk/api/winrt/microsoft.windows.widgets.providers.widgetmanager.updatewidget). For a web widget, instead of providing a **body** object defining the widget content, you should specify an empty **body** object and instead include a **metadata** object with a **webUrl** field that points to the URL that will supply the HTML content for the widget.
16+
17+
```json
18+
{
19+
    "type": "AdaptiveCard",
20+
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
21+
    "version": "1.6",
22+
    "body": [],
23+
    "metadata":
24+
    {
25+
        "webUrl": "https://www.contoso.com/widgetprovider.html"
26+
    }
27+
}
28+
```
29+
30+
## Handle resource requests
31+
32+
Widget providers can specify a web request filter string for a widget in the *WebRequestFilter* attribute of the **Definition** element in the provider's package manifest file. Whenever the widget content requests a resource by URI that matches the filter, the request will be intercepted and redirected to the widget provider's implementation of [IWidgetResourceProvider.OnResourceRequested](/windows/windows-app-sdk/api/winrt/microsoft.windows.widgets.providers.iwidgetresourceprovider.onresourcerequested).
33+
34+
The filter pattern is expressed using the format described in [Match Patterns](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Match_patterns). The filter string in the registration must use [Punycode](https://en.wikipedia.org/wiki/Punycode) where necessary. All content types will be redirected when matched so the filter should only resolve to content intended to be obtained through the **IWidgetResourceProvider** in the application. For more information on the widget provider package manifest format, see [Widget provider package manifest XML format](/windows/apps/develop/widgets/widget-provider-manifest).
35+
36+
To handle resource requests, widget providers must implement the [IWidgetResourceProvider](/windows/windows-app-sdk/api/winrt/microsoft.windows.widgets.providers.iwidgetresourceprovider) interface.
37+
38+
```csharp
39+
internal class WidgetProvider : IWidgetProvider, IWidgetResourceProvider
40+
```
41+
42+
In the implementation of the **OnResourceRequested** method, widget providers can provide the requested resources by setting the [WidgetResourceRequestedArgs.Response](/windows/windows-app-sdk/api/winrt/microsoft.windows.widgets.providers.widgetresourcerequestedargs.response) property to a [WidgetResourceResponse](/windows/windows-app-sdk/api/winrt/microsoft.windows.widgets.providers.widgetresourceresponse) object containing the requested resource. When obtaining the resource asynchronously, the provider should request a deferral by calling [WidgetResourceRequestedArgs.GetDeferral](/windows/windows-app-sdk/api/winrt/microsoft.windows.widgets.providers.widgetresourcerequestedargs.getdeferral) and then complete the deferral when the resource has been set.
43+
44+
```csharp
45+
async void IWidgetResourceProvider.OnResourceRequested(WidgetResourceRequestedArgs args)
46+
{
47+
var deferral = args.GetDeferral();
48+
49+
if (args.Request.Uri.Length > 0)
50+
{
51+
if (args.Request.Uri == "https://contoso.com/logo-image")
52+
{
53+
string fullPath = Windows.ApplicationModel.Package.Current.InstalledPath + "/Assets/image.png";
54+
var file = await StorageFile.GetFileFromPathAsync(fullPath);
55+
var response = new WidgetResourceResponse(RandomAccessStreamReference.CreateFromFile(file), "OK", 200);
56+
response.Headers.Add("Content-Type", "image/png");
57+
args.Response = response;
58+
}
59+
}
60+
61+
deferral.Complete();
62+
}
63+
```
64+
65+
If the provider does not set a response on the **WidgetResourceRequestedArgs** object passed into the method, the system will retrieve the resource from the web. In this case, the provider can choose to modify the [Headers](/windows/windows-app-sdk/api/winrt/microsoft.windows.widgets.providers.widgetresourcerequestedargs.headers) property of the [WidgetResourceRequestedArgs.Request](/windows/windows-app-sdk/api/winrt/microsoft.windows.widgets.providers.widgetresourcerequestedargs.request) object, such as to provide user context or tokens, and the system will use the updated headers when retrieving the resource from the web.
66+
67+
## Handle messages to and from web content
68+
69+
To receive string messages from the widget's content that has been posted using the [window.chrome.webview.postMessage](/microsoft-edge/webview2/reference/javascript/webview) JavaScript method, widget providers can implement the [IWidgetProviderMessage](/windows/windows-app-sdk/api/winrt/microsoft.windows.widgets.providers.iwidgetprovidermessage) interface and implement the [OnMessageReceived](/windows/windows-app-sdk/api/winrt/microsoft.windows.widgets.providers.iwidgetprovidermessage.onmessagereceived) method.
70+
71+
```csharp
72+
internal class WidgetProvider : IWidgetProvider, IWidgetProviderMessage
73+
...
74+
public void OnMessageReceived(WidgetMessageReceivedArgs args)
75+
{
76+
Console.WriteLine($"Message received from widget {args.WidgetContext.Id}: {args.Message}");
77+
}
78+
```
79+
80+
Widget providers can send a message to the web content of the widget by calling [WidgetManager.SendMessage](/windows/windows-app-sdk/api/winrt/microsoft.windows.widgets.providers.widgetmanager.sendmessage). You must provide the ID of the widget to which the message is sent, which is the value specified in the *Id* attribute of the **Definition** element in the provider's package manifest file. For more information see [Widget provider package manifest XML format](/windows/apps/develop/widgets/widget-provider-manifest). The message string can be simple text or the serialized form of an object interpreted by the web content. For more information, see [PostWebMessageAsString](/dotnet/api/microsoft.web.webview2.core.corewebview2.postwebmessageasstring).
81+
82+
```csharp
83+
var message = $"{{ \"current_location\": \"{ location }\" }}";
84+
WidgetManager.GetDefault().SendMessageToContent("Weather_Widget", message);
85+
```
86+
87+
## Limitations and requirements
88+
89+
* This feature is available only to users in the European Economic Area (EEA). In the EEA, installed apps that implement a feed provider can provide content feed in the Widgets Board.
90+
91+
92+
93+
94+
95+
96+
97+
98+
99+
100+
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
---
2+
title: Customize the widget header area
3+
description: Learn how to customize the header area of a Windows widget.
4+
ms.topic: article
5+
ms.date: 11/12/2024
6+
ms.localizationpriority: medium
7+
---
8+
9+
# Customize the widget header area
10+
11+
In the latest release, apps that implement Windows widgets can customize the header that is displayed for their widget in the Widgets Board, overriding the default presentation. Header customization is implemented in the Adaptive Card payload you pass to the OS from your widget provider, so the steps are the same regardless of the language your widget provider is implemented in. For a walkthrough of creating a widget provider, see [Implement a widget provider in a C# Windows App](implement-widget-provider-cs.md) or [Implement a widget provider in a win32 app (C++/WinRT)](implement-widget-provider-win32.md).
12+
13+
## The default header
14+
15+
By default, the widget header shows the display name and the icon specified in the app manifest file. The display name is specified with the **DisplayName** attribute of the **Definition** element and the icon is specified with an **Icon** element under **ThemeResources**. For more information about the widget app manifest file format, see [Widget provider package manifest XML format](widget-provider-manifest.md).
16+
17+
The following example shows a portion of the Adaptive Card JSON payload for a widget that uses the default presentation. In the sections below, examples will be provided that modify this template to override the default header.
18+
19+
```json
20+
{
21+
"type": "AdaptiveCard",
22+
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
23+
"version": "1.6",
24+
"body": [
25+
...
26+
]
27+
}
28+
```
29+
30+
## Override the display name string
31+
32+
You can override the value specified in the **DisplayName** element in the app manifest by adding a `header` field to with the new display name in the JSON payload before sending it to the widget host.
33+
34+
The following example demonstrates overriding the display name string.
35+
36+
```json
37+
{
38+
"type": "AdaptiveCard",
39+
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
40+
"version": "1.6",
41+
"body": [
42+
...
43+
] ,
44+
"header": "Redmond Weather"
45+
}
46+
```
47+
48+
## Override the display name string and icon
49+
50+
To override both the display name string and the icon specified in the app manifest, add a `header` object with fields for `text` and `iconUrl`.
51+
52+
The following example demonstrates overriding the display name string and icon.
53+
54+
```json
55+
{
56+
"type": "AdaptiveCard",
57+
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
58+
"version": "1.6",
59+
"body": [
60+
...
61+
] ,
62+
"header": {
63+
"text": "Redmond weather",
64+
"iconUrl": "https://contoso.com/weatherimage.png"
65+
}
66+
}
67+
```
68+
69+
## Set the header to be empty
70+
71+
Some widget providers may want to allow their full UX to expand into the header region of the widget, even though this area of the widget isn't actionable. For this scenario, you can set the header to be empty by setting the `header` feel to `null`. Note that the UX in the header is not clickable by the user.
72+
73+
The following example demonstrates setting an empty header.
74+
75+
```json
76+
{
77+
"type": "AdaptiveCard",
78+
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
79+
"version": "1.6",
80+
"body": [
81+
...
82+
] ,
83+
"header": null
84+
}
85+
```
86+

hub/apps/develop/widgets/widget-provider-manifest.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ Represents the registration for a single widget.
125125
| **AdditionalInfoUri** | string | No | A URI that can be associated with the widget to be used when the user clicks on the title bar of the widget frame or when clicking the **Powered by** element of its context menu.| N/A |
126126
| **ExcludedRegions** | string | No | A list of regions where the widget should not be available. Widgets can specify **ExcludedRegions** or **ExclusiveRegions** but must not specify both in a single widget definition. The value of the attribute is a comma separated list of two character region codes.| N/A |
127127
| **ExclusiveRegions** | string | No | A list of the only regions where the widget should be available. Widgets can specify **ExcludedRegions** or **ExclusiveRegions** but must not specify both in single widget definition. The value of the attribute is a comma separated list of two character region codes.| N/A |
128+
| **WebRequestFilter** | string | No | Specifies the filter that specifies the resource request URLs for which the request will be intercepted and redirected to the widget provider's implementation of [IWidgetResourceProvider.OnResourceRequested](/windows/windows-app-sdk/api/winrt/microsoft.windows.widgets.providers.iwidgetresourceprovider.onresourcerequested). The filter pattern is expressed using the format described in [Match Patterns](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Match_patterns). The filter string in the registration must use [Punycode](https://en.wikipedia.org/wiki/Punycode) where necessary. The filter string must match the origin of the widget registration, which is specified in the *webUrl* field of the adaptive card content. | N/A |
128129

129130
## Capabilities
130131

0 commit comments

Comments
 (0)