@W-21482430 feat: migrate exp lwr site knowledge docs to skill (#27)

* feat: migrate exp lwr site knowledge docs to skill

* feat: small wording adjustment

* feat: stricter wording for loading reference docs

* feat: incorporate new guest user fix

* feat: rename docs to use verb and update some wording

* feat: updating wording

* feat: wording adjustments

* fix: resolve pr comments

* fix: rm old references

* fix: rm extra comma

* fix: make LLM always load the reference docs

* fix: wording

* feat: incorporate core changes and wording updates

* fix: guest user name

* fix: stricter wording

* fix: revert to repeat instructions

* fix: rm "manual" to avoid confusion

* fix: updating mcp tools calls instructions

* feat: handle component slots

* fix: add MCP hints for objectList

---------

Co-authored-by: Jeff Carey <jeffrey.carey@salesforce.com>
Co-authored-by: Hemant Singh Bisht <hsinghbisht@salesforce.com>
This commit is contained in:
Scott Mo 2026-03-18 10:11:27 -05:00 committed by GitHub
parent 287a7e9caf
commit 690f722a0b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 1441 additions and 178 deletions

View File

@ -0,0 +1,196 @@
---
name: salesforce-experience-lwr-site
description: Creates, modifies, or manages Salesforce Experience Cloud LWR sites via DigitalExperience metadata. Always trigger when users mention Experience sites, LWR sites, DigitalExperience, Experience Cloud, community sites, portals, creating pages, adding routes, views, theme layouts, branding sets, previewing sites, or any DigitalExperience bundle work. Also use when users mention specific content types like sfdc_cms__route, sfdc_cms__themeLayout, etc. or when troubleshooting site deployment.
---
# Experience LWR Site Builder
Build and configure Salesforce Experience Cloud Lightning Web Runtime (LWR) sites via metadata (DigitalExperienceConfig, DigitalExperienceBundle, Network, CustomSite, CMS contents).
## 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)
- 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. **ALWAYS** load the relevant reference docs before doing anything.
3. **ALWAYS** strictly follow workflows in [Common Workflows](#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.json` and `content.json` file.
#### 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 |
| `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`.
## References
Reference docs within the skill directory. Note that these are **local** and not MCP.
- [bootstrap-template-byo-lwr.md](docs/bootstrap-template-byo-lwr.md) - Site creation, template defaults
- [configure-content-route.md](docs/configure-content-route.md) - Route creation (custom/object pages)
- [configure-content-view.md](docs/configure-content-view.md) - View creation/editing (custom/object pages)
- [configure-content-themeLayout.md](docs/configure-content-themeLayout.md) - Theme layout creation + theme sync
- [configure-content-brandingSet.md](docs/configure-content-brandingSet.md) - Branding with color patterns/WCAG
- [handle-component-and-region-ids.md](docs/handle-component-and-region-ids.md) - **UUID generation (CRITICAL)** for component and region ids used in views and themeLayout.
- [handle-ui-components.md](docs/handle-ui-components.md) - Component discovery, schemas, insertion, configuration
## Common Workflows
- See [References](#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](docs/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):
- [ ] Load [configure-content-route.md](docs/configure-content-route.md)
- [ ] Load [configure-content-view.md](docs/configure-content-view.md)
- [ ] Load [handle-component-and-region-ids.md](docs/handle-component-and-region-ids.md)
- [ ] Follow the instructions of the above docs strictly to accomplish user's goal
### Adding UI Components to Pages
**Steps** (Follow the steps sequentially. Do not skip any step before proceeding):
- [ ] Read and follow [handle-ui-components.md](docs/handle-ui-components.md) to add LWCs to LWR sites.
- [ ] Load and follow [handle-component-and-region-ids.md](docs/handle-component-and-region-ids.md) to handle id generation
- [ ] Read and follow [configure-content-themeLayout.md](docs/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 Theme Layouts
**Steps** (Follow the steps sequentially. Do not skip any step before proceeding):
- [ ] Read and follow strictly [configure-content-themeLayout.md](docs/configure-content-themeLayout.md).
### Configuring Branding
**Steps** (Follow the steps sequentially. Do not skip any step before proceeding):
- [ ] Read and follow strictly [configure-content-brandingSet.md](docs/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
- [ ] Read and follow strictly 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](docs/configure-content-route.md).
- [ ] **Always** Read [handle-component-and-region-ids.md](docs/handle-component-and-region-ids.md) if creating or modifying view or theme layout
- [ ] **Always** Call `execute_metadata_action` to 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_action` ONCE 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_action` using the following:
```json
{
"metadataType": "ExperienceSiteLwr",
"actionName": "getSiteContentMetadata",
"parameters": {
"contentType": "<content type from table above>",
"shouldIncludeExamples": true
}
}
```
### Retrieving Site URLs After Deployment
After successfully deploying the site using `sf project deploy`, use the `execute_metadata_action` MCP tool to get the preview and builder URLs:
```json
{
"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.
### Validation & Deployment
Use `sf` CLI to validate and deploy. Access help docs by attaching `--help`, e.g.:
- `sf project deploy --help`
- `sf project deploy validate --help`
Note that metadata types are space-delimited.
**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}`

View File

@ -0,0 +1,224 @@
# 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
```bash
sf community create --name "{siteName}" --template-name 'Build Your Own (LWR)' --url-path-prefix "{prefix}"
```
After creation, retrieve metadata using sf CLI.
### Option 2: Scaffold Locally
```bash
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:
```json
{
"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**:
```yaml
label: {siteName}
urlPathPrefix: {siteUrlPathPrefix}
space: site/{siteName}1
```
**DigitalExperienceBundle**:
```yaml
label: {siteName}1
modules: [sfdc_cms__collection, sfdc_cms__mobilePublisherConfig]
```
**Network**:
```yaml
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/CommunityWelcomeEmailTemplate
```
**CustomSite**:
```yaml
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}vforcesite
```
### Content 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

View File

@ -0,0 +1,131 @@
# Content Type: sfdc_cms__brandingSet
**Use when** user explicitly requests creating/updating branding set.
## Table of Contents
- Core Principles
- Generation Guidelines
- 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 type
- `content.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:
```json
{
"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:
```json
{
"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 all `required` properties from `schemaDefinition`. Use `examplesOfContentType` for reference.
- `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`: A `SCOPED` branding 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 templates 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`)
**Rules**:
- Before any actions, *always* call `execute_metadata_action` to get the full schema and examples per the skill document.
### 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.json` follow naming conventions (1, 2)
- [ ] `content.json` has all required fields (3)
- [ ] `contentBody` follows the schema provided by `execute_metadata_action`
## 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 `ForegroundColor` to 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 `Small` variant is typically **75%** of the base size.
- Example: `BodyFontSize` (1rem) → `BodySmallFontSize` (0.75rem).
- **Heading Scale**: Headings follow a standard typographic scale:
- `HeadingExtraLarge`: 2.5rem
- `HeadingLarge`: 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**: `FormElementLabelFontSize` and `FormElementTextFontSize` should match.
### 5. Spacing and Ratios
- **Device Ratios**: Desktop spacing (padding/spacers) is typically **1.33x** larger than mobile spacing.
- Example: `ColumnSpacerSizeDesktop` (1rem) vs `ColumnSpacerSizeMobile` (0.75rem).

View File

@ -0,0 +1,232 @@
# 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 type
- `content.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:
```json
{
"apiName": "[ROUTE_NAME]",
"type": "sfdc_cms__route",
"path": "routes"
}
```
**Rules**:
- `apiName`: Must match the route directory name exactly
- `type`: 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:
```json
{
"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 all `required` properties from `schemaDefinition`. Use `examplesOfContentType` for 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.json` follows structure (see _meta.json Structure)
- [ ] `content.json` follows 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:
```json
[
["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:
```json
{
"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 all `required` properties from `schemaDefinition`. Use `examplesOfContentType` for 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
```json
{
"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_action` to 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/`
- `activeViewId` must match the view directory name exactly
- `routeType` must exactly match `viewType` in 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.json` and `content.json`
- [ ] All naming conventions applied (see B.5)
- [ ] Corresponding views exist (see B.6)
- [ ] `routeType` matches `viewType` for all three routes

View File

@ -0,0 +1,141 @@
# 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__themeLayout` directory.
- _meta.json Structure
- content.json Structure
- Naming Conventions
- Theme Sync After Creation
- Generation Checklist
- Purpose B: Editing existing theme layouts under the `sfdc_cms__themeLayout` directory.
## 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 type
- `content.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.
### _meta.json Structure
The `_meta.json` file must contain:
```json
{
"apiName": "[THEME_LAYOUT_NAME]",
"type": "sfdc_cms__themeLayout",
"path": "themeLayouts"
}
```
**Rules**:
- `apiName`: Must match the themeLayout directory name exactly
- `type`: Always `"sfdc_cms__themeLayout"`
- `path`: Always `"themeLayouts"`
### content.json Structure
The `content.json` file must contain:
```json
{
"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 all `required` properties from `schemaDefinition`. Use `examplesOfContentType` for reference.
- Do not add additional fields.
- `urlName`: URL identifier (lowercase, words separated by dashes e.g., "scoped-header-and-footer")
**Rules**:
- Before any actions, *always* call `execute_metadata_action` to 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.json
```
**Lookup**: 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 `layouts` entries.
- `layoutId` MUST exactly match the new theme layout `apiName`.
- `layoutType` MUST be chosen based on intended view usage.
- **Default**: Generate a random 30-character alphanumeric string (e.g., `xEGgPxY5j5TForZe3J7SBguOfQicEy`) for the `layoutType`. Ensure this string is unique and does not match any existing `layoutType` in the list.
**Example**:
```json
{
"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.json` created with correct `apiName`, `type`, and `path` (III)
- [ ] `content.json` created with all required fields (IV)
- [ ] `urlName` uses lowercase with hyphens (V)
- [ ] `title` is human-readable (V)
- [ ] `sfdc_cms__theme/[THEME_API_NAME]/content.json` updated by appending a new `contentBody.layouts` mapping (VI)
- [ ] **CRITICAL**: Complete all the UUID generation steps. See `docs/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](docs/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`).

View File

@ -0,0 +1,233 @@
# 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 type
- `content.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:
```json
{
"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.
- **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:
```json
{
"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 all `required` properties from `schemaDefinition`. Use `examplesOfContentType` for 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 metadata
```
**CRITICAL REQUIREMENTS**:
- **Region names are fixed**: The region `name` field MUST be exactly `content` or `sfdcHiddenRegion`. Do NOT invent custom region names.
- **sfdcHiddenRegion MUST contain seoAssistant**: The `sfdcHiddenRegion` region MUST ALWAYS include a `community_builder:seoAssistant` component in its `children` array.
- **Components live in children**: All components are placed inside the `children` array of a region. Use an empty `children: []` array for `content` if 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.json` follow structure (see Directory Structure, _meta.json Structure)
- [ ] `content.json` has all required fields (A.1)
- [ ] Component structure correct with both regions (A.1)
- [ ] **CRITICAL**: Complete all the UUID generation steps. see `docs/handle-component-and-region-ids.md`
- [ ] `viewType` matches route's `routeType` (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`:
```json
[
["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
```json
{
"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 all `required` properties from `schemaDefinition`. Use `examplesOfContentType` for reference.
- `contentBody.viewType`: **CRITICAL**: Must exactly match route's `routeType`
- `urlName`: Lowercase with hyphens (e.g., `account-detail`)
**Rules**:
- Before any actions, *always* call `execute_metadata_action` to 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 (`keyPrefix` or API name with `__c`)
- [ ] All three views created: **Detail**, **List**, and **Related List**, each with `_meta.json` and `content.json`
- [ ] `viewType` matches route's `routeType` for 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 `docs/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](docs/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

View File

@ -0,0 +1,42 @@
# Guest User Sharing Rules (Public Sites Only)
**Use when** the user explicitly wants to make the site **public** (accessible to unauthenticated visitors). If the site is private/login-required, guest sharing rules are not needed.
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
<?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 `includeHVUOwnedRecords` field
- Using `includeRecordsOwnedByAll` (that's for `sharingCriteriaRules`, not guest rules)

View File

@ -0,0 +1,27 @@
# 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

View File

@ -0,0 +1,215 @@
# 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's `id`)
- `columns`: Array of column definitions
**Each column**:
- `UUID`: Column ID (matches column region's `id`)
- `columnKey`: Column identifier (e.g., `col1`, `col2`) - matches column region's `name`
- `columnName`: Display name (e.g., "Column 1")
- `columnWidth`: String from `"1"` to `"12"` (must sum to 12)
- `seedComponents`: Array or `null` (typically `[]` or `null`)
**Example** (serialized as JSON string in `sectionConfig` attribute):
```json
{
"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:
```js
/**
* @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
```json
{
"id": "[UNIQUE_UUID]",
"type": "component",
"definition": "[NAMESPACE]:[COMPONENT_NAME]",
"attributes": {
"[ATTRIBUTE_NAME]": "[ATTRIBUTE_VALUE]"
}
}
```
**Field Definitions**:
- `id`: Unique UUID (see `handle-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 `@api` properties in `targetConfigs` (with `lightningCommunity__Default` target)
- OOTB: Only exposed schema properties
### Complete Examples
**Example 1: Overall structure**
Correct nesting: `content` region → section → column region → components
```json
{
"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.
```json
{
"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"
}

View File

@ -1,178 +0,0 @@
---
name: salesforce-experience-site
description: Use this skill when users need to create, modify, or manage Salesforce Experience Cloud sites (LWR sites). Trigger when users mention Experience sites, LWR sites, DigitalExperience, Experience Cloud, community sites, portals, creating pages, adding routes, views, theme layouts, branding sets, or any DigitalExperience bundle work. Also use when users mention specific content types like sfdc_cms__route, sfdc_cms__view, sfdc_cms__themeLayout, or when troubleshooting site deployment. Always use this skill for any Experience Cloud or LWR site work.
---
## When to Use This Skill
Use this skill when you need to:
- Create Experience Cloud sites or communities
- Build LWR (Lightning Web Runtime) sites
- Set up site configuration and settings
- Generate Experience Site metadata
- Troubleshoot deployment errors related to Experience Sites
## Specification
# Experience LWR Site Metadata Specification
An LWR site can be represented by metadata DigitalExperienceConfig, DigitalExperienceBundle, Network, CustomSite, and CMS contents. Your purpose is to assist developers in creating and editing these metadata.
## Supported Template Types
Template name - Template DevName
- Build Your Own (LWR) - talon-template-byo
## Core Properties
Before doing anything else, identify the following properties from the local project if available. 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: Optional. Defaults to `talon-template-byo`.
## General Tips
TIP 1. When available, the site developer name can be found in the CustomSite filename (e.g., `sites/MySite.site-meta.xml` → developer name is `MySite`).
## Project Structure in DigitalExperienceBundle Format
### Site Metadata
- DigitalExperienceConfig
- Path: `digitalExperienceConfigs/{siteName}1.digitalExperienceConfig-meta.xml`
- DigitalExperienceBundle
- Path: `digitalExperiences/site/{siteName}1/{siteName}1.digitalExperience-meta.xml`
- Network
- Path: `networks/{siteName}.network-meta.xml`
- CustomSite
- Path: `sites/{siteName}.site-meta.xml`
### DigitalExperience Contents
- Path: `digitalExperiences/site/{siteName}1/sfdc_cms__*/{contentApiName}/*`
- Description: These are the content components defining routes, views, theme layouts, etc. Each component must have a `_meta.json` and `content.json` file.
#### 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, updating theme layout) |
| `sfdc_cms__brandingSet` | Brand colors, fonts, and styling tokens | Required; defines site-wide styling |
| `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 |
**Important:** Creating any new pages require BOTH `sfdc_cms__route` AND `sfdc_cms__view`.
## CUD Operations on DigitalExperience Contents
- Users can perform create, update, delete operations on DigitalExperience Contents.
- **IMPORTANT:** Before ANY modification (create, update, or delete) to content, ALWAYS call `execute_metadata_action` first to get the schema, examples, and instructions for that content type.
- **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_action` ONCE 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, call `execute_metadata_action` using the following:
```json
{
"metadataType": "ExperienceSite",
"actionName": "getSiteContentMetadata",
"parameters": {
"contentType": "<content type from table above>",
"shouldIncludeExamples": true
}
}
```
- Do not call the `execute_metadata_action` MCP tool with any other site actionName unless specified in this knowledge doc/instructions.
## Retrieving Site URLs After Deployment
After successfully deploying the site using `sf project deploy`, use the `execute_metadata_action` MCP tool to get the preview and builder URLs:
```json
{
"metadataType": "ExperienceSite",
"actionName": "getSiteUrls",
"parameters": {
"siteDevName": "<site developer name>"
}
}
```
Refer to TIP 1 to get the site developer name.
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.
## Enhancement Rules
- If need to understand how site metadata should be configured, use the `get_metadata_api_context` MCP tool to get the schemas.
- Use MCP tool `execute_metadata_action` with `getSiteTemplateMetadata` to get the knowledge document about the template and its default configurations if needed. **IMPORTANT:** This MUST be used for new site:
```json
{
"metadataType": "ExperienceSite",
"actionName": "getSiteTemplateMetadata",
"parameters": {
"templateDevName": "<template DevName, e.g. talon-template-byo>"
}
}
```
- To validate Experience Site metadata, run CLI command `sf project deploy validate --metadata DigitalExperienceBundle DigitalExperience DigitalExperienceConfig Network CustomSite --target-org ${usernameOrAlias}`
## Guest User Sharing Rules (Public Sites Only)
**When to use**: Only create guest sharing rules when the user explicitly wants to make the site **public** (accessible to unauthenticated visitors). If the site is private/login-required, guest sharing rules are not needed.
If sharingRules metadata is not available locally in force-app/main/default/sharingRules, retrieve it from the org before creating new rules.
To get the full SharingRules schema, use the `get_metadata_api_context` MCP tool:
```json
{
"metadataType": "SharingRules"
}
```
### XML Example
```xml
<?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 developer name]</guestUser>
</sharedTo>
<criteriaItems>
<field>Name</field>
<operation>notEqual</operation>
<value>null</value>
</criteriaItems>
</sharingGuestRules>
</SharingRules>
```
Refer to TIP 1 to get the site developer name.
### Critical Requirements
1. **SharedTo Element**: Must use `<guestUser>{siteName}</guestUser>` where `{siteName}` is the Network name (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 `includeHVUOwnedRecords` field
- Using `includeRecordsOwnedByAll` (that's for `sharingCriteriaRules`, not guest rules)
## Workflows
### Creating a new site
- Verify with user on the value of site name, url path prefix, and site template type.
- Retrieve template information from `getSiteTemplateMetadata` and strictly follow the rules of its knowledge document.
- Proceed to the workflow of editing an existing site.
### Editing an existing site
- Identify the intent of the user and break it down into steps.
- Make use of `get_metadata_api_context` if user wants to edit site metadata.
- Use `getSiteContentMetadata` to understand how to edit site contents.
- Once the tasks are done, perform site metadata validation.