$npx -y skills add forcedotcom/sf-skills --skill experience-ui-bundle-metadata-generateUse this skill when adding a front-end React UI bundle to an existing project or configuring UI bundle metadata and config files. TRIGGER when: adding or scaffolding a new UI bundle inside a project that already exists; running sf template generate ui-bundle; editing ui-bundle.js
| 1 | # UI Bundle Metadata |
| 2 | |
| 3 | ## Scaffolding a New UI Bundle |
| 4 | |
| 5 | Use `sf template generate ui-bundle` to create new apps — not create-react-app, Vite, or other generic scaffolds. |
| 6 | |
| 7 | - **Always pass `--template reactbasic`** to scaffold a React-based bundle. |
| 8 | - **UI bundle name (`-n`):** Alphanumerical only — no spaces, hyphens, underscores, or special characters. |
| 9 | - Pass `--output-dir` to use a different location for template generation. |
| 10 | |
| 11 | **Example:** |
| 12 | ```bash |
| 13 | sf template generate ui-bundle -n CoffeeBoutique --template reactbasic |
| 14 | ``` |
| 15 | |
| 16 | After generation: |
| 17 | 1. **Verify API version** — run `bash <skill_dir>/scripts/check-api-version.sh` from the project root to ensure `sourceApiVersion` in `sfdx-project.json` is 67.0 or higher. The script will automatically update it if needed. |
| 18 | 2. Replace all default boilerplate — "React App", "Vite + React", default `<title>`, placeholder text |
| 19 | 3. Populate the home page with real content (landing section, banners, hero, navigation) |
| 20 | 4. Update navigation and placeholders (see the `experience-ui-bundle-frontend-generate` skill) |
| 21 | 5. **Configure a hosting target** — a UI bundle without a `<target>` in its meta XML will not be visible in the org. Use `experience-ui-bundle-custom-app-generate` for internal (App Launcher) apps or `experience-ui-bundle-site-generate` for external (Experience Site) apps. |
| 22 | |
| 23 | Always install dependencies before running any scripts in the UI bundle directory. |
| 24 | |
| 25 | --- |
| 26 | |
| 27 | ## UIBundle Bundle |
| 28 | |
| 29 | A UIBundle bundle lives under `uiBundles/<AppName>/` and must contain: |
| 30 | |
| 31 | - `<AppName>.uibundle-meta.xml` — filename must exactly match the folder name |
| 32 | - A build output directory (default: `dist/`) with at least one file |
| 33 | |
| 34 | ### Meta XML |
| 35 | |
| 36 | Required fields: `masterLabel`, `version` (max 20 chars), `isActive` (boolean). |
| 37 | Optional: `description` (max 255 chars), `target`. |
| 38 | |
| 39 | #### Target Field |
| 40 | |
| 41 | The `<target>` element specifies where the UI bundle is hosted: |
| 42 | |
| 43 | | Value | Use Case | Companion Metadata | |
| 44 | |-------|----------|-------------------| |
| 45 | | `Experience` | External-facing site via Digital Experience | Network, CustomSite, DigitalExperienceConfig, DigitalExperienceBundle | |
| 46 | | `CustomApplication` | Internal app via Lightning App Launcher | CustomApplication (`applications/*.app-meta.xml`) | |
| 47 | |
| 48 | A `<target>` is **required** for the app to be accessible in a Salesforce org. A UI bundle deployed without a target will not appear anywhere — no App Launcher entry, no Experience Site URL. Always pair the bundle with one of: |
| 49 | - `experience-ui-bundle-site-generate` (for `Experience` target) |
| 50 | - `experience-ui-bundle-custom-app-generate` (for `CustomApplication` target) |
| 51 | |
| 52 | **Example with Experience target:** |
| 53 | ```xml |
| 54 | <?xml version="1.0" encoding="UTF-8"?> |
| 55 | <UIBundle xmlns="http://soap.sforce.com/2006/04/metadata"> |
| 56 | <masterLabel>propertyrentalapp</masterLabel> |
| 57 | <description>A Salesforce UI Bundle.</description> |
| 58 | <isActive>true</isActive> |
| 59 | <version>1</version> |
| 60 | <target>Experience</target> |
| 61 | </UIBundle> |
| 62 | ``` |
| 63 | |
| 64 | **Example with CustomApplication target:** |
| 65 | ```xml |
| 66 | <?xml version="1.0" encoding="UTF-8"?> |
| 67 | <UIBundle xmlns="http://soap.sforce.com/2006/04/metadata"> |
| 68 | <masterLabel>propertymanagementapp</masterLabel> |
| 69 | <description>A Salesforce UI Bundle.</description> |
| 70 | <isActive>true</isActive> |
| 71 | <version>1</version> |
| 72 | <target>CustomApplication</target> |
| 73 | </UIBundle> |
| 74 | ``` |
| 75 | |
| 76 | ### ui-bundle.json |
| 77 | |
| 78 | Optional file. Allowed top-level keys: `outputDir`, `routing`, `headers`. |
| 79 | |
| 80 | **Constraints:** |
| 81 | - Valid UTF-8 JSON, max 100 KB |
| 82 | - Root must be a non-empty object (never `{}`, arrays, or primitives) |
| 83 | |
| 84 | **Path safety** (applies to `outputDir` and `routing.fallback`): Reject backslashes, leading `/` or `\`, `..` segments, null/control characters, globs (`*`, `?`, `**`), and `%`. All resolved paths must stay within the bundle. |
| 85 | |
| 86 | #### outputDir |
| 87 | Non-empty string referencing a subdirectory (not `.` or `./`). Directory must exist and contain at least one file |