canvas-app-yaml · v1.0.0 · 2026-05-30 · sha256 eb0b5e65bb9170ff
canvas-app-yaml v1.0.0A
Immutable. This exact content is served forever at /api/v1/blob/eb0b5e65bb9170ff.
---
name: "canvas-app-yaml"
description: 'Author Microsoft Power Apps canvas app source as unpacked *.fx.yaml + CanvasManifest.json so an agent can generate Power Fx screens that pac canvas pack and pac solution pack will accept. Covers the Src/ YAML control tree, Power Fx formula syntax, App OnStart, screens, data sources, components, and the round-trip with pac canvas unpack/pack.'
metadata:
author: "AgentX"
version: "1.0.0"
created: "2026-05-30"
compatibility:
surfaces: ["low-code-builder", "agent-x", "engineer"]
platforms: ["power-platform", "power-apps", "canvas-apps", "power-fx"]
---
# Power Apps Canvas App YAML
> Purpose: emit canvas app source that round-trips through `pac canvas unpack` / `pac canvas pack` and packs into a solution under `CanvasApps/`.
## When to Use
- Generating a canvas app (forms, galleries, screens over Dataverse or other data) from a PRD-LOWCODE
- Editing screen logic or controls in an existing unpacked app
- Reviewing Power Fx before packaging
## On-Disk Layout (after `pac canvas unpack`)
```
CanvasApps/
<prefix>_<appname>_<DocumentUri>/
CanvasManifest.json # app metadata, dependencies, data sources, app-level Power Fx
Src/
App.fx.yaml # App.OnStart, App.Formulas, named formulas
<ScreenName>.fx.yaml # one file per screen, control tree + Power Fx
Component/ # reusable canvas components
Assets/ # images, media
Connections/ # data source connection metadata
DataSources/ # *.json per data source (table, connector)
```
`pac canvas pack --sources ./Src --msapp build/app.msapp` rebuilds the `.msapp`, which `pac solution pack` then embeds.
## The Src YAML Control Tree
Each screen is a YAML tree. Indentation defines nesting. Each control has `Control:` and a properties block. Power Fx expressions are prefixed with `=`.
```yaml
Screens:
HomeScreen:
Properties:
Fill: =RGBA(248, 249, 250, 1)
Children:
- TitleLabel:
Control: Label@2.5.1
Properties:
Text: ="Issues"
Size: =24
FontWeight: =FontWeight.Semibold
- IssueGallery:
Control: Gallery@2.15.0
Variant: galleryVertical
Properties:
Items: =SortByColumns(Filter(Issues, Status.Value = "Open"), "agx_duedate")
OnSelect: =Set(varSelected, ThisItem)
Children:
- TitleRow:
Control: Label@2.5.1
Properties:
Text: =ThisItem.agx_name
```
Rules:
- `Control: <Name>@<version>` -- the version must match a control the target environment ships. Use current GA versions; do not invent.
- Property values are Power Fx, always `=`-prefixed.
- `Children:` is an ordered list; z-order follows list order.
## Power Fx Essentials
| Need | Pattern |
|------|---------|
| App state | `Set(varName, value)` (global), `UpdateContext({x: 1})` (screen-scoped) |
| Named formula (preferred over OnStart) | In `App.Formulas`: `varTheme = RGBA(...);` |
| Filter a table | `Filter(Issues, Status.Value = "Open")` |
| Sort | `SortByColumns(source, "col", SortOrder.Ascending)` |
| Lookup single row | `LookUp(Issues, agx_issueid = varId)` |
| Patch (create/update) | `Patch(Issues, Defaults(Issues), {agx_name: txtTitle.Text})` |
| Navigate | `Navigate(DetailScreen, ScreenTransition.Cover)` |
| Choice column value | `ThisItem.Status.Value` (display), bind via the choice record |
Prefer **named formulas** (`App.Formulas`) and **delegable** queries (Filter/Sort on Dataverse columns) over `OnStart` + `ClearCollect` of whole tables, which breaks past 2000 rows.
## CanvasManifest.json (key fields)
```json
{
"FormatVersion": "0.24",
"Properties": { "Id": "<guid>", "Name": "<prefix>_<appname>" },
"PublishInfo": { "AppName": "Issue Tracker" },
"AppPreviewFlagsMap": { "delegationforalltabularsources": true },
"DataSources": [ { "Name": "Issues", "Type": "NativeCDSDataSourceInfo" } ]
}
```
## Solution Integration
- The app folder name embeds a `DocumentUri` GUID -- keep it stable across regenerations.
- Add a `RootComponent type="300"` (Canvas App) entry to `Solution.xml`.
- Data sources that point at Dataverse tables create implicit dependencies; ensure those tables are in the same solution or referenced.
## Anti-Patterns
- Inventing `Control@version` numbers -- packing fails or the control renders blank.
- `ClearCollect(coll, Filter(BigTable, ...))` of large tables in `OnStart` -- delegation warning + truncation at 2000 rows.
- Hardcoding environment-specific GUIDs in formulas -- use connection references and environment variables.
- Editing the `.msapp` binary directly -- always edit `Src/*.fx.yaml` and re-pack.
## Verify
```bash
pac canvas pack --sources ./Src --msapp build/app.msapp # must succeed
```
## Related
- [solution-anatomy](../solution-anatomy/SKILL.md) -- where CanvasApps/ sits in the tree
- [dataverse-schema](../dataverse-schema/SKILL.md) -- the tables a canvas app binds to
- [pac-cli](../pac-cli/SKILL.md) -- pac canvas unpack/pack