Instruction file imported from salesforce-misc/NZC-USEEIOMatchingAgent (
.cursor/rules/lwc-best-practices.mdc). Copyright stays with the author.
description: LWC coding standards and best practices for modern Salesforce development. globs: /*.js,/.html,**/.css author: emy.paulson@salesforce.com tags: lwc, components, best-practices
LWC Best Practices
Naming Conventions
- Use PascalCase for component class names and folder names (e.g.,
AccountDetails,AccountDetails.js) - Use camelCase for variables, methods, and tracked properties
- Name custom events clearly with actions (e.g.,
recordSaved,userSelected) - Add suffixes like
Modal,Form, orListto describe the component’s role
Project Structure
- Follow this folder layout:
modules/namespace/componentName/componentName.js-meta.xmlcomponentName.jscomponentName.htmlcomponentName.css__tests__/componentName.test.js
Code Organization
- Use Lightning base components whenever possible instead of building custom ones.
- Add smart comments only when needed:
- Don’t comment on what the code does—write self-explanatory code instead
- Use comments to explain why something is done a certain way
- Document complex logic, APIs, and edge cases that aren’t obvious
- Break large methods into smaller, focused functions
- Use helper modules for reusable logic
- Organize
.js,.html, and.cssin the same folder per component - Comment major sections and lifecycle hooks for clarity
- Prefer multiple small components over one large one
Functions & Reactivity
- Use
async/awaitfor better readability and handling - Check for
nullorundefinedin logic to avoid crashes - Use
@apionly for properties/methods that should be accessed from outside - Use
@wirefor reactive data and handle errors safely - Reassign entire objects to trigger reactivity (e.g.,
this.obj = { ...this.obj })
Lightning UI Record API
- Prefer the
lightning/uiRecordApimodule (getRecord,getRecords,createRecord,updateRecord,deleteRecord) for CRUD so you automatically get field-level security, sharing, and caching benefits. - Always import field schemas (e.g.,
import NAME_FIELD from '@salesforce/schema/Account.Name';) and pass only the exact fields you need togetRecord/getRecordsto reduce payload size and avoid stale data. - When using
getRecord, derive values viagetFieldValue(record, FIELD)orgetFieldDisplayValueinstead of traversingrecord.fieldsmanually; these helpers normalize null checks and localization. - For create/update flows, build a
recordInputwithfields: { FieldApiName: value }, then callcreateRecord(recordInput)orupdateRecord(recordInput)and wrap intry/catchto surface errors withShowToastEvent. - Use
notifyRecordUpdateAvailable([{recordId}])orrefreshApexafter imperative mutations so wired adapters stay in sync. - Handle wire adapter
errorobjects explicitly (checkerror.body.messageorerror.body.output.errors) and surface user-friendly toasts while logging details for debugging. - When deleting records, guard user actions with confirmation UI and call
deleteRecord(recordId)insidetry/catchwith optimistic UI updates rolled back if the promise rejects.
Styling & SLDS
- Use SLDS utility classes for layout and spacing
- Avoid inline styles; use the component’s CSS file
- Use SLDS design tokens for spacing and colors (avoid hardcoded values)
- Add accessibility-related classes and ARIA attributes when needed
- When adding custom styles, do not use SLDS utility classes. Instead, define and use your own CSS classes as needed.
Error Handling
- Handle wire service errors using the
errorparameter - Use
try/catchin async logic, and check error types withinstanceof - Show error messages using
ShowToastEvent - Always handle promise rejections and edge cases in logic
Security
- Don’t use
innerHTML,eval(), or direct DOM access (e.g.,document,window) - Never store sensitive data in
localStorageorsessionStorage - Validate all
@apiinputs and message payloads
Communication Between Components
- Use Lightning Message Service (LMS) for communication between unrelated components
- Validate message content before sending or processing
Accessibility
- Use
aria-label,aria-labelledby, andaria-describedbyfor assistive tech support - Add
tabindexwhere keyboard navigation is needed - Include descriptive
titleorlabelfor screen readers - Use semantic HTML (e.g.,
<ul>,<button>,<fieldset>) to improve clarity
Testing
- Aim for over 85% code coverage in tests
- Write Jest tests for public methods and different UI states
- Mock wire calls in tests
- Follow a clear structure: Arrange → Act → Assert
- Test for errors, loading states, and edge cases
- Check rendered DOM elements and triggered events
- Do not assert on component properties (internal or public) in tests. Always verify component behavior by checking the rendered DOM elements, their attributes, text content, and emitted events.