Loading...
Loading...
Quality standards for Salesforce Lightning Web Components (LWC), Aura components, and Visualforce pages. Covers SLDS 2 compliance, accessibility (WCAG 2.1 AA), data access pattern selection, component communication rules, XSS prevention, CSRF enforcement, FLS/CRUD in AuraEnabled methods, view state management, and Jest test requirements. Use this skill when building or reviewing any Salesforce UI component to enforce platform-specific security and quality standards.
npx skill4agent add github/awesome-copilot salesforce-component-standards| Use case | Pattern | Why |
|---|---|---|
| Read a single record reactively (follows navigation) | | Lightning Data Service — cached, reactive |
| Standard CRUD form for a single object | | Built-in FLS, CRUD, and accessibility |
| Complex server query or filtered list | | Allows caching; wire re-fires on param change |
| User-triggered action, DML, or non-cacheable server call | Imperative | Required for DML — wired methods cannot be |
| Cross-component communication (no shared parent) | Lightning Message Service (LMS) | Decoupled, works across DOM boundaries |
| Multi-object graph relationships | GraphQL | Single round-trip for complex related data |
| Rule | Enforcement |
|---|---|
No raw user data in | Use |
Apex | Use |
| No hardcoded org-specific IDs in component JavaScript | Query or pass as a prop — never embed record IDs in source |
| A parent can pass anything — validate type and range before using as a query parameter |
color: #FF3366color: var(--slds-c-button-brand-color-background)!important<lightning-*>lightning-buttonlightning-inputlightning-datatablelightning-card<label>aria-labelalternative-textaria-labelaria-*aria-describedby| Direction | Mechanism |
|---|---|
| Parent → Child | |
| Child → Parent | |
| Sibling / unrelated components | Lightning Message Service (LMS) |
| Never use | |
bubbles: truecomposed: true@api valueconnectedCallbackrenderedCallbackrenderedCallback// Minimum test coverage expectations
it('renders the component with correct title', async () => { ... });
it('calls apex method and displays results', async () => { ... }); // Wire mock
it('dispatches event when button is clicked', async () => { ... });
it('shows error state when apex call fails', async () => { ... }); // Error path@salesforce/sfdx-lwc-jestwiresetImmediateemit({ data, error })jest.mock('@salesforce/apex/MyClass.myMethod', ...)force:appPage@AuraEnabledwith sharing{!v.something}<div><ui:outputText value="{!v.text}" /><c:something><!-- ❌ NEVER — renders raw user input as HTML -->
<apex:outputText value="{!userInput}" escape="false" />
<!-- ✅ ALWAYS — auto-escaping on -->
<apex:outputText value="{!userInput}" />
<!-- Default escape="true" — platform HTML-encodes the output -->escape="false"<apex:form><form method="POST">// ❌ NEVER
String soql = 'SELECT Id FROM Account WHERE Name = \'' + ApexPages.currentPage().getParameters().get('name') + '\'';
List<Account> results = Database.query(soql);
// ✅ ALWAYS — bind variable
String nameParam = ApexPages.currentPage().getParameters().get('name');
List<Account> results = [SELECT Id FROM Account WHERE Name = :nameParam];transientreadonly="true"<apex:page>// Before reading a field
if (!Schema.sObjectType.Account.fields.Revenue__c.isAccessible()) {
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'You do not have access to this field.'));
return null;
}
// Before performing DML
if (!Schema.sObjectType.Account.isDeletable()) {
throw new System.NoAccessException();
}| Anti-pattern | Technology | Risk | Fix |
|---|---|---|---|
| LWC | XSS | Use template bindings |
| Hardcoded hex colours | LWC/Aura | Dark-mode / SLDS 2 break | Use SLDS CSS custom properties |
Missing | LWC/Aura/VF | Accessibility failure | Add |
No guard in | LWC | Infinite rerender loop | Add |
| Application event for parent-child | Aura | Unnecessary broadcast scope | Use component event instead |
| Visualforce | XSS | Remove — use default escaping |
Raw | Visualforce | CSRF vulnerability | Use |
No | VF / Apex | Data exposure | Add |
| FLS not checked in custom controller | VF / Apex | Privilege escalation | Add |
| SOQL concatenated with URL param | VF / Apex | SOQL injection | Use bind variables |