PluginBench
Skill
Pass
Audit score 90

generating-ui-bundle-custom-app

forcedotcom/sf-skills

Create a Custom Application to host a React UI bundle in Lightning Experience and expose it via the App Launcher.

What is generating-ui-bundle-custom-app?

This skill generates a CustomApplication metadata record that surfaces a React UI bundle in the Lightning App Launcher for internal Salesforce users. Use it when you have a UI bundle in uiBundles/*/src/ and need to make it accessible as a launchable app without requiring a Digital Experience Site.

  • Resolves required properties (appName, appLabel, appNamespace) from project configuration and user input
  • Queries Salesforce API context to determine version-specific field availability (uiBundle vs. webApplication)
  • Creates CustomApplication metadata at applications/{appName}.app-meta.xml with correct bundle references
  • Updates UIBundle metadata with target field if supported by the org's API version
  • Generates version-aware XML using appropriate field names for the target Salesforce instance

How to install generating-ui-bundle-custom-app

npx skills add https://github.com/forcedotcom/sf-skills --skill generating-ui-bundle-custom-app
Prerequisites
  • A Salesforce project with uiBundles/{name}/src/ directory structure
  • sfdx-project.json configured with packageDirectories and namespace (if applicable)
  • Access to target Salesforce org to query API metadata context
Claude Code
Cursor
Windsurf
Cline

How to use generating-ui-bundle-custom-app

  1. 1.Resolve all required properties: appName (from UI bundle directory), appLabel (human-readable name), and appNamespace (from sfdx-project.json or org query)
  2. 2.Query the target org's API context using salesforce-api-context tools to check for CustomApplication.uiBundle and UIBundle.target field support
  3. 3.Create the applications/{appName}.app-meta.xml file in the correct source directory (from sfdx-project.json packageDirectories)
  4. 4.Populate the CustomApplication metadata using the template, substituting placeholders with resolved values and applying version-specific field names (uiBundle or webApplication)
  5. 5.If the target field is supported, update the .uibundle-meta.xml file to include <target>CustomApplication</target>
  6. 6.Validate the deployment with: sf project deploy validate --metadata CustomApplication UIBundle --target-org {usernameOrAlias}

Use cases

Good for
  • Expose an internal React UI bundle as a launchable app in the Lightning App Launcher
  • Create a Custom Application that delegates rendering to an existing UI bundle without using tabs or flexipages
  • Configure a thin launcher entry for a React app hosted within Salesforce Lightning Experience
  • Make a UI bundle accessible to internal users without setting up a Digital Experience Site
Who it's for
  • Salesforce developers building internal React applications
  • Teams deploying UI bundles to Lightning Experience
  • Developers who need app launcher integration without Experience Cloud

generating-ui-bundle-custom-app FAQ

When should I use this skill instead of generating-custom-application?

Use this skill when your project contains a UI bundle (uiBundles/*/src/) and you need to expose it via the Lightning App Launcher. Do NOT use generating-custom-application for UI bundle apps, as that skill is for apps using tabs, action overrides, or flexipages.

What's the difference between uiBundle and webApplication fields?

The uiBundle field (newer API versions) uses the format {appNamespace}__{appName}, while webApplication (older versions) uses just {appName} without namespace. Step 2 queries your org's API version to determine which field to use.

Do I need a Digital Experience Site or Network for this?

No. Custom Applications for UI bundles are a lightweight alternative that don't require Networks, CustomSite, DigitalExperienceConfig, or DigitalExperienceBundle metadata.

How do I determine my appNamespace?

Check the namespace property in sfdx-project.json first. If not set, query your org with: sf data query -q "SELECT NamespacePrefix FROM Organization" --target-org {usernameOrAlias}. If neither exists, use the default namespace 'c'.

What happens if the bundle reference is wrong?

The app launcher entry will exist but show a blank page. Ensure the appNamespace and appName match the UI bundle directory name and that you use the correct field name (uiBundle vs. webApplication) for your org's API version.

Full instructions (SKILL.md)

Source of truth, from forcedotcom/sf-skills.


name: generating-ui-bundle-custom-app description: "MUST activate when the project contains a uiBundles//src/ directory and the task involves creating or configuring a Custom Application for hosting a UI bundle in Lightning Experience. Use this skill when creating a CustomApplication metadata record to surface the UI bundle in the App Launcher. Activate when files matching applications/.app-meta.xml exist and need modification, or when the user wants to expose their app via the Lightning App Launcher without a Digital Experience Site. Do NOT use generating-custom-application for this — UI bundle apps do not use tabs, action overrides, or flexipages." metadata: version: "1.0"

Custom Application for React UI Bundles

Create and configure a Salesforce Custom Application that hosts a React UI bundle in Lightning Experience. This skill generates the CustomApplication metadata so the app appears in the Lightning App Launcher and can be accessed by internal users.

Custom Applications differ from Experience Sites: they don't need Networks, CustomSite, DigitalExperienceConfig, or DigitalExperienceBundle metadata. The Custom Application acts as a thin launcher entry that delegates rendering to the React UI bundle referenced by uiBundle.

Required Properties

Resolve all properties before generating any metadata. Each has a fallback chain — work through each option in order until a value is found.

PropertyFormatHow to Resolve
appNamelowercamelcase (e.g., myInternalApp)The UI bundle name from uiBundles/<name>/ directory
appNamespaceStringnamespace in sfdx-project.jsonsf data query -q "SELECT NamespacePrefix FROM Organization" --target-org ${usernameOrAlias} → default c
appLabelHuman-readable stringUser-provided, or derive from appName by converting camelCase to Title Case

The appNamespace and appName connect the Custom Application to the correct React UI bundle. In newer API versions this uses <uiBundle>{appNamespace}__{appName}</uiBundle>; in older versions it uses <webApplication>{appName}</webApplication>. Getting this wrong means the app launcher entry exists but shows a blank page. Step 2 of the workflow determines which field to use.

Generation Workflow

Step 1: Resolve All Required Properties

Determine values for all properties before constructing anything. Use the resolution strategies in the table above.

Step 2: Query API Context (Version-Aware Field Discovery)

Call salesforce-api-context MCP tools to discover which fields exist for the target org's API version. This ensures the generated metadata is compatible with the user's Salesforce version.

Required calls:

  1. Call get_metadata_type_fields for CustomApplication — check whether the uiBundle field exists
  2. Call get_metadata_type_fields for UIBundle — check whether the target field exists

Field resolution based on API response:

Field CheckIf presentIf absent (older API version)
CustomApplication.uiBundleUse <uiBundle>{appNamespace}__{appName}</uiBundle>Use <webApplication>{appName}</webApplication> (no namespace)
UIBundle.targetUse <target>CustomApplication</target>Omit the <target> element entirely

If salesforce-api-context is unavailable after a real attempt, fall back to the newer field names (uiBundle + target).

Step 3: Create the Project Structure

Create any files and directories that don't already exist:

Metadata TypePath
CustomApplication<sourceDir>/applications/{appName}.app-meta.xml

Note: <sourceDir> is determined from sfdx-project.json. Read packageDirectories[] and use the entry where "default": true; the full source directory is <path>/main/default. If no default is set, use the first entry. Commonly force-app/main/default, but this path is configurable.

Step 4: Populate All Metadata Fields

Use the default template in the doc below. Values in {braces} are resolved property references — substitute them with the actual values from Step 1. Apply the field resolution from Step 2 to determine which XML elements to use.

Metadata TypeTemplate Reference
CustomApplicationconfigure-metadata-custom-application.md

Execution Note for Step 4: Load and use the doc

  • Agents MUST read the full contents of the docs/*.md file referenced in Step 4 before attempting to populate metadata fields.
  • Read the file in full, replace placeholders (e.g. {appName}) with the resolved values, then use the expanded template to populate the metadata XML content.
  • If Step 2 determined the older field names apply, substitute <uiBundle> with <webApplication> in the generated output.

Step 5: Update UI Bundle Meta XML

If Step 2 confirmed the target field exists on UIBundle, add <target>CustomApplication</target> to the .uibundle-meta.xml file (skip if the field doesn't exist in the org's API version):

<?xml version="1.0" encoding="UTF-8"?>
<UIBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <masterLabel>{appName}</masterLabel>
    <description>A Salesforce UI Bundle.</description>
    <isActive>true</isActive>
    <version>1</version>
    <target>CustomApplication</target>
</UIBundle>

Step 6: Do Not Modify Non-Templated Properties

Do not modify any default property values for CustomApplication metadata that are not expressed as variables wrapped in {braces}.

Verification Checklist

Before deploying, confirm:

  • All required properties are resolved
  • API context was queried to determine available fields (Step 2)
  • applications/{appName}.app-meta.xml exists with correct content
  • The bundle reference field matches the org's API version (<uiBundle> or <webApplication>)
  • If target field is supported: .uibundle-meta.xml has <target>CustomApplication</target>
  • Deployment validates successfully:
sf project deploy validate --metadata CustomApplication UIBundle --target-org ${usernameOrAlias}