Skip to content
Development
Skill

/platform-widget-generate

Use this skill to author a complete HXL WidgetBundle (UEM body + schema.json + -meta.xml). TRIGGER when: user asks for a widget, mosaic, fragment, card, or rich UI surface for any subject, domain, feature, or entity noun; the prompt names only an entity or data shape without

From plugin
sf-skills
803161 skills6 agents10 commands3 MCP
Install
$ npx -y skills add forcedotcom/sf-skills --skill platform-widget-generate --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/platform-widget-generate

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use this skill to author a complete HXL WidgetBundle (UEM body + schema.json + -meta.xml). TRIGGER when: user asks for a widget, mosaic, fragment, card, or rich UI surface for any subject, domain, feature, or entity noun; the prompt names only an entity or data shape without

SKILL.md

platform-widget-generate.SKILL.md
name: platform-widget-generate
description: "Use this skill to author a complete HXL WidgetBundle (UEM body + schema.json + -meta.xml). TRIGGER when: user asks for a widget, mosaic, fragment, card, or rich UI surface for any subject, domain, feature, or entity noun; the prompt names only an entity or data shape without invoking Lightning Types, CLTs, or Apex-backed types. DO NOT TRIGGER when: the prompt explicitly says 'Lightning Type', 'CLT', 'Custom Lightning Type', 'Apex-backed type', or references '@apexClassType/...' (use platform-lightning-type-widget-coordinate); authoring a custom-LWC renderer for a Custom Lightning Type (use platform-custom-lightning-type-generate); or editing only an LWC component."
metadata:
  version: "1.1"
  minApiVersion: "68.0"
  relatedSkills:
    - "platform-apex-generate"
    - "platform-custom-lightning-type-generate"
    - "platform-lightning-type-widget-coordinate"
  mcpTools:
    metadata-experts:
      tools: ["execute_metadata_action"]
      semver: ">=1.0.0"

Generating a Widget Bundle

Author a complete WidgetBundle: a UEM tree (`tile/widget`), a JSON Schema describing the widget's input contract, and the `.uiwidget-meta.xml` that registers the bundle.

When to Use This Skill

Use when the user asks for a widget, mosaic, fragment, or card-style rich UI surface. Do not use this skill for custom-LWC renderers or for `renderer.json` files inside a Custom Lightning Type bundle — those belong to `platform-custom-lightning-type-generate`.

Inputs

  • **`widgetName`** (required) — `camelCase` identifier; becomes the directory name under `uiWidgets/`.
  • A **shape** — what data the widget renders. The widget cannot be generated without it. The shape arrives one of two ways, in priority order:

1. **`lightningTypeSchema`** — `{ path, apexClassFqn }` for an existing Apex-backed Lightning Type. The FQN takes one of two forms: outer-class (`<namespace>__<ClassName>`) where the outer class is the payload, or inner-class (`<namespace>__<ClassName>$<InnerClass>`) where the named inner class is the payload. Passed in by the `platform-lightning-type-widget-coordinate` orchestrator. When present, derive per `references/schema-from-lightning-type.md`. 2. **Extracted from the user's prompt** — when no `lightningTypeSchema` is passed, infer the shape directly from what the user wrote: a pasted JSON payload, an enumerated field list ("id as string, total as number"), or descriptive prose. The output is the same ordered list of `{ name, type, required }` either way.

If neither source yields a shape, STOP and ask the user before proceeding.

Output

Three files in `<pkgDir>/uiWidgets/<widgetName>/`:

| File | Content | |---|---| | `<widgetName>.json` | Widget envelope — `{ "type": "lightning__agentforceWidget", "contentBody": { "widgetBody": { UEM tree rooted at tile/widget } } }` | | `schema.json` | JSON Schema — root has `type: "object"` + `properties.attributes` wrapper carrying `lightning:type: "lightning__objectType"` and the field `properties` | | `<widgetName>.uiwidget-meta.xml` | `<UiWidgetBundle>` element with `<masterLabel>`, `<description>`, and `<widgetType>JSON</widgetType>` |

See `references/widget-bundle-layout.md` for the `<pkgDir>` resolution procedure and the exact `<widgetName>.uiwidget-meta.xml` shape.

---

Composition

A widget body is a UEM tree of blocks nested under `contentBody.widgetBody`. The root node is `tile/widget`. Every node — root and non-root — has the same shape: no `type` key; just `definition`, optional `attributes`, optional `meta`, and optional `children`. Block shape:

interface Block {
  definition: string  // {namespace}/{blockName} — root is "tile/widget"
  attributes?: Record<string, any>
  meta?: { // see references/widget-meta-directives.md
    forEach?: string
    forItem?: string
    if?: string
  }
  children?: Block[]
}

The first child of `tile/widget.children` SHOULD be a single `tile/column` (or a single `tile/card`). All widget content typically goes inside that first child for predictable vertical structure across surfaces.

---

Available Metadata Actions

discoverUiComponents

**Purpose:** Discover the palette of blocks available for composition.

**Required parameters:** `actionName: "discoverUiComponents"`, `metadataType: "FRAGMENT"`, `parameters.pageType: "FRAGMENT"`. Optional: `searchQuery` to filter by name/description.

**Returns:** list of `{ definition, description, label, attributes? }`.

getUiComponentSchemas

**Purpose:** Fetch JSON schemas (property types, required vs optional, validation) for selected blocks.

**Required parameters:** `actionName: "getUiComponentSchemas"`, `metadataType: "FRAGMENT"`, `parameters.pageType: "FRAGMENT"`, `parameters.componentDefinitions: ["namespace/definition", ...]`. Optional: `includeKnowledge` (default `true`).

**Returns:** `componentSchemas[]` — success entries carry the JSON schema, failure entries carry an error message. Partial failures are supported.

> Never pass `tile/widget` to `getUiComponentSchemas` — it is a fixed wrapper, not a queryable component.

---

Attribute Binding

  • Bind a block property to runtime data with `{!$attrs.<attrName>}`. `<attrName>` MUST match a property name in `schema.json`.
  • Inside a `forEach`, reference the loop variable instead — e.g. `"text": "{!$item.name}"`. See `references/widget-meta-directives.md`.

---

Layout Best Practices

These conventions cover widget *structure* — how blocks are grouped and stacked.

| Primitive | Purpose | When to use | |---|---|---| | `tile/column` | Vertical stack of children | Root wrapper, and any group of blocks that should stack | | `tile/row` | Horizontal stack of children | Two or more blocks that belong on the same line | | `tile/card` | Visually-boxed group | A bounded section that should read as one unit | | `tile/spacer` | Whitespace between blocks | When extra space is needed between content groups |

  • **Sectioning:** Separate ma
Read more
Ships withsf-skills

This repository provides a curated collection of Salesforce agent skills for building applications.

Get the whole plugin

Other skills on sf-skills.