12 KiB
| name | description |
|---|---|
| salesforce-flexipage | Generate valid, deployable Salesforce Lightning Page (FlexiPage) metadata XML. Always use this skill when working with .flexipage-meta.xml files. Trigger when users mention Lightning pages, creating pages, adding components to pages, or page customization. Always use this skill for any FlexiPage-related work, even if they just mention "page" in the context of Salesforce. |
CONTEXT
When to Use This Skill
Use this skill when you need to:
- Edit ANY
*.flexipage-meta.xmlfile - Create new Lightning Pages (FlexiPages) for records, apps, or home pages
- Edit existing pages by adding or changing components
- Troubleshoot FlexiPage deployment errors
Goal
Generate valid, deployable FlexiPage metadata XML using CLI bootstrapping, with incremental enhancement and deployment. Ensure all generated XML follows Salesforce metadata conventions and passes deployment validation.
Overview
Generate Lightning Pages (RecordPage, AppPage, HomePage) using CLI bootstrapping for component discovery and configuration.
Terminology: Lightning Pages are the marketing/UX name for FlexiPage metadata. Users may refer to them simply as "pages", "Lightning pages", or "FlexiPages". The metadata type is FlexiPage and files use the .flexipage-meta.xml extension.
CRITICAL FOUNDATION (Read First!)
Critical XML Rules
1. Property Value Encoding (MOST COMMON ERROR)
Any property value with HTML/XML characters MUST be manually encoded in the following order (wrong order causes double-encoding corruption):
1. & → & (FIRST! Encode this before others)
2. < → <
3. > → >
4. " → "
5. ' → '
Wrong:
<value><b>Important</b> text</value>
Correct:
<value><b>Important</b> text</value>
Check your XML: Search for <value> tags - they should never contain raw < or > characters.
2. Field References
ALWAYS: Record.{FieldApiName}
NEVER: {ObjectName}.{FieldApiName}
<!-- Correct -->
<fieldItem>Record.Name</fieldItem>
<!-- Wrong -->
<fieldItem>Account.Name</fieldItem>
3. Region vs Facet Types
Template Regions (header, main, sidebar):
<name>header</name>
<type>Region</type>
Component Facets (internal slots like fieldSection columns):
<name>Facet-12345</name>
<type>Facet</type>
Rule: If it's a template region name → Region. If it's a component slot → Facet.
4. fieldInstance Structure
Ensure every fieldInstance includes:
<itemInstances>
<fieldInstance>
<fieldInstanceProperties>
<name>uiBehavior</name>
<value>none</value> <!-- none|readonly|required -->
</fieldInstanceProperties>
<fieldItem>Record.FieldName__c</fieldItem>
<identifier>RecordFieldName_cField</identifier>
</fieldInstance>
</itemInstances>
Rules:
- Place each fieldInstance in its own
<itemInstances>wrapper - Always include
fieldInstancePropertieswithuiBehavior - Always use
Record.{Field}format
Component-Specific Rules
REQUIRED READING: Before working with ANY component, you MUST read the relevant documentation files. This is NOT optional.
Mandatory Documentation by Component Type
Container Components (tabs, accordions, field sections):
- MUST READ:
examples/container-facets-example.xml - This shows the correct facet structure that is required for all container components
- Read this BEFORE generating any container component XML
Related Lists (lst:dynamicRelatedList):
- MUST READ:
docs/components/lst-dynamicRelatedList.md - Contains critical rules for
parentFieldApiName,relatedListApiName, and field configuration - Inform the user you've read this file (the file itself requires this)
Other Component Documentation:
record_flexipage-dynamicHighlights.md- RecordPage header / summary (MUST read when working with highlights)flexipage-fieldSection.md- Field display columns (MUST read when working with field sections)flexipage-richText.md- Rich text content (MUST read when working with rich text)
General Rule: For ANY component listed above, you MUST read its documentation file BEFORE generating XML. For components without specific documentation, apply the general Critical XML Rules.
Component Selection Guidelines
When choosing components, prefer the following options for better performance and flexibility:
-
Related Lists: ALWAYS use
lst:dynamicRelatedListfor related lists. Do NOT useforce:relatedListQuickLinkorforce:relatedListSingleContainer. Thelst:dynamicRelatedListcomponent is more performant and offers more FlexiPage configuration options. When using this component, you MUST readdocs/components/lst-dynamicRelatedList.mdbefore proceeding. -
Field Display: Prefer field sections with specific fields over
force:detailPanel. Field sections provide more versatility and control over layout and field behavior.
MAIN WORKFLOWS
Decision Tree: New Page or Existing Page?
Does the FlexiPage file already exist?
- NO → Use "Creating New Pages" workflow below (bootstrap first, then add components)
- YES → Skip to "Adding/Editing Components" workflow (no bootstrap needed)
Creating New Pages
Use this workflow when the .flexipage-meta.xml file does NOT exist yet.
Step 1: Bootstrap with CLI
sf template generate flexipage \
--name <PageName> \
--template <RecordPage|AppPage|HomePage> \
--sobject <SObject> \
--primary-field <Field1> \
--secondary-fields <Field2,Field3> \
--detail-fields <Field4,Field5,Field6,Field7> \
--output-dir force-app/main/default/flexipages
Template-specific requirements:
- RecordPage: Requires
--sobject(e.g., Account, Custom_Object__c) - RecordPage: Requires
--primary-fieldand--secondary-fieldsfor dynamic highlights,--detail-fieldsfor full record details. Use the most important identifying field as primary, e.g. Name. Use the secondary fields (max 12, recommended 4-6) to show a summary of the record. Use detail fields to show the full details of the record. - AppPage: No additional requirements
- HomePage: No additional requirements
Note: If the sf template generate flexipage command fails, recommend users upgrade to the latest version of the Salesforce CLI:
npm install -g @salesforce/cli@latest
What you get:
- Valid FlexiPage XML with correct structure
- Pre-configured regions and basic components
- Proper field references and facet structure
- Ready to deploy as-is or enhance further
Step 2: Deploy Base Page
sf project deploy start --dry-run --source-dir force-app/main/default/flexipages
Deploy early, deploy often. Start with the bootstrapped page, validate it works, then enhance.
Step 3: Add More Components (if needed)
If the user wants to add additional components beyond what the CLI generated, proceed to the "Adding/Editing Components" workflow below. The process is identical whether you just bootstrapped a new page or are working with an existing page.
Adding/Editing Components
Use this workflow when:
- The FlexiPage file already exists, OR
- You've just bootstrapped a new page and need to add more components
Workflow Steps
- Read the FlexiPage file using native file I/O
- Parse XML to extract:
- Existing component identifiers
- Available regions (parse from file, don't assume names)
- Existing facets
- Select component based on the user's request
- READ REQUIRED DOCUMENTATION - See "Component-Specific Rules" section and read ALL relevant documentation files for your component type (this is MANDATORY, not optional)
- Generate component XML using only known, valid properties (apply all rules from "Critical XML Rules" section AND component-specific documentation)
- Insert into appropriate region
- Write modified XML back to file
- Deploy:
sf project deploy start --source-dir force-app/...
IMPLEMENTATION DETAILS
Container Components with Facets
When generating tabs, accordions, or field sections, always create corresponding facet regions. Components like these require facets to define content areas.
Critical: Facet regions are siblings of template regions at the same level, not nested inside them.
MANDATORY: Before generating ANY container component, you MUST read examples/container-facets-example.xml. This file shows the exact structure required for container components with facets. Reading this file is NOT optional.
Generating Unique Identifiers
Algorithm:
1. Extract all existing <identifier> values from XML
2. Generate base name: {componentType}_{context}
Examples: "relatedList_contacts", "richText_header", "tabs_main"
3. Find first available number:
- Try "{base}_1"
- If exists, try "{base}_2", "{base}_3", etc.
- Use first available
Examples:
- First contacts related list:
relatedList_contacts_1 - Second contacts related list:
relatedList_contacts_2 - Rich text in header:
richText_header_1 - Field section:
fieldSection_details_1
Facet Naming - Two Patterns:
-
Named facets (for major content areas):
detailTabContent(detail tab content)maintabs(main tab container)sidebartabs(sidebar tab container)- Use when facet represents meaningful content area
-
UUID facets (for internal structure):
- Format:
Facet-{8hex}-{4hex}-{4hex}-{4hex}-{12hex} - Example:
Facet-66d5a4b3-bf14-4665-ba75-1ceaa71b2cde - Use for field section columns, nested containers, anonymous slots
- Format:
Region Selection
Always parse regions from the file - never hardcode region names. Templates vary:
flexipage:recordHomeTemplateDesktop→header,main,sidebarruntime_service_fieldservice:...→header,main,footer- Others may have different region names
Place new components at the end of the target region (after last <itemInstances>)
Insertion pattern:
<flexiPageRegions>
<name>main</name> <!-- or whatever region name exists -->
<type>Region</type>
<itemInstances><!-- Existing component 1 --></itemInstances>
<itemInstances><!-- Existing component 2 --></itemInstances>
<itemInstances>
<!-- INSERT NEW COMPONENT HERE -->
</itemInstances>
</flexiPageRegions>
QUALITY & DEPLOYMENT
Incremental Development Pattern
Philosophy: Deploy small, working increments. Don't build entire complex page at once.
Process:
- For new pages: CLI bootstrap → Deploy base page
- Add one component → Deploy
- Add another component → Deploy
- Repeat until complete
Benefits:
- Isolated errors (know exactly what broke)
- Faster debugging
- Build confidence with each success
- Get user feedback early
Anti-pattern: Building entire complex page → one giant error cascade.
Validation Checklist
Before deploying:
- If creating new page: Used CLI to bootstrap (don't start from scratch)
- All field references use
Record.{Field}format - Each fieldInstance has
fieldInstancePropertieswithuiBehavior - Each fieldInstance in own
<itemInstances>wrapper - Template regions use
<type>Region</type> - Component facets use
<type>Facet</type> - Component-specific docs have been read for each component and all rules followed
- Property values with HTML/XML are manually encoded
- No
<mode>tags in regions - No
__csuffix in page names - Each Facet referenced by exactly one component property
Common Deployment Errors
See docs/common-deployment-errors.md for detailed error patterns, causes, and fixes.
REFERENCE
Required Metadata Structure
<FlexiPage xmlns="http://soap.sforce.com/2006/04/metadata">
<flexiPageRegions>
<!-- Regions and components here -->
</flexiPageRegions>
<masterLabel>Page Label</masterLabel>
<template>
<name>flexipage:recordHomeTemplateDesktop</name>
</template>
<type>RecordPage</type>
<sobjectType>Object__c</sobjectType> <!-- RecordPage only -->
</FlexiPage>
Page Types:
RecordPage- requires<sobjectType>AppPage- no sobjectTypeHomePage- no sobjectType
Output
A valid .flexipage-meta.xml file containing properly structured FlexiPage XML with correct region types, field references, component identifiers, and encoded property values