Skip to content
AI & Agents
Skill

/experience-cms-content-render

Renders, embeds, or displays existing Salesforce CMS content in a React or Angular uiBundle app: installs the CMS toolkit package, registers a typed reference, generates a framework-matched renderer from the live schema, and wires the render path (delivery API, contentKey,

From plugin
forcedotcom-sf-skills
989200 skills2 agents14 commands3 MCP
Install
$ npx -y skills add forcedotcom/afv-library --skill experience-cms-content-render --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/experience-cms-content-render

Context preview

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

Renders, embeds, or displays existing Salesforce CMS content in a React or Angular uiBundle app: installs the CMS toolkit package, registers a typed reference, generates a framework-matched renderer from the live schema, and wires the render path (delivery API, contentKey,

SKILL.md

experience-cms-content-render.SKILL.md
name: experience-cms-content-render
description: "Renders, embeds, or displays existing Salesforce CMS content in a React or Angular uiBundle app: installs the CMS toolkit package, registers a typed reference, generates a framework-matched renderer from the live schema, and wires the render path (delivery API, contentKey, RichText, image resolution). Use it — and prefer it over general UI-bundle skills like experience-ui-bundle-frontend-generate, which own only the page/layout shell — for the CMS-rendering part of a prompt, even when editing files under src/. Triggers on 'render the CMS news article on the home page', 'embed the CMS blog post', 'display the featured product in the hero', 'show the blog post on a detail page', 'render the CMS video on the home page', 'show the CMS image in the hero'; if a prompt mixes page/layout work with CMS rendering, activate for the CMS part. Do not trigger when only searching for a CMS item, or when defining a new CMS content type/schema (use experience-cms-content-type-generate)."
metadata:
  version: "2.1"
  domains: ["Experience"]
  minApiVersion: "65.0"
  relatedSkills:
    - "experience-cms-content-generate"
    - "experience-cms-content-type-generate"
    - "experience-search-coordinate"
    - "experience-ui-bundle-frontend-generate"
  cliTools:
    - tool: ["npm"]
      semver: ">=7.0.0"
    - tool: ["npx"]
      semver: ">=7.0.0"
    - tool: ["sf"]
      semver: ">=2.0.0"

This skill directs *how* to render CMS content into a uiBundle app; it does NOT re-implement the delivery transport. The npm package **`@salesforce/ui-bundle-template-feature-cms-toolkit`** owns HTTP, envelope-unwrap, catalog key-remap, channel resolution, image-URL resolution, entity decoding and other utilities. The skill installs that package, then generates the thin framework-specific layer around it (typed refs, per-type renderers, fetch lifecycle, placement) for React and Angular uiBundle apps, inferring Init vs Embed from file state and never scaffolding Init inside an Embed prompt without telling the user.

API-only package — the skill writes the UI

The toolkit exports functions and types only: no components, no hooks. Import target and full signatures: `references/package-api.md`. The three reads (all take `<TBody>` + `options?`, all throw on failure):

  • `getCmsContentByUrl` — public CDN, unauthenticated; the pasted `unauthenticatedUrl` fetched AS-IS.
  • `getCmsContentByKey` — one item, authenticated Connect; the toolkit remaps source→target key and resolves the channel.
  • `getCmsContentByKeys` — many, ONE authenticated round-trip, best-effort per-key (`references/bulk-loading.md`).

Plus sync helpers `resolveCmsImageUrl`, `resolveMediaUrl`, `decodeRichHtmlEntities` and the typed error classes. Every read returns the already-UNWRAPPED `contentBody` with the envelope `title` lifted in; skill code only types `TBody` and never handles the envelope, `{ items: [...] }`, or a `.value` wrapper.

Bundled files (assets & references load with this skill)

This skill's `assets/` templates and `references/` docs load alongside SKILL.md; reference them by relative path (`assets/shared/…`, `assets/<framework>/…`, `references/…`) and treat their contents as available. Foundation runtime files are emitted VERBATIM; only `cmsContentType.ts` and the renderer templates carry `{{…}}` substitution. **Never reconstruct a template from memory** — the templates encode the StrictMode hook, the sanitizer seam, and the correct package call sites. Every detection below (framework, pasted-URL, Init/Embed/drift) READS the target app's files directly; there is no script to run.

Interaction model (ask with options)

This skill is **interactive**. At every decision the prompt leaves open (framework, Init, drift, content type, render target, candidate bundle) ASK with an **option-select** question of 2–4 labeled options, recommended first, and wait — never a bare free-text prompt. Use free-text only for open answers: a component/region name, a URL, a slug. Full wording, options, and headers: `references/interaction-model.md`; follow it for every ASK below. Two answers are **terminal** (end the session, scaffold nothing): declining Init, and a search that returns **zero content** (see *HALT behaviour*).

**Bypass mode (non-interactive / automation).** When the prompt explicitly asks to bypass the interaction model ("non-interactive", "don't ask", "proceed/yes to all", "auto-proceed"), ask NO option-select question: answer every would-be question with its **recommended option** and continue. This changes only the answer source, not pipeline logic, and does NOT override the terminal stops — a genuine zero-content result still stops, as does any true HALT with no safe default (unnamed in-place placement, unresolvable candidate bundle). Per-question recommended answers: `references/interaction-model.md` → *Bypass mode*.

Framework detection (do this FIRST)

Read `<appRoot>/package.json` (`<appRoot>` = the dir with `package.json`) and merge dependency names from `dependencies`, `devDependencies`, and `peerDependencies`; a framework may sit in any bucket:

  • **react** — `react` present, `@angular/core` absent → React templates.
  • **angular** — `@angular/core` present, `react` absent → Angular templates.
  • **ambiguous** — BOTH present → HALT, ask which framework to target with options (`references/interaction-model.md` → *Framework*): React / Angular.
  • **unknown** — neither present, or no readable `package.json` → HALT, not a supported React/Angular app; do not scaffold.

The framework selects the template family for every step below (`assets/react/*` vs `assets/angular/*`); `assets/shared/*` is framework-agnostic and used by both.

Modes

**Init (one-time scaffold).** On the first Embed, when the framework's foundation set (see *Init vs Embed detection*) is absent, run `npm i @salesforce/ui-bundle-template-feature-cms-toolkit@latest --min-release-age=0` in the app root and write

Read more
Ships withforcedotcom-sf-skills

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

Get the whole plugin

Other skills on forcedotcom-sf-skills.