Skip to content
Development
Skill

/experience-cms-content-render

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

From plugin
sf-skills
1.1k200 skills6 agents15 commands4 MCP

Claude Code

$ npx -y skills add forcedotcom/sf-skills --skill experience-cms-content-render --agent claude-code

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, registers a typed reference, generates a framework-matched renderer from the live schema, and wires the render path (delivery API, contentKey, RichText, image resolution). Prefer over general UI-bundle skills like experience-ui-bundle-frontend-generate (page/layout shell only) for the CMS-rendering part, even under src/. Triggers on prompts like 'render the CMS article on the home page', 'embed this CMS blog post here', 'show the CMS video in the hero', 'display the CMS image in the banner', or 'add this CMS content block to the detail page'; for mixed prompts, activate for the CMS part only. Do not trigger for searching a CMS item or 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 the shared runtime once (prompt the user first). This npm install is the ONLY way the toolkit is added; every import uses the `@salesfo

Read more
@forcedotcom
Ships withsf-skills

This repository provides Salesforce agent skills, plugins, and sample apps for building applications.

1.1k200 skills6 agents4 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
1.1k
Star history of forcedotcom/sf-skills on GitHub, a chart by star-history.com

Other skills on sf-skills.

agentforce-observe

agentforce-observe

Analyze production Agentforce agent behavior using session traces and Data Cloud, and manage Agent Health Monitoring (AHM)…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills2w309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react5d252k
@facebook@facebookInstall Skill

Questions about experience-cms-content-render.

Which coding agents can use experience-cms-content-render?
experience-cms-content-render installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.