
Generating Experience Lwr Site
- 6 installs
- 787 repo stars
- Updated August 5, 2026
- forcedotcom/afv-library
Creates and configures Salesforce Experience Cloud LWR sites via DigitalExperience metadata including routes, views, theme layouts, branding, and guest sharing rules.
About
Builds and configures Experience Cloud Lightning Web Runtime sites through DigitalExperience metadata, covering pages, routes, theme layouts, branding, and guest sharing rules. A developer uses it when creating or modifying LWR community sites or portals in Salesforce.
- Works with DigitalExperienceBundle routes, theme layouts, and branding sets
- Handles guest sharing rules and guest user access for LWR sites
Generating Experience Lwr Site by the numbers
- 6 all-time installs (skills.sh)
- Ranked #1,782 of 2,245 Frontend Development skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/forcedotcom/afv-library --skill generating-experience-lwr-siteAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 6 |
|---|---|
| repo stars | ★ 787 |
| Last updated | August 5, 2026 |
| Repository | forcedotcom/afv-library ↗ |
What it does
Creates and configures Salesforce Experience Cloud LWR sites via DigitalExperience metadata including routes, views, theme layouts, branding, and guest sharing rules.
Files
Experience LWR Site Builder
Build and configure Salesforce Experience Cloud Lightning Web Runtime (LWR) sites via metadata (DigitalExperienceConfig, DigitalExperienceBundle, Network, CustomSite, CMS contents).
IMPORTANT!!
Right after loading this skill, you MUST copy the selected workflows/steps to your plan as a TODO checklist and work on each of the item carefully to ensure correctness. You MUST load the relevant reference docs even though they may live outside of user's project folder.
Table of Contents
- When to Use
- Critical Rules
- Core Site Properties
- Project Structure in DigitalExperienceBundle Format
- Reference Docs
- Common Workflows
When to Use
When working with Experience LWR sites:
- Creating and scaffolding new LWR site
- Adding pages (routes + views)
- Configuring LWC components, layouts, themes, or branding styles
- Setting up guest user access (public sites)
- Creating or modifying guest sharing rules (
sharingGuestRules) for any Salesforce object (Account, Case, Contact, etc.) — including when the user refers to a "Site Guest User" username or any guest user by ID - Troubleshoot deployment errors related to Experience LWR Sites
Supported Template: Build Your Own (LWR) - talon-template-byo
- More templates to support in the future.
Critical Rules
1. Before using any MCP tool, make sure they're actually available. If a tool is missing for the current task, let the user know and pause the current workflow. 2. MUST ALWAYS load the relevant reference docs before doing anything. 3. MUST ALWAYS strictly follow workflows in Common Workflows that match user's requirements. The instructions there should override any conflicting global rules and should have the highest priority over your existing knowledge. 4. Flexipage is abstracted away for newer LWR sites with DigitalExperienceBundle, so NEVER use any Flexipage-related MCP tool or skills to handle LWR sites' contents.
Core Site Properties
Before doing anything else, note down the following properties from the local project if available as they will be used for various operations. Check with the user if any of the following is missing:
- Site name: Required. (e.g.,
'My Community'). - URL path prefix: Optional. Alphanumeric characters only. Convert from site name if not provided (e.g.,
'mycommunity') and verify with the user for the converted value. - Template type devName:
talon-template-byo.
Project Structure in DigitalExperienceBundle Format
Site Metadata
- DigitalExperienceConfig
digitalExperienceConfigs/{siteName}1.digitalExperienceConfig-meta.xml- DigitalExperienceBundle
digitalExperiences/site/{siteName}1/{siteName}1.digitalExperience-meta.xml- Network
networks/{siteName}.network-meta.xml- CustomSite
sites/{siteName}.site-meta.xml
DigitalExperience Contents
digitalExperiences/site/{siteName}1/sfdc_cms__*/{contentApiName}/*- These are the content components defining routes, views, theme layouts, etc. Each component must have a
_meta.jsonandcontent.jsonfile.
Content Type Descriptions
| Content Type | Description | When to Use |
|---|---|---|
sfdc_cms__site | Root site configuration containing site-wide settings | Required for every site; one per site |
sfdc_cms__appPage | Application page container that groups routes and views | Required; defines the app shell |
sfdc_cms__route | URL routing definition mapping paths to views | Create one for each page/URL path |
sfdc_cms__view | Page layout and component structure | Create one for each route; defines page content. Also use to edit existing views (e.g., adding/removing components on a specific page) |
sfdc_cms__brandingSet | Brand colors, fonts, and styling tokens | Required; defines site-wide styling. Use to create or edit existing branding sets |
sfdc_cms__languageSettings | Language and localization configuration | Required; defines supported languages |
sfdc_cms__mobilePublisherConfig | Mobile app publishing settings | Required for mobile app deployment |
sfdc_cms__theme | Theme definition referencing layouts and branding | Required; one per site |
sfdc_cms__themeLayout | Page layout templates used by views | Create layouts for different page structures. Also use to edit existing theme layouts (e.g., updating theme layout, add a component that's persistent across pages) |
Important: Creating any new pages require BOTH sfdc_cms__route AND sfdc_cms__view.
Object Pages
Object Pages are dedicated pages used to display and manage record-level data for a specific Salesforce entity/object. For example, an custom object "Car" should have "Car_Detail", "Car_List", and "Car_Related_list" views.
References
Reference docs within the skill directory. Note that these are local and not MCP. Before doing anything, you MUST ALWAYS load them first if they match user intent.
- bootstrap-template-byo-lwr.md - Site creation, template defaults
- configure-content-route.md - Route creation (custom/object pages)
- configure-content-view.md - View creation/editing (custom/object pages)
- configure-content-themeLayout.md - Theme layout creation + theme sync
- configure-content-brandingSet.md - Branding with color patterns/WCAG
- handle-component-and-region-ids.md - UUID generation (CRITICAL) for component and region ids used in views and themeLayout.
- handle-ui-components.md - Component discovery, schemas, insertion, configuration
- configure-guest-sharing-rules.md - Guest sharing rules (
sharingGuestRules) for public sites — use for any request involving "guest sharing rule", "Site Guest User", or sharing object records with unauthenticated visitors - update-site-urls.md - Updating site URLs - URL architecture, workflow for updating
urlPathPrefixin DigitalExperienceConfig, Network, and CustomSite
Common Workflows
- See References for detailed capabilities.
- Always follow the steps defined in the workflows sequentially whether the task is small, big, quick, or complex.
Creating a New Site
Rules:
- NEVER generate the files manually.
Steps (Follow the steps sequentially. Do not skip any step before proceeding):
- [ ] ALWAYS read bootstrap-template-byo-lwr.md within the skill directory. Do not proceed to the next step without loading the file.
- [ ] Follow the bootstrap doc strictly on site creation
Creating and Editing Standard or Object Pages
Steps (Follow the steps sequentially. Do not skip any step before proceeding):
- [ ] MUST read configure-content-route.md
- [ ] MUST read configure-content-view.md
- [ ] MUST read handle-component-and-region-ids.md
Adding UI Components to Pages
Steps (Follow the steps sequentially. Do not skip any step before proceeding):
- [ ] MUST read handle-ui-components.md to add LWCs to LWR sites.
- [ ] MUST read handle-component-and-region-ids.md to handle id generation
- [ ] MUST read configure-content-themeLayout.md if a component has one of the following requirements:
- needs to be "sticky" and persistent across pages
- is used as a theme layout
Creating Page Layouts / Container Components
Steps (Follow the steps sequentially. Do not skip any step before proceeding):
- [ ] MUST read handle-ui-components.md
Creating Theme Layouts
Steps (Follow the steps sequentially. Do not skip any step before proceeding):
- [ ] CRITICAL:Before doing anything else, MUST Check with user whether this new theme layout reuses an existing theme layout Lightning web component or requires a new one. If it requires a new one, make sure to read handle-ui-components.md to create the new theme layout component before proceeding. DO NOT skip this step even if doing so would be faster or more efficient.
- [ ] MUST read configure-content-themeLayout.md.
- [ ] MUST read configure-content-view.md if need to apply theme layout to pages
Applying/Setting Theme Layouts
Steps (Follow the steps sequentially. Do not skip any step before proceeding):
- [ ] MUST read configure-content-view.md
Configuring Branding
Steps (Follow the steps sequentially. Do not skip any step before proceeding):
- [ ] MUST read configure-content-brandingSet.md to configure background colors, foreground colors, button colors, and other branding colors that affect all pages.
CUD Operations on DigitalExperience Contents
- Users can perform create, update, delete operations on DigitalExperience Contents.
Steps (Follow the steps sequentially. Do not skip any step before proceeding):
- [ ] Determine what content types the user wants to modify
- [ ] MUST read the reference doc related to the target content types if the doc exists. e.g., if modifying
sfdc_cms__route, load configure-content-route.md. - [ ] MUST read handle-component-and-region-ids.md if creating or modifying view or theme layout
- [ ] Always Call
execute_metadata_actionto get the schema and examples for that content type after loading the corresponding reference docs. - Call once per content type per user request: If you're creating/modifying multiple items of the same content type (e.g., creating 3 routes), you only need to call
execute_metadata_actionONCE for that content type. Reuse the schema and examples for all items of that type within the same user request. - For each unique content type you need to work with, always call
execute_metadata_actionusing the following:
{
"metadataType": "ExperienceSiteLwr",
"actionName": "getSiteContentMetadata",
"parameters": {
"contentType": "<content type from table above>",
"shouldIncludeExamples": true
}
}Configuring Guest User Sharing Rules
- [ ] MUST read configure-guest-sharing-rules.md and follow all steps there.
Retrieving Site Preview and Builder URLs After Deployment
Use when user requests to preview a site, access a builder site, or after successfully deploying a site.
Use the execute_metadata_action MCP tool to get the preview and builder URLs:
{
"metadataType": "ExperienceSiteLwr",
"actionName": "getSiteUrls",
"parameters": {
"siteDevName": "<site developer name>"
}
}The site developer name can be found in the CustomSite filename (e.g., sites/MySite.site-meta.xml → developer name is MySite).
If the site is not found, an error message will be returned indicating that the site may not be deployed. Ensure the site has been successfully deployed before calling this action.
Updating Experience Site URLs
Use when user wants to update or change site URLs (urlPathPrefix).
Steps (Follow the steps sequentially. Do not skip any step before proceeding):
- [ ] MUST read update-site-urls.md to understand the three-component architecture and URL update workflow
- [ ] Follow the step-by-step workflow in the doc to update URLs consistently across all three components (DigitalExperienceConfig, Network, CustomSite)
Validation & Deployment
Use sf CLI to validate and deploy. Access help docs by attaching --help, e.g.:
sf project deploy --helpsf project deploy validate --help
Note that metadata types are space-delimited. Never wrap them in quotes or use commas. For example, --metadata "DigitalExperienceBundle DigitalExperience" is incorrect — always use --metadata DigitalExperienceBundle DigitalExperience.
Validate:
sf project deploy validate --metadata DigitalExperienceBundle DigitalExperience DigitalExperienceConfig Network CustomSite --target-org ${usernameOrAlias}Deploy:
sf project deploy start --metadata DigitalExperienceBundle DigitalExperience DigitalExperienceConfig Network CustomSite --target-org ${usernameOrAlias}Build Your Own (LWR) Template
Use when creating a new site or retrieving default values for site metadata.
Table of Contents
- Bootstrap Options
- Default Values Reference
Bootstrap Options
IMPORTANT: First site setup initializes services. Warn user - recommend Option 1 for first site.
Ask user to choose:
1. Create in org, then download metadata 2. Scaffold locally before deploying
Option 1: Create in Org
Step 1: Run the create command:
sf community create --name "{siteName}" --template-name 'Build Your Own (LWR)' --url-path-prefix "{prefix}" --target-org {usernameOrAlias} --jsonSite creation is an async job. As soon as the terminal returns output, capture the jobId and move on — do not wait for the shell command to fully exit.
Step 2: Ask the user: "Would you like me to wait for the site creation to complete and then retrieve the metadata for you, or would you prefer to retrieve it yourself once it's ready?"
Stop here and wait for the user's response before proceeding.
---
If the user wants to wait and retrieve:
Poll the BackgroundOperation object using the following command, replacing {jobId} with the ID returned from the create command:
SELECT Status FROM BackgroundOperation WHERE Id = '{jobId}'Use the MCP tool run_soql_query to run this query on the given target org. If the MCP tool is not available, run the following command instead, replacing {jobId} and {usernameOrAlias} with the appropriate values:
sf data query --query "SELECT Status FROM BackgroundOperation WHERE Id = '{jobId}'" --target-org {usernameOrAlias} --jsonRepeat until Status is Complete. If the query does not return Complete after several attempts, ask the user to manually check their target org to confirm whether site creation has completed. Stop here and do not proceed until the user confirms the site is ready.
Once complete, run each of the following retrieval commands one at a time. Do not chain them together (e.g. do not use &&). Wait for each command to return output before running the next. Metadata types are space-delimited — never wrap them in quotes or use commas:
sf project retrieve start --metadata DigitalExperienceBundle --target-org {usernameOrAlias} --jsonsf project retrieve start --metadata DigitalExperienceConfig --target-org {usernameOrAlias} --jsonsf project retrieve start --metadata Network --target-org {usernameOrAlias} --jsonsf project retrieve start --metadata CustomSite --target-org {usernameOrAlias} --json---
If the user wants to retrieve themselves:
Provide them with the retrieval command to run once the site is ready. Metadata types are space-delimited — never wrap them in quotes or use commas:
sf project retrieve start --metadata DigitalExperienceBundle DigitalExperienceConfig Network CustomSite --target-org {usernameOrAlias} --json---
Option 2: Scaffold Locally
sf template generate digital-experience site --name "{siteName}" --template-name 'Build Your Own (LWR)' --url-path-prefix "{prefix}"Generates metadata with defaults: DigitalExperienceConfig, DigitalExperiences, Network, CustomSite, and content (route, view, themeLayout, etc.).
Post-Creation Config
After site metadata is generated, use MCP tool execute_metadata_action to fetch additional information about the template:
{
"metadataType": "ExperienceSiteLwr",
"actionName": "getSiteTemplateMetadata",
"parameters": { "templateDevName": "talon-template-byo" }
}If result provides disabledViews, delete both view and route directories.
Example: If disabledViews includes "tooManyRequests":
- Delete:
digitalExperiences/site/{siteDevName}/sfdc_cms__view/tooManyRequests/ - Delete:
digitalExperiences/site/{siteDevName}/sfdc_cms__route/Too_Many_Requests/
---
Default Values Reference
Note: CLI generates these. Listed for reference only - use CLI first.
Metadata Defaults
DigitalExperienceConfig:
label: {siteName}
urlPathPrefix: {siteUrlPathPrefix}
space: site/{siteName}1DigitalExperienceBundle:
label: {siteName}1
modules: [sfdc_cms__collection, sfdc_cms__mobilePublisherConfig]Network:
allowInternalUserLogin: false
allowMembersToFlag: false
changePasswordTemplate: unfiled$public/CommunityChangePasswordEmailTemplate
disableReputationRecordConversations: true
emailSenderAddress: {adminEmailAddress}
emailSenderName: {siteName}
embeddedLoginEnabled: false
enableApexCDNCaching: true
enableCustomVFErrorPageOverrides: false
enableDirectMessages: true
enableExpFriendlyUrlsAsDefault: false
enableExperienceBundleBasedSnaOverrideEnabled: true
enableGuestChatter: false
enableGuestFileAccess: false
enableGuestMemberVisibility: false
enableImageOptimizationCDN: true
enableInvitation: false
enableKnowledgeable: false
enableLWRExperienceConnectedApp: true
enableMemberVisibility: false
enableNicknameDisplay: true
enablePrivateMessages: false
enableReputation: false
enableShowAllNetworkSettings: false
enableSiteAsContainer: true
enableTalkingAboutStats: true
enableTopicAssignmentRules: true
enableTopicSuggestions: false
enableUpDownVote: false
forgotPasswordTemplate: unfiled$public/CommunityForgotPasswordEmailTemplate
gatherCustomerSentimentData: false
headlessForgotPasswordTemplate: unfiled$public/CommunityHeadlessForgotPasswordTemplate
headlessRegistrationTemplate: unfiled$public/CommunityHeadlessRegistrationTemplate
networkMemberGroups:
- profile: admin
networkPageOverrides:
- changePasswordPageOverrideSetting: Standard
- forgotPasswordPageOverrideSetting: Designer
- homePageOverrideSetting: Designer
- loginPageOverrideSetting: Designer
- selfRegProfilePageOverrideSetting: Designer
newSenderAddress: admin@company.com
picassoSite: {siteName}1
selfRegistration: false
sendWelcomeEmail: true
site: {siteName}
siteArchiveStatus: NotArchived
status: UnderConstruction
tabs:
- defaultTab: home
- standardTab: Chatter
urlPathPrefix: {siteUrlPathPrefix}vforcesite
welcomeTemplate: unfiled$public/CommunityWelcomeEmailTemplateCustomSite:
active: true
allowGuestPaymentsApi: false
allowHomePage: false
allowStandardAnswersPages: false
allowStandardIdeasPages: false
allowStandardLookups: false
allowStandardPortalPages: true
allowStandardSearch: false
authorizationRequiredPage: CommunitiesLogin
bandwidthExceededPage: BandwidthExceeded
browserXssProtection: true
cachePublicVisualforcePagesInProxyServers: true
clickjackProtectionLevel: SameOriginOnly
contentSniffingProtection: true
enableAuraRequests: true
fileNotFoundPage: FileNotFound
genericErrorPage: Exception
inMaintenancePage: InMaintenance
indexPage: CommunitiesLanding
masterLabel: {siteName}
redirectToCustomDomain: false
referrerPolicyOriginWhenCrossOrigin: true
selfRegPage: CommunitiesSelfReg
siteType: ChatterNetwork
urlPathPrefix: {siteUrlPathPrefix}vforcesiteContent Defaults
apiNames and other metadata of site contents:
sfdc_cms__appPage:
- mainAppPage
sfdc_cms__brandingSet:
- Build_Your_Own_LWR
sfdc_cms__languageSettings:
- languages
sfdc_cms__mobilePublisherConfig:
- mobilePublisherConfig
sfdc_cms__theme:
- Build_Your_Own_LWR
sfdc_cms__route:
| Route | apiName | routeType | urlPrefix | urlName | viewId | configurationTags |
|---|---|---|---|---|---|---|
| Home | Home | home | "" | home | home | |
| Login | Login | login-main | login | login | login | |
| Register | Register | self-register | SelfRegister | register | register | |
| Forgot_Password | Forgot_Password | forgot-password | ForgotPassword | forgot-password | forgotPassword | |
| Check_Password | Check_Password | check-password | CheckPasswordResetEmail | check-password | checkPasswordResetEmail | |
| Error | Error | error | error | error | error | |
| Service_Not_Available | Service_Not_Available | service-not-available | service-not-available | service-not-available | serviceNotAvailable | allow-in-static-site |
| Too_Many_Requests | Too_Many_Requests | too-many-requests | too-many-requests | too-many-requests | tooManyRequests | too-many-requests, allow-in-static-site |
| News_Detail__c | News_Detail__c | managed-content-sfdc_cms__news | news | news-detail | newsDetail |
sfdc_cms__view:
| View | apiName | viewType | urlName | themeLayoutType |
|---|---|---|---|---|
| home | home | home | home | Inner |
| login | login | login-main | login | Inner |
| register | register | self-register | register | Inner |
| forgotPassword | forgotPassword | forgot-password | forgot-password | Inner |
| checkPasswordResetEmail | checkPasswordResetEmail | check-password | check-password | Inner |
| error | error | error | error | Inner |
| serviceNotAvailable | serviceNotAvailable | service-not-available | service-not-available | ServiceNotAvailable |
| tooManyRequests | tooManyRequests | too-many-requests | too-many-requests | ServiceNotAvailable |
| newsDetail | newsDetail | managed-content-sfdc_cms__news | news-detail | Inner |
sfdc_cms__site:
- {siteName}1
sfdc_cms__themeLayout:
- scopedHeaderAndFooter
- snaThemeLayout
Content Type: sfdc_cms__brandingSet
Use when user explicitly requests creating/updating branding set.
Table of Contents
- Core Principles
- Generation Guidelines
- Editing Existing Branding Sets
- Branding Property Patterns
Core Principles
1. Purpose: Manage site-wide branding properties (colors, fonts, etc.). 2. Site Association: Branding sets are linked to the site configuration.
Generation Guidelines
1. Directory Structure
1. Location: digitalExperiences/site/[SITE_NAME]/sfdc_cms__brandingSet/[BRANDING_SET_NAME]/ 2. Required Files:
_meta.json- Metadata file defining the API name and typecontent.json- Content file defining the configuration and layout
3. Naming Convention: Underscore-separated names (e.g., Branding_Set).
2. _meta.json Structure
The _meta.json file must contain:
{
"apiName": "[BRANDING_SET_NAME]",
"type": "sfdc_cms__brandingSet",
"path": "brandingSets"
}Rules:
apiName: Must match the directory name exactly (e.g.,Branding_Set)
3. content.json Structure
The content.json file must contain:
{
"type": "sfdc_cms__brandingSet",
"title": "[DISPLAY_TITLE]",
"contentBody": {},
"urlName": "[URL_NAME]"
}Field Definitions:
type: Required. Represents the content type. The only supported value is"sfdc_cms__brandingSet".title: Required. Human-readable display title (e.g., Branding Set).- Maximum length is 100 characters.
- Must be unique within the space's brandingSet content items.
contentBody: Include allrequiredproperties fromschemaDefinition.
1. Seed: Always call execute_metadata_action with shouldIncludeExamples: true. Copy the entire example object from examplesOfContentType[0] into content.json. NEVER start from a minimal stub. 2. Recalculate (CRITICAL STOP): You MUST stop and perform explicit changes for dependent tokens BEFORE generating JSON.
- [] Refer to "Branding Property Patterns" for detailed calculations.
brandingSetType: Represents whether the color palette is for the entire site or a specific section.APP: The branding set applies to the entire site. There can be only one branding set of this type.SCOPED: ASCOPEDbranding set can be applied only to a section component for granular overrides.definitionName: Required. Represents the name for the branding set used in the site or template’s theme.- Build Your Own (LWR): uses
talon-template-byo:branding - Microsite: uses
microsite-template-marketing:branding values: Required. Represents a map (object) of branding values (colors, fonts, etc.) that can be applied to a site.- Format: An object containing key-value pairs that represent branding-set values.
- Patterns: See the "Branding Property Patterns" section for details on value relationships.
urlName: Lowercase with hyphens (e.g.,branding-set)
4. Naming Conventions Summary
| Field | Format | Example |
|---|---|---|
| Directory/apiName | Underscore-separated | Branding_Set |
| title | Human-readable | Branding Set |
| urlName | Lowercase-hyphens | build-your-own-lwr |
5. Generation Checklist
- [ ] Directory and
_meta.jsonfollow naming conventions - [ ]
content.jsonhas all required fields - [ ]
contentBodyfollows the schema provided byexecute_metadata_action - [ ] STOP AND VERIFY:
contentBody.valueshonors all Branding Property Patterns defined below and explicitly recalculated and updated all dependent tokens based on any token updates requested by the user.
Editing Existing Branding Sets
Use this section when modifying existing branding sets under the sfdc_cms__brandingSet directory.
Editing Checklist
- [ ] Ensure all modified branding properties honor the Branding Property Patterns defined below.
Branding Property Patterns
When generating or validating contentBody.values, follow these established patterns for consistency:
1. Color Scaling Patterns (The "Rule of 3")
Salesforce uses a numeric suffix system (Color, Color1, Color2, Color3) to create a tonal palette.
- Darkening Trend: As the suffix number increases, the color becomes progressively darker.
- Example:
BackgroundColor(#ffffff) →_BackgroundColor1(#ebebeb) →_BackgroundColor2(#c2c2c2) →_BackgroundColor3(#858585). - Contrast/Foreground Colors: Every base color has a corresponding
ForegroundColorto ensure accessibility. - WCAG Compliance: Ensure a color contrast ratio of at least 4.5:1 between the background and foreground colors for standard text.
- Dark base colors usually have white (#ffffff) foregrounds.
- Light base colors (like
_NeutralColor) usually have black (#000000) foregrounds.
2. Font Size Hierarchy
- Base vs. Small: The
Smallvariant is typically 75% of the base size. - Example:
BodyFontSize(1rem) →BodySmallFontSize(0.75rem). - Heading Scale: Headings follow a standard typographic scale:
HeadingExtraLarge: 2.5remHeadingLarge: 1.75rem (~70% of XL)HeadingMedium: 1.25rem (~50% of XL)HeadingSmall: 1.125rem
3. Design Token Mapping
Prefer using DXP Design Tokens over hardcoded values where possible:
- Fonts: Use
var(--dxp-s-html-font-family)for base, body, and button fonts. - Brand Alignment: Use
var(--dxp-g-brand)for primary brand colors and links.
4. Component Consistency
- Buttons: Maintain consistent
BorderRadius(e.g., 4px) across all button sizes (Small, Medium, Large). - Form Elements:
FormElementLabelFontSizeandFormElementTextFontSizeshould match.
5. Spacing and Ratios
- Device Ratios: Desktop spacing (padding/spacers) is typically 1.33x larger than mobile spacing.
- Example:
ColumnSpacerSizeDesktop(1rem) vsColumnSpacerSizeMobile(0.75rem).
Content Type: sfdc_cms__route
Use when user explicitly requests creating a new page. Not for editing existing routes.
Table of Contents
- Generation Guidelines
- Core Principles
- Directory Structure (All Routes)
- _meta.json Structure
- Part A: CUSTOM PAGES
- Part B: OBJECT PAGES
Generation Guidelines
PAGE TYPES: These guidelines supports two types of pages:
1. Custom Pages - Single route pages for custom content (e.g., About Us). Note: Standard pages (e.g., Home, Login) come pre-built with the site and cannot be created. 2. Object Pages - Requires 3 routes: Detail, List, and Related List (e.g., Account, custom objects)
Core Principles
1. Purpose: Generate new routes under the sfdc_cms__route directory. 2. View Association: Each route must reference a corresponding view in the sfdc_cms__view directory. 3. CRITICAL: The routeType in the route's content.json MUST exactly match the viewType in the corresponding view's content.json. This is a required validation rule.
Directory Structure (All Routes)
1. Location: digitalExperiences/site/[SITE_NAME]/sfdc_cms__route/[ROUTE_NAME]/ 2. Required Files:
_meta.json- Metadata file defining the API name and typecontent.json- Content file defining the configuration and layout
3. Naming Convention: Underscore-separated names with "__c" suffix (About_Us__c, Account_Detail__c)
_meta.json Structure (All Routes)
The _meta.json file must contain:
{
"apiName": "[ROUTE_NAME]",
"type": "sfdc_cms__route",
"path": "routes"
}Rules:
apiName: Must match the route directory name exactlytype: Always"sfdc_cms__route"path: Always"routes"
Part A: CUSTOM PAGES
Use this section when creating single-route custom content pages.
A.1. content.json Structure
The content.json file must contain:
{
"type": "sfdc_cms__route",
"title": "[DISPLAY_TITLE]",
"contentBody": {},
"urlName": "[URL_NAME]"
}Field Definitions:
type: Always"sfdc_cms__route"title: Human-readable display title (e.g., About Us)contentBody: Include allrequiredproperties fromschemaDefinition. UseexamplesOfContentTypefor reference.urlName: URL identifier (lowercase with hyphens, e.g.,about-us)
A.2. Naming Conventions
For a page named "About Us":
| Field | Format | Example |
|---|---|---|
| Directory Name | Underscore-separated + "__c" | About_Us__c |
| apiName | Same as directory | About_Us__c |
| title | Human-readable | About Us |
| contentBody.activeViewId | Underscore-separated (no __c) | About_Us |
| contentBody.routeType | "custom-" + lowercase hyphens | custom-about-us |
| contentBody.urlPrefix | Lowercase hyphens | about-us |
| urlName | Lowercase hyphens | about-us |
CRITICAL: routeType MUST exactly match viewType in the corresponding view's content.json.
A.3. View Dependency
- Before creating a route, ensure the corresponding view exists in
sfdc_cms__view/[view_name]/ - If the view doesn't exist, create it first following the view creation guidelines
A.4. Generation Checklist
- [ ] Route directory and files created (see Directory Structure)
- [ ]
_meta.jsonfollows structure (see _meta.json Structure) - [ ]
content.jsonfollows structure (see A.1) - [ ] All naming conventions applied (see A.2)
- [ ] Corresponding view exists (see A.3)
Part B: OBJECT PAGES
Use this section when creating object pages that require Detail, List, and Related List routes.
B.1. Overview
Object pages require three routes to be created together:
1. Detail Route - Displays a single record 2. List Route - Displays a list of records 3. Related List Route - Displays related records for a parent record
OBJECT TYPES: Two types of Salesforce objects use different routeType formats:
| Object Type | routeType Format | Example |
|---|---|---|
| Standard (Account, Contact) | [type]-[keyPrefix] | detail-001, list-001, relatedlist-001 |
| Custom (Test_Object__c) | [type]-[ObjectApiName] | detail-Test_Object__c, list-Test_Object__c |
- keyPrefix: 3-character identifier unique to each standard object (Account=001, Contact=003)
- ObjectApiName: Custom object API name including the "__c" suffix
Obtain object information from the objectList MCP output:
[
["Label", "ApiName", "KeyPrefix", "IsCustom"]
]B.2. Required Routes
Create three directories under sfdc_cms__route/:
[OBJECT_NAME]_Detail__c/[OBJECT_NAME]_List__c/[OBJECT_NAME]_Related_List__c/
B.3. content.json Structure
Each route's content.json file must contain:
{
"type": "sfdc_cms__route",
"title": "[OBJECT_NAME] [TYPE]",
"contentBody": {},
"urlName": "[object_name_lowercase]-[type]"
}Field Definitions:
type: Always"sfdc_cms__route"title: Human-readable title (Account Detail, Account List)contentBody: Include allrequiredproperties fromschemaDefinition. UseexamplesOfContentTypefor reference.contentBody.urlPrefix: CRITICAL: Must be identical across all three object page views (Detail, List, and Related List) for the same object.urlName: Lowercase with hyphens (account-detail, account-list)
B.4. Object Page Examples
Use [ObjectName] as the object name (Account, Test_Object) and [IDENTIFIER] as:
- Standard objects: keyPrefix (001 for Account, 003 for Contact)
- Custom objects: ObjectApiName (Test_Object__c)
content.json Template
{
"type": "sfdc_cms__route",
"title": "[ObjectName] [Detail|List|Related List]",
"contentBody": {
"activeViewId": "[ObjectName]_[Detail|List|Related_List]",
"configurationTags": [],
"pageAccess": "UseParent",
"routeType": "[detail|list|relatedlist]-[IDENTIFIER]",
"urlPrefix": "[object-name-lowercase]"
},
"urlName": "[object-name-lowercase]-[detail|list|related-list]"
}Rules:
- Before any actions, always call
execute_metadata_actionto get the full schema and examples per the skill document.
routeType Examples
| Route Type | Standard (Account) | Custom (Test_Object__c) |
|---|---|---|
| Detail | detail-001 | detail-Test_Object__c |
| List | list-001 | list-Test_Object__c |
| Related List | relatedlist-001 | relatedlist-Test_Object__c |
B.5. Naming Conventions
For an object named "Account":
| Field | Detail | List | Related List |
|---|---|---|---|
| Directory Name | Account_Detail__c | Account_List__c | Account_Related_List__c |
| apiName | Account_Detail__c | Account_List__c | Account_Related_List__c |
| title | Account Detail | Account List | Account Related List |
| activeViewId | Account_Detail | Account_List | Account_Related_List |
| routeType (Standard) | detail-[keyPrefix] | list-[keyPrefix] | relatedlist-[keyPrefix] |
| routeType (Custom) | detail-[ObjectApiName] | list-[ObjectApiName] | relatedlist-[ObjectApiName] |
| urlPrefix | account | account | account |
| urlName | account-detail | account-list | account-related-list |
CRITICAL: routeType MUST exactly match viewType in the corresponding view's content.json.
B.6. View Dependency
- Before creating routes, ensure corresponding views exist in
sfdc_cms__view/: [ObjectName]_Detail/,[ObjectName]_List/,[ObjectName]_Related_List/activeViewIdmust match the view directory name exactlyrouteTypemust exactly matchviewTypein the corresponding view- If views don't exist, create them first following the view creation guidelines
B.7. Generation Checklist
- [ ] Object type determined (Standard or Custom) and identifier obtained (keyPrefix or ObjectApiName)
- [ ] All three routes created: Detail, List, and Related List, each with
_meta.jsonandcontent.json - [ ] All naming conventions applied (see B.5)
- [ ] Corresponding views exist (see B.6)
- [ ]
routeTypematchesviewTypefor all three routes
Content Type: sfdc_cms__themeLayout
Use when user explicitly requests creating a new layout.
Table of Contents
- Directory Structure
- Purpose A: Generate new theme layouts under the
sfdc_cms__themeLayoutdirectory.
- _meta.json Structure
- content.json Structure
- Naming Conventions
- Theme Sync After Creation
- Generation Checklist
- Purpose B: Editing existing theme layouts under the
sfdc_cms__themeLayoutdirectory.
Directory Structure
1. Location: digitalExperiences/site/[SITE_NAME]/sfdc_cms__themeLayout/[THEME_LAYOUT_NAME]/ 2. Required Files:
_meta.json- Metadata file defining the API name and typecontent.json- Content file defining the configuration and layout
Purpose A: Generate New Theme Layouts
IMPORTANT: These guidelines should ONLY be applied when the user explicitly requests creating a new layout for their site. Do not apply these guidelines automatically for other tasks or when editing existing layouts.
Order of operations
If the user decides to create a new LWC, create the LWC first THEN the theme layout metadata.
_meta.json Structure
The _meta.json file must contain:
{
"apiName": "[THEME_LAYOUT_NAME]",
"type": "sfdc_cms__themeLayout",
"path": "themeLayouts"
}Rules:
apiName: Must match the themeLayout directory name exactlytype: Always"sfdc_cms__themeLayout"path: Always"themeLayouts"
content.json Structure
The content.json file must contain:
{
"type": "sfdc_cms__themeLayout",
"title": "[DISPLAY_TITLE]",
"contentBody": {
"component": {
"attributes": { },
"children": [ "[regions in the layout]" ],
"definition": "[FQN of root layout component]",
"id": "[root component id]",
"type": "component"
}
},
"urlName": "[url name]"
}Field Definitions:
type: Always"sfdc_cms__themeLayout"title: Human-readable display title, words separated by spaces (e.g. "Scoped Header and Footer")contentBody: Include allrequiredproperties fromschemaDefinition. UseexamplesOfContentTypefor reference.- Do not add additional fields.
urlName: URL identifier (lowercase, words separated by dashes e.g., "scoped-header-and-footer")contentBody.compnent.definition: The actual theme layout component that displays/renders the layout and includes theme region components.
Rules:
- Before any actions, always call
execute_metadata_actionto get the full schema and examples per the skill document.
Naming Conventions
1. Directory Name: Should be in camelCase 2. apiName: Must exactly match the directory name 3. title: Human-readable title with spaces (e.g., "Service Not Available Theme Layout") 4. urlName: Lowercase with hyphens for URL-friendly format (e.g., "new-layout")
Theme Sync After Creation
After creating a new sfdc_cms__themeLayout, you MUST update:
digitalExperiences/site/[SITE_NAME]/sfdc_cms__theme/[THEME_API_NAME]/content.jsonLookup: To find the theme content.json for the current site:
1. Navigate up from the current theme layout directory to the site directory. 2. Look in sfdc_cms__theme/ (sibling directory to sfdc_cms__themeLayout/). 3. Find the theme directory (typically one per site). 4. Read the file: content.json.
Action (append-only):
- ALWAYS append a new entry to
contentBody.layouts. - Do NOT replace or remove existing
layoutsentries. layoutIdMUST exactly match the new theme layoutapiName.layoutTypeMUST be chosen based on intended view usage.- Default: Generate a random 30-character alphanumeric string (e.g.,
xEGgPxY5j5TForZe3J7SBguOfQicEy) for thelayoutType. Ensure this string is unique and does not match any existinglayoutTypein the list.
Example:
{
"contentBody": {
"layouts": [
{ "layoutId": "existingLayoutA", "layoutType": "Inner" },
{ "layoutId": "existingLayoutB", "layoutType": "ServiceNotAvailable" },
{ "layoutId": "[NEW_THEME_LAYOUT_API_NAME]", "layoutType": "[30_CHAR_RANDOM_STRING]" }
]
}
}Generation Checklist
When generating a new theme layout, ensure:
- [ ]
_meta.jsoncreated with correctapiName,type, andpath - [ ]
content.jsoncreated with all required fields - [ ]
urlNameuses lowercase with hyphens - [ ]
titleis human-readable - [ ]
sfdc_cms__theme/[THEME_API_NAME]/content.jsonupdated by appending a newcontentBody.layoutsmapping - [ ] CRITICAL: Complete all the UUID generation steps. See handle-component-and-region-ids.md
Purpose B: Editing Existing Theme Layouts
Component Modifications
When adding, removing, or configuring components in existing theme layouts, always refer to handle-ui-components.md for placement hierarchy, component structure, column layout, and property configuration.
Note: Theme layouts often define the overall structure (header/footer) surrounding the main content region. Ensure components are added to the correct region (e.g., header, footer).
Content Type: sfdc_cms__view
Use when user explicitly requests creating a new page or editing an existing page.
Table of Contents
- Purpose A: Generate New Views
- Purpose B: Editing Existing Views
Purpose A: Generate New Views
Generation Guidelines
PAGE TYPES: These guidelines supports two types of pages:
1. Custom Pages - Single view pages for custom content (e.g., About Us). Note: Standard pages (e.g., Home, Login) come pre-built with the site and cannot be created. 2. Object Pages - Requires 3 views: Detail, List, and Related List (e.g., Account, custom objects)
Core Principles
1. Route Association: Views are referenced by routes via the activeViewId field. 2. CRITICAL: The viewType MUST exactly match the routeType in the corresponding route.
Directory Structure (All Views)
1. Location: Views must be created under: digitalExperiences/site/[SITE_NAME]/sfdc_cms__view/[VIEW_NAME]/ 2. Required Files:
_meta.json- Metadata file defining the API name and typecontent.json- Content file defining the configuration and layout
3. Naming Convention: Underscore-separated names, no "__c" suffix (About_Us, Account_Detail)
_meta.json Structure (All Views)
The _meta.json file must contain:
{
"apiName": "[VIEW_NAME]",
"type": "sfdc_cms__view",
"path": "views"
}Rules:
apiName: Must match directory name exactly. No "__c" suffix.type: Always"sfdc_cms__view"path: Always"views"
Theme Layout Type (All Views)
The contentBody.themeLayoutType field specifies which theme layout to use for the view. There can only be one per view.
- Default:
"Inner"- Use this default if the user does not specify a layout OR if the lookup fails to find a matching layoutType - Lookup: To find valid values:
1. Navigate up from the current view directory to the site directory 2. Look in sfdc_cms__theme/ (sibling directory to sfdc_cms__view/) 3. Find the theme directory (typically one per site) 4. Check content.json → contentBody.layouts[] for the layouts array
- Layout Name/ID Resolution: If the user provides only a layout name or ID (e.g., "scopedHeaderAndFooter"), you must look up the corresponding
layoutType:
1. Find the theme's content.json as described above 2. Locate the contentBody.layouts array containing layoutId/layoutType pairs 3. Match the user-provided name/ID against layoutId values 4. Use the corresponding layoutType value for contentBody.themeLayoutType 5. Use ONLY the `layoutType` value for contentBody.themeLayoutType - do NOT use the layoutId or user's provided name 6. If no match is found, use the default `"Inner"`
PART A: CUSTOM PAGES
Use this section when creating single-view custom content pages.
A.1. content.json Structure
The content.json file must contain:
{
"type": "sfdc_cms__view",
"title": "[DISPLAY_TITLE]",
"contentBody": {},
"urlName": "[URL_NAME]"
}Field Definitions:
type: Always"sfdc_cms__view"title: Human-readable display title (e.g., About Us)contentBody: Include allrequiredproperties fromschemaDefinition. UseexamplesOfContentTypefor reference.urlName: Lowercase with hyphens (e.g.,about-us)
A.2. Component Structure
MUST use community_layout:sldsFlexibleLayout as the root with exactly 2 regions (content and sfdcHiddenRegion), even if no components exist:
community_layout:sldsFlexibleLayout (root)
├── content (region) — main page content
└── sfdcHiddenRegion (region) — hidden region for SEO and metadataCRITICAL REQUIREMENTS:
- Region names are fixed: The region
namefield MUST be exactlycontentorsfdcHiddenRegion. Do NOT invent custom region names. - sfdcHiddenRegion MUST contain seoAssistant: The
sfdcHiddenRegionregion MUST ALWAYS include acommunity_builder:seoAssistantcomponent in itschildrenarray. - Components live in children: All components are placed inside the
childrenarray of a region. Use an emptychildren: []array forcontentif no components exist.
Each region requires: id (unique UUID), name, title, type: "region", children. Do not add any other fields.
A.3. Naming Conventions Summary
| Field | Format | Example |
|---|---|---|
| Directory/apiName | Underscore-separated, no "__c" | About_Us |
| title | Human-readable | About Us |
| viewType | custom- + lowercase-hyphens | custom-about-us |
| urlName | Lowercase-hyphens | about-us |
A.4. Route Dependency
The route's activeViewId must match the view's directory name exactly.
A.5. Generation Checklist
- [ ] Directory and
_meta.jsonfollow structure (see Directory Structure, _meta.json Structure) - [ ]
content.jsonhas all required fields (A.1) - [ ] Component structure correct with both regions (A.1)
- [ ] CRITICAL: Complete all the UUID generation steps. see handle-component-and-region-ids.md
- [ ]
viewTypematches route'srouteType(CRITICAL)
PART B: OBJECT PAGES
Use this section when creating object pages that require Detail, List, and Related List views.
B.1. Overview
Object pages require three views: Detail, List, and Related List. All share the same object name.
Object Types & viewType Format:
| Object Type | Identifier | viewType Example |
|---|---|---|
| Standard (Account, Contact) | keyPrefix (3-char) | detail-001, list-001, relatedlist-001 |
| Custom (Test_Object__c) | API name with __c | detail-Test_Object__c, list-Test_Object__c |
Obtain object information from the objectList MCP output from sfdc_cms__route:
[
["Label", "ApiName", "KeyPrefix", "IsCustom"]
]B.2. Required Views
Create three directories under sfdc_cms__view/:
[OBJECT_NAME]_Detail/[OBJECT_NAME]_List/[OBJECT_NAME]_Related_List/
B.3. content.json Structure
{
"type": "sfdc_cms__view",
"title": "[OBJECT_NAME] [TYPE]",
"contentBody": {
"component": {},
"dataProviders": [],
"themeLayoutType": "[THEME_LAYOUT_TYPE]",
"viewType": "[PREFIX]-[IDENTIFIER]"
},
"urlName": "[OBJECT_NAME_LOWERCASE]-[TYPE]"
}Field Definitions:
type: Always"sfdc_cms__view"title: Human-readable (e.g., "Account Detail")contentBody: Include allrequiredproperties fromschemaDefinition. UseexamplesOfContentTypefor reference.contentBody.viewType: CRITICAL: Must exactly match route'srouteTypeurlName: Lowercase with hyphens (e.g.,account-detail)
Rules:
- Before any actions, always call
execute_metadata_actionto get the full schema and examples per the skill document.
B.4. Component Structure
Uses same structure as Part A.1 (Component Structure) with these SEO assistant differences:
- Detail View:
pageTitle: "{!Record._Object}: {!Record._Title}" - List/Related List Views:
recordId: "{!recordId}"(no pageTitle)
Default template includes one section with one empty column. seedComponents must be [] (not null).
B.5. Naming Conventions Summary
| Field | Detail | List | Related List |
|---|---|---|---|
| Directory/apiName | [Object]_Detail | [Object]_List | [Object]_Related_List |
| title | [Object] Detail | [Object] List | [Object] Related List |
| viewType (Standard) | detail-[keyPrefix] | list-[keyPrefix] | relatedlist-[keyPrefix] |
| viewType (Custom) | detail-[ApiName__c] | list-[ApiName__c] | relatedlist-[ApiName__c] |
| urlName | [object]-detail | [object]-list | [object]-related-list |
B.6. Route Dependency
The route's activeViewId must match the view's directory name exactly. The viewType must exactly match the route's routeType.
B.7. Generation Checklist
- [ ] Object type determined; identifier obtained (
keyPrefixor API name with__c) - [ ] All three views created: Detail, List, and Related List, each with
_meta.jsonandcontent.json - [ ]
viewTypematches route'srouteTypefor all three views (CRITICAL) - [ ] Component structure correct with both regions (see A.1)
- [ ] SEO assistant configured correctly per view type (B.4)
- [ ] CRITICAL: Complete both UUID generation steps. see handle-component-and-region-ids.md
Purpose B: Editing Existing Views
Use this section when modifying existing views under the sfdc_cms__view directory.
Component Modifications
When adding, removing, or configuring components in existing views, always refer to handle-ui-components.md for placement hierarchy, component structure, column layout, and property configuration.
Theme Layout Type
To change a view's theme layout, update contentBody.themeLayoutType in the view's content.json. See Theme Layout Type (All Views) for default and lookup details
Guest User Sharing Rules (Public Sites Only)
Use when the user asks to create or modify a guest sharing rule, mentions a username containing "Guest User" or "Site Guest User" (e.g. "ZenLease Site Guest User"), or wants to share object records with unauthenticated visitors.
Steps
1. Resolve the guest user identity: If the user provides a username like "ZenLease Site Guest User", use it directly as the <guestUser> value (CommunityNickname). If a user ID is provided (e.g. 005AAC00003f8EP), query the org to get the CommunityNickname first. 2. Check for existing file: Look for sharingRules/{ObjectName}.sharingRules-meta.xml locally. If missing, retrieve it from the org before editing. 3. Generate the rule: Follow the XML example and critical requirements below. Never use sharingCriteriaRules or <role>/<group> for guest rules.
If sharingRules metadata is not available locally in force-app/main/default/sharingRules, retrieve it from the org before creating new rules.
Retrieve Full SharingRules Schema
Use the metadata MCP tool with metadataType "SharingRules" to retrieve schema.
XML Example
<?xml version="1.0" encoding="UTF-8"?>
<SharingRules xmlns="http://soap.sforce.com/2006/04/metadata">
<sharingGuestRules>
<fullName>ShareAccountsWithSiteGuest</fullName>
<accessLevel>Read</accessLevel>
<includeHVUOwnedRecords>false</includeHVUOwnedRecords>
<label>Share Accounts With Site Guest</label>
<sharedTo>
<guestUser>[site Guest User's CommunityNickanme]</guestUser>
</sharedTo>
<criteriaItems>
<field>Name</field>
<operation>notEqual</operation>
<value>null</value>
</criteriaItems>
</sharingGuestRules>
</SharingRules>Critical Requirements
1. SharedTo Element: Must use <guestUser>{site Guest User's CommunityNickanme}</guestUser> (not URL path prefix). 2. includeHVUOwnedRecords: Required field. Set to false unless records owned by high-volume site users should be included. 3. One XML file per object: Put all rules for a given object in one file. Do not create additional.
Common Mistakes
- Using
<role>or<group>instead of<guestUser>in sharedTo - Omitting the required
includeHVUOwnedRecordsfield - Using
includeRecordsOwnedByAll(that's forsharingCriteriaRules, not guest rules)
UUID Generation
Use when handling IDs for components and regions of views. All component and region IDs in Experience Site content must be unique UUIDs.
Requirements
1. Format: Lowercase UUID v4 (e.g., 5d56a22f-c1e8-40d3-92ec-6e10e71e36de) 2. Uniqueness: Must be unique across ALL content.json files in site (under digitalExperiences/site/<SITE_NAME>/)
For New content.json Files Only
Multistep Process (REQUIRED):
- CRITICAL: Each step must be performed separately - do NOT combine steps into a single automated command or script
- Step 1: Create files with descriptive placeholders for UUIDs (e.g.,
UUID_CONTENT_REGION,UUID_HIDDEN_REGION,UUID_SEO_COMPONENT) - Step 2: Count the total number of UUID placeholder occurrences in the generated file, then generate exactly that many UUIDs using:
node -e "console.log(Array.from({length: N}, () => require('crypto').randomUUID()).join('\n'))"where N is the total count of placeholder occurrences. Present this command to the user for execution.- Step 3: Replace each placeholder occurrence sequentially with the generated UUIDs from the list, ensuring each occurrence gets a unique UUID from the list. Perform replacements one at a time or in small batches - do NOT automate this with scripts.
- Step 4: Validate that all placeholders have been replaced - read the file and search for any remaining placeholder patterns (e.g.,
UUID_). The file is NOT valid until all placeholders are replaced with actual UUIDs. - CRITICAL: Every single placeholder occurrence must be replaced with a DIFFERENT UUID from the generated list, even if the placeholder name is repeated. For example, if you have 5 total placeholder occurrences, generate 5 UUIDs and replace each occurrence with the next UUID from the list.
- NEVER write UUIDs inline during file creation - always use the multistep placeholder approach
For Editing Existing content.json Files
- CRITICAL: Read file first and preserve all existing UUIDs exactly as-is
- NEVER replace existing UUIDs with placeholders
- For newly added components/regions only, follow the multistep placeholder process from step 3
UI Component Handling
Use when adding/configuring components to be used in Experience site.
Component Insertion
Insert custom Lightning Web Components (LWC) into views.
What is a Custom Component?
Any LWC in c namespace (e.g., c:heroBanner). Distinct from OOTB components (e.g., community_builder:htmlEditor).
Prerequisites for Custom LWC
js-meta.xml Requirements:
<isExposed>true</isExposed>- Targets:
lightningCommunity__Page,lightningCommunity__Default
Property Type Constraints (MANDATORY GATE):
1. Supported: String, Integer, Boolean, Color, Picklist 2. Unsupported: Any other type → STOP immediately
- Do NOT delete, comment, or auto-correct
- Advise user to set up Custom Property Editor (CPE) or Custom Property Type
3. Type Mismatch: type="Number" → change to type="Integer" in js-meta.xml
Do not proceed until LWC files are compliant or user advised on CPE/CPT.
Placement Hierarchy
NEVER place components directly in top-level regions. Must nest inside community_layout:section → column region.
community_layout:sldsFlexibleLayout (root)
└── region (content/header/footer)
└── community_layout:section
└── region (column: col1/col2)
└── component(s)Column Width & Layout
12-unit grid: Column widths sum to 12 per section.
Width Formats:
- Grid units: 8 + 4
- Percentages: 66% + 33% → 8 + 4; 50% + 50% → 6 + 6
- Ratios: 2:1 → 8 + 4; 1:1 → 6 + 6; equal thirds → 4 + 4 + 4
Layout Rules:
- One section = one horizontal row
- Multiple rows = multiple sections (siblings)
- Multiple components in column = vertical stack
Set width in sectionConfig (JSON string attribute on section component).
sectionConfig Structure
Top-level (when parsed):
UUID: Section ID (matches section component'sid)columns: Array of column definitions
Each column:
UUID: Column ID (matches column region'sid)columnKey: Column identifier (e.g.,col1,col2) - matches column region'snamecolumnName: Display name (e.g., "Column 1")columnWidth: String from"1"to"12"(must sum to 12)seedComponents: Array ornull(typically[]ornull)
Example (serialized as JSON string in sectionConfig attribute):
{
"UUID": "295e6a8b-fd94-485b-af9d-7ccf5b3048ee",
"columns": [
{
"UUID": "7e1f7e33-5ba8-4fef-8494-6ea3e90b22a0",
"columnKey": "col1",
"columnName": "Column 1",
"columnWidth": "12",
"seedComponents": null
}
]
}Named Region Creation
In order to create a component with drag-n-droppable region/slot that can be used in Experience Builder sites and persist across views, there are multiple steps needed.
Page layout components should add the lightningCommunity__Page_Layout target in js-meta.xml. Theme layout components should add the lightningCommunity__Theme_Layout target in js-meta.xml. Add lightningCommunity__Page as a target for page layouts and any component with slots that is not explicitly defined as a theme layout.
The js file in LWC need to declare named slots:
/**
* @slot header
* @slot footer
*/
export default class YourComponentName extends LightningElement {}Do not add any other comments in the declaration comment block. The named @slot annotations must be the last comments in the block before the class declaration.
In html, named slots are needed. <slot name="header"> and <slot name="footer"> in the above example.
For theme layout component, a <slot> with no name is the main content region, a slot with name is a sticky region that doesn't change from page to page that uses the same theme layout component.
No need to declare target config properties for the slots/regions. See the example below for adding a component with named slots into a view.
Component Structure
{
"id": "[UNIQUE_UUID]",
"type": "component",
"definition": "[NAMESPACE]:[COMPONENT_NAME]",
"attributes": {
"[ATTRIBUTE_NAME]": "[ATTRIBUTE_VALUE]"
}
}Field Definitions:
id: Unique UUID (seehandle-component-and-region-ids.md)type: Always"component"definition:- Custom LWC:
c:[componentName](e.g.,c:heroBanner) - OOTB:
[namespace]:[componentName](e.g.,community_builder:richTextEditor) attributes: Component properties- Omit if no attributes (don't include empty object)
- Custom LWC: Only
@apiproperties intargetConfigs(withlightningCommunity__Defaulttarget) - OOTB: Only exposed schema properties
Complete Examples
Example 1: Overall structure Correct nesting: content region → section → column region → components
{
"type": "region",
"name": "content",
"children": [
{
"attributes": {
"sectionConfig": "{\"UUID\":\"295e6a8b-fd94-485b-af9d-7ccf5b3048ee\",\"columns\":[{\"UUID\":\"7e1f7e33-5ba8-4fef-8494-6ea3e90b22a0\",\"columnName\":\"Column 1\",\"columnKey\":\"col1\",\"columnWidth\":\"12\",\"seedComponents\":null}]}"
},
"children": [
{
"children": [
{
"definition": "c:testComponent",
"id": "2ae498bd-2871-487d-8fb1-b186376cee3b",
"type": "component"
},
{
"id": "7c7d3b6a-1e2f-4a33-9c1e-8b2a6d5f4e3b",
"type": "component",
"definition": "c:helloWorld",
"attributes": {
"title": "Hello"
}
}
],
"id": "7e1f7e33-5ba8-4fef-8494-6ea3e90b22a0",
"name": "col1",
"title": "Column 1",
"type": "region"
}
],
"definition": "community_layout:section",
"id": "295e6a8b-fd94-485b-af9d-7ccf5b3048ee",
"type": "component"
}
]
}CRITICAL: Follow UUID generation process (handle-component-and-region-ids.md) when inserting components.
Example 2: Representing slots If a component with slots (i.e. @slot annotation) is inserted, slots must appear as named regions. In this example the component threeColumn has 3 slots, named left, center, and right.
{
"attributes" : { },
"children" : [ {
"id" : "4c6148c7-c07e-4245-ae50-ac07891046f2",
"name" : "left",
"title" : "left",
"type" : "region"
}, {
"id" : "f362e789-7f09-40b4-a59f-03f76ea73401",
"name" : "center",
"title" : "center",
"type" : "region"
}, {
"id" : "2678ddd4-a1a4-41c4-bf5a-1a3e55891eb2",
"name" : "right",
"title" : "right",
"type" : "region"
} ],
"definition" : "c:threeColumn",
"id" : "b9e517c5-90ac-49e9-91b7-3730512c95a3",
"type" : "component"
}
Updating Experience Site URLs
Experience sites have a three-component architecture with two distinct URL patterns. Understanding this structure is critical when updating site URLs.
Architecture Overview
Every Salesforce Experience Site consists of three components:
1. Network (metadata: Network) - Network configuration 2. ChatterNetwork Site (metadata: CustomSite) - Authentication endpoints and core site services 3. ChatterNetworkPicasso Site (metadata: DigitalExperienceConfig + DigitalExperienceBundle) - Customer-facing pages and content
URL Pattern
These three components use two different URLs:
- Primary URL (ChatterNetworkPicasso): Used for customer-facing pages
- Defined in:
DigitalExperienceConfig→<urlPathPrefix> - Example:
mysite
- Secondary URL (Network + CustomSite): Used for authentication endpoints and other services
- Defined in:
Network→<urlPathPrefix>ANDCustomSite→<urlPathPrefix> - Example:
mysitevforcesite - Must be synchronized - both files must have identical values
By default, Salesforce differentiates these URLs by appending vforcesite suffix to the Network/CustomSite URL.
URL Update Workflow
When updating site URLs, follow this workflow:
Step 1: Discover All URL References
Search for all occurrences of urlPathPrefix across the project metadata files.
For agents: Use the search_files tool with these parameters:
- path:
force-app/main/default - regex:
urlPathPrefix - file_pattern:
*.xml
For humans: Use your IDE's search functionality or command line tools:
# Using grep
grep -r "urlPathPrefix" force-app/main/default --include="*.xml"
# Using VS Code: Ctrl+Shift+F (Windows/Linux) or Cmd+Shift+F (Mac)
# Search for: urlPathPrefix
# Files to include: *.xmlStep 2: Identify URL Groups
Determine which files belong to which URL group:
- Primary URL Group:
DigitalExperienceConfig - Secondary URL Group:
NetworkANDCustomSite
Step 3: Update URLs Consistently
Update the <urlPathPrefix> value in each file:
- DigitalExperienceConfig: Update to new primary URL
- Network: Update to new secondary URL (typically primary URL +
vforcesite) - CustomSite: Update to same value as Network (must be synchronized)
Step 4: Validate Naming Convention
Ensure URL values follow best practices:
- Use lowercase letters only
- Avoid special characters except hyphens where appropriate
- Keep URLs concise and meaningful
Step 5: Verify Consistency
Before deploying, confirm:
- [ ] Primary URL in
DigitalExperienceConfigis set correctly - [ ] Secondary URL in
NetworkmatchesCustomSiteexactly - [ ] URLs are properly differentiated (typically via suffix)
- [ ] All URL values follow naming conventions
Example URL Configuration
ChatterNetworkPicasso Site (Primary):
DigitalExperienceConfig: <urlPathPrefix>bestsupport</urlPathPrefix>
Network + ChatterNetwork Site (Secondary):
Network: <urlPathPrefix>bestsupportvforcesite</urlPathPrefix>
CustomSite: <urlPathPrefix>bestsupportvforcesite</urlPathPrefix>Common Pitfalls to Avoid
❌ Don't update only one or two files - all three must be updated ❌ Don't use different values in Network and CustomSite ❌ Don't use the same URL for both Primary and Secondary groups ❌ Don't skip the discovery step with search_files ✅ Do use search_files to find all occurrences first ✅ Do maintain URL differentiation between the two groups ✅ Do follow lowercase naming conventions