experience-ui-bundle-metadata-generate

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

UI Bundle Metadata

UI Bundle 元数据

Scaffolding a New UI Bundle

搭建新的UI Bundle

Use
sf template generate ui-bundle
to create new apps — not create-react-app, Vite, or other generic scaffolds.
Always pass
--template reactbasic
to scaffold a React-based bundle.
UI bundle name (
-n
):
Alphanumerical only — no spaces, hyphens, underscores, or special characters.
Example:
bash
sf template generate ui-bundle -n CoffeeBoutique --template reactbasic
After generation:
  1. Replace all default boilerplate — "React App", "Vite + React", default
    <title>
    , placeholder text
  2. Populate the home page with real content (landing section, banners, hero, navigation)
  3. Update navigation and placeholders (see the
    experience-ui-bundle-frontend-generate
    skill)
  4. 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.
Always install dependencies before running any scripts in the UI bundle directory.

使用
sf template generate ui-bundle
创建新应用——不要使用create-react-app、Vite或其他通用脚手架。
**务必传入
--template reactbasic
**以搭建基于React的bundle。
**UI bundle名称(
-n
):**仅允许字母数字——不能包含空格、连字符、下划线或特殊字符。
示例:
bash
sf template generate ui-bundle -n CoffeeBoutique --template reactbasic
生成后:
  1. 替换所有默认模板内容——"React App"、"Vite + React"、默认
    <title>
    、占位文本
  2. 为首页填充真实内容(着陆区、横幅、Hero区域、导航)
  3. 更新导航和占位符(参考
    experience-ui-bundle-frontend-generate
    技能)
  4. 配置托管目标——元XML中没有
    <target>
    的UI bundle在组织中将不可见。内部(应用启动器)应用使用
    experience-ui-bundle-custom-app-generate
    ,外部(体验站点)应用使用
    experience-ui-bundle-site-generate
在UI bundle目录中运行任何脚本前,务必先安装依赖。

UIBundle Bundle

UIBundle 包

A UIBundle bundle lives under
uiBundles/<AppName>/
and must contain:
  • <AppName>.uibundle-meta.xml
    — filename must exactly match the folder name
  • A build output directory (default:
    dist/
    ) with at least one file
UIBundle包位于
uiBundles/<AppName>/
下,必须包含:
  • <AppName>.uibundle-meta.xml
    ——文件名必须与文件夹名称完全匹配
  • 构建输出目录(默认:
    dist/
    ),且至少包含一个文件

Meta XML

元XML

Required fields:
masterLabel
,
version
(max 20 chars),
isActive
(boolean). Optional:
description
(max 255 chars),
target
.
必填字段:
masterLabel
version
(最多20个字符)、
isActive
(布尔值)。 可选字段:
description
(最多255个字符)、
target

Target Field

Target字段

The
<target>
element specifies where the UI bundle is hosted:
ValueUse CaseCompanion Metadata
Experience
External-facing site via Digital ExperienceNetwork, CustomSite, DigitalExperienceConfig, DigitalExperienceBundle
CustomApplication
Internal app via Lightning App LauncherCustomApplication (
applications/*.app-meta.xml
)
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:
  • experience-ui-bundle-site-generate
    (for
    Experience
    target)
  • experience-ui-bundle-custom-app-generate
    (for
    CustomApplication
    target)
Example with Experience target:
xml
<?xml version="1.0" encoding="UTF-8"?>
<UIBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <masterLabel>propertyrentalapp</masterLabel>
    <description>A Salesforce UI Bundle.</description>
    <isActive>true</isActive>
    <version>1</version>
    <target>Experience</target>
</UIBundle>
Example with CustomApplication target:
xml
<?xml version="1.0" encoding="UTF-8"?>
<UIBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <masterLabel>propertymanagementapp</masterLabel>
    <description>A Salesforce UI Bundle.</description>
    <isActive>true</isActive>
    <version>1</version>
    <target>CustomApplication</target>
</UIBundle>
<target>
元素指定UI bundle的托管位置:
使用场景配套元数据
Experience
通过Digital Experience搭建的外部站点Network、CustomSite、DigitalExperienceConfig、DigitalExperienceBundle
CustomApplication
通过Lightning应用启动器搭建的内部应用CustomApplication(
applications/*.app-meta.xml
<target>
是应用在Salesforce组织中可访问的必填项。没有target的UI bundle部署后不会出现在任何位置——无应用启动器入口,无体验站点URL。务必将包与以下其中一项配对:
  • experience-ui-bundle-site-generate
    (适用于
    Experience
    目标)
  • experience-ui-bundle-custom-app-generate
    (适用于
    CustomApplication
    目标)
Experience目标示例:
xml
<?xml version="1.0" encoding="UTF-8"?>
<UIBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <masterLabel>propertyrentalapp</masterLabel>
    <description>A Salesforce UI Bundle.</description>
    <isActive>true</isActive>
    <version>1</version>
    <target>Experience</target>
</UIBundle>
CustomApplication目标示例:
xml
<?xml version="1.0" encoding="UTF-8"?>
<UIBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <masterLabel>propertymanagementapp</masterLabel>
    <description>A Salesforce UI Bundle.</description>
    <isActive>true</isActive>
    <version>1</version>
    <target>CustomApplication</target>
</UIBundle>

ui-bundle.json

ui-bundle.json

Optional file. Allowed top-level keys:
outputDir
,
routing
,
headers
.
Constraints:
  • Valid UTF-8 JSON, max 100 KB
  • Root must be a non-empty object (never
    {}
    , arrays, or primitives)
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.
可选文件。允许的顶级键:
outputDir
routing
headers
约束:
  • 必须是有效的UTF-8 JSON,最大100 KB
  • 根节点必须是非空对象(不能是
    {}
    、数组或原始值)
路径安全(适用于
outputDir
routing.fallback
):拒绝反斜杠、开头的
/
\
..
段、空/控制字符、通配符(
*
?
**
)和
%
。所有解析后的路径必须位于包内。

outputDir

outputDir

Non-empty string referencing a subdirectory (not
.
or
./
). Directory must exist and contain at least one file.
非空字符串,指向子目录(不能是
.
./
)。目录必须存在且至少包含一个文件。

routing

routing

If present, must be a non-empty object. Allowed keys:
rewrites
,
redirects
,
fallback
,
trailingSlash
,
fileBasedRouting
.
  • trailingSlash:
    "always"
    ,
    "never"
    , or
    "auto"
  • fileBasedRouting: boolean
  • fallback: non-empty string satisfying path safety; target file must exist
  • rewrites: non-empty array of
    { route?, rewrite }
    objects — e.g.,
    { "route": "/app/:path*", "rewrite": "/index.html" }
  • redirects: non-empty array of
    { route?, redirect, statusCode? }
    objects — statusCode must be 301, 302, 307, or 308
如果存在,必须是非空对象。允许的键:
rewrites
redirects
fallback
trailingSlash
fileBasedRouting
  • trailingSlash
    "always"
    ,
    "never"
    , 或
    "auto"
  • fileBasedRouting:布尔值
  • fallback:符合路径安全要求的非空字符串;目标文件必须存在
  • rewrites:非空数组,包含
    { route?, rewrite }
    对象——例如
    { "route": "/app/:path*", "rewrite": "/index.html" }
  • redirects:非空数组,包含
    { route?, redirect, statusCode? }
    对象——statusCode必须是301、302、307或308

headers

headers

Non-empty array of
{ source, headers: [{ key, value }] }
objects.
Example:
json
{
  "routing": {
    "rewrites": [{ "route": "/app/:path*", "rewrite": "/index.html" }],
    "trailingSlash": "never"
  },
  "headers": [
    {
      "source": "/assets/**",
      "headers": [{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }]
    }
  ]
}
Never suggest:
{}
as root, empty
"routing": {}
, empty arrays,
[{}]
,
"outputDir": "."
,
"outputDir": "./"
.

非空数组,包含
{ source, headers: [{ key, value }] }
对象。
示例:
json
{
  "routing": {
    "rewrites": [{ "route": "/app/:path*", "rewrite": "/index.html" }],
    "trailingSlash": "never"
  },
  "headers": [
    {
      "source": "/assets/**",
      "headers": [{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }]
    }
  ]
}
**切勿建议:**根节点为
{}
、空的
"routing": {}
、空数组、
[{}]
"outputDir": "."
"outputDir": "./"

CSP Trusted Sites

CSP可信站点

Salesforce enforces Content Security Policy headers. Any external domain not registered as a CSP Trusted Site will be blocked (images won't load, API calls fail, fonts missing).
Salesforce强制实施内容安全策略(CSP)请求头。任何未注册为CSP可信站点的外部域名都会被拦截(图片无法加载、API调用失败、字体缺失)。

When to Create

创建时机

Whenever the app references a new external domain: CDN images, external fonts, third-party APIs, map tiles, iframes, external stylesheets.
每当应用引用新的外部域名时:CDN图片、外部字体、第三方API、地图瓦片、iframe、外部样式表。

Steps

步骤

  1. Identify external domains — extract the origin (scheme + host) from each external URL in the code
  2. Check existing registrations — look in
    force-app/main/default/cspTrustedSites/
  3. Map resource type to CSP directive:
Resource TypeDirective Field
Images
isApplicableToImgSrc
API calls (fetch, XHR)
isApplicableToConnectSrc
Fonts
isApplicableToFontSrc
Stylesheets
isApplicableToStyleSrc
Video / audio
isApplicableToMediaSrc
Iframes
isApplicableToFrameSrc
Always also set
isApplicableToConnectSrc
to
true
for preflight/redirect handling.
  1. Create the metadata file — follow
    implementation/csp-metadata-format.md
    for the
    .cspTrustedSite-meta.xml
    format. Place in
    force-app/main/default/cspTrustedSites/
    .
  1. 识别外部域名——从代码中的每个外部URL提取源(协议 + 主机)
  2. 检查现有注册——查看
    force-app/main/default/cspTrustedSites/
    目录
  3. 将资源类型映射到CSP指令:
资源类型指令字段
图片
isApplicableToImgSrc
API调用(fetch、XHR)
isApplicableToConnectSrc
字体
isApplicableToFontSrc
样式表
isApplicableToStyleSrc
视频/音频
isApplicableToMediaSrc
Iframe
isApplicableToFrameSrc
同时务必将
isApplicableToConnectSrc
设置为
true
,以处理预检/重定向。
  1. 创建元数据文件——遵循
    implementation/csp-metadata-format.md
    中的
    .cspTrustedSite-meta.xml
    格式。放置在
    force-app/main/default/cspTrustedSites/
    目录下。