lwc-development

Lightning Web Components Development Guide

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "lwc-development" with this command: npx skills add david-sfdev/claude-sf-skills/david-sfdev-claude-sf-skills-lwc-development

Lightning Web Components Development Guide

Core Principle: Always Use Lightning Namespace Components

CRITICAL: When building Lightning Web Components for Salesforce, ALWAYS use lightning-* namespace components instead of generic HTML elements. This ensures proper Salesforce integration, styling, accessibility, and platform compatibility.

Component Selection Guide

User Input Components

Use This NOT This When

<lightning-input>

<input>

Text fields, numbers, dates, checkboxes, toggles

<lightning-textarea>

<textarea>

Multi-line text input

<lightning-combobox>

<select>

Dropdown selections with search

<lightning-dual-listbox>

<select multiple>

Moving items between lists

<lightning-input-address>

Multiple <input> fields Address entry with validation

<lightning-input-location>

Map/location inputs Geographic location selection

<lightning-slider>

<input type="range">

Numeric range selection

<lightning-radio-group>

<input type="radio">

Radio button groups

<lightning-checkbox-group>

<input type="checkbox">

Checkbox groups

Buttons & Actions

Use This NOT This When

<lightning-button>

<button>

Standard actions, form submissions

<lightning-button-icon>

<button> with icon Icon-only buttons

<lightning-button-menu>

<select> or custom menu Dropdown action menus

<lightning-button-group>

Multiple <button>

Related button groups

Layout & Structure

Use This NOT This When

<lightning-card>

<div> with custom styling Contained content sections

<lightning-layout>

<div> with flexbox Responsive grid layouts

<lightning-layout-item>

<div>

Items within lightning-layout

<lightning-accordion>

Custom collapsible <div>

Expandable/collapsible sections

<lightning-tab> / <lightning-tabset>

Custom tab UI Tabbed interfaces

<lightning-carousel>

Custom slideshow Image carousels

<lightning-tile>

<div>

Compact record display

Data Display

Use This NOT This When

<lightning-datatable>

<table>

Tabular data with sorting/filtering

<lightning-tree>

Nested <ul>

Hierarchical data

<lightning-tree-grid>

Complex nested tables Tree structure with columns

<lightning-formatted-*>

Manual formatting Display formatted values (date, time, currency, etc.)

<lightning-output-field>

<span> or <div>

Display Salesforce field values

<lightning-avatar>

<img> for user photos User profile pictures

<lightning-badge>

<span> with styling Status indicators

<lightning-icon>

SVG or font icons SLDS icons

<lightning-progress-bar>

Custom progress indicators Progress visualization

<lightning-progress-indicator>

Custom step indicators Multi-step processes

Record Interaction

Use This NOT This When

<lightning-record-form>

Custom form with fields Quick record create/edit/view forms

<lightning-record-edit-form>

Manual field inputs Custom record editing with validation

<lightning-record-view-form>

Manual field display Display record fields

<lightning-output-field>

Manual field rendering Display fields in view forms

Navigation & Feedback

Use This NOT This When

<lightning-spinner>

Custom loading animation Loading states

<lightning-pill>

<span> with close button Removable tags/labels

<lightning-helptext>

Custom tooltip Help text/tooltips

<lightning-breadcrumb> / <lightning-breadcrumbs>

Custom breadcrumb trail Navigation hierarchy

Essential LWC Patterns

  1. Component Structure

// componentName.js import { LightningElement, api, track, wire } from 'lwc';

export default class ComponentName extends LightningElement { @api recordId; // Public property @track privateData; // Reactive private property

// Use @wire for reactive data
@wire(wireAdapter, { params })
wiredProperty;

}

  1. Lightning Input Example

CORRECT:

<template> <lightning-card title="User Form"> <div class="slds-p-around_medium"> <lightning-input label="Name" value={name} onchange={handleNameChange}> </lightning-input>

        &#x3C;lightning-input 
            type="email"
            label="Email" 
            value={email}
            required>
        &#x3C;/lightning-input>
        
        &#x3C;lightning-button 
            label="Submit" 
            variant="brand"
            onclick={handleSubmit}>
        &#x3C;/lightning-button>
    &#x3C;/div>
&#x3C;/lightning-card>

</template>

INCORRECT (DO NOT USE):

<!-- WRONG - Don't use generic HTML --> <div class="card"> <input type="text" placeholder="Name" /> <input type="email" placeholder="Email" /> <button>Submit</button> </div>

  1. Lightning Datatable Example

// JavaScript import { LightningElement, wire } from 'lwc'; import getAccounts from '@salesforce/apex/AccountController.getAccounts';

const COLUMNS = [ { label: 'Account Name', fieldName: 'Name', type: 'text' }, { label: 'Industry', fieldName: 'Industry', type: 'text' }, { label: 'Annual Revenue', fieldName: 'AnnualRevenue', type: 'currency' } ];

export default class AccountList extends LightningElement { columns = COLUMNS; @wire(getAccounts) accounts; }

<!-- HTML --> <template> <lightning-card title="Accounts" icon-name="standard:account"> <lightning-datatable key-field="Id" data={accounts.data} columns={columns}> </lightning-datatable> </lightning-card> </template>

  1. Record Forms

Quick Record Form (minimal code):

<lightning-record-form object-api-name="Contact" fields={fields} mode="edit" onsubmit={handleSubmit} onsuccess={handleSuccess}> </lightning-record-form>

Custom Record Edit Form (more control):

<lightning-record-edit-form record-id={recordId} object-api-name="Account"> <lightning-messages></lightning-messages> <lightning-input-field field-name="Name"></lightning-input-field> <lightning-input-field field-name="Industry"></lightning-input-field> <lightning-button type="submit" label="Save"></lightning-button> </lightning-record-edit-form>

Styling with SLDS

Use Salesforce Lightning Design System (SLDS) utility classes instead of custom CSS:

<!-- Use SLDS classes --> <div class="slds-grid slds-wrap"> <div class="slds-col slds-size_1-of-2 slds-p-around_small"> <lightning-input label="First Name"></lightning-input> </div> <div class="slds-col slds-size_1-of-2 slds-p-around_small"> <lightning-input label="Last Name"></lightning-input> </div> </div>

<!-- Common SLDS classes --> <!-- Spacing: slds-p-around_small, slds-m-top_medium --> <!-- Grid: slds-grid, slds-col, slds-size_1-of-2 --> <!-- Text: slds-text-heading_medium, slds-text-align_center -->

Common Anti-Patterns to Avoid

❌ DON'T: Use Ternary Operators in HTML Templates

CRITICAL: LWC templates do NOT support ternary operators or complex JavaScript expressions in HTML.

WRONG:

<!-- WRONG - Ternary operators are not supported in LWC templates --> <div>{isActive ? 'Active' : 'Inactive'}</div> <lightning-input label={isRequired ? 'Required Field' : 'Optional Field'}></lightning-input> <div class={status === 'complete' ? 'green' : 'red'}></div>

CORRECT:

<!-- CORRECT - Use if:true/if:false or getters --> <template if:true={isActive}> <div>Active</div> </template> <template if:false={isActive}> <div>Inactive</div> </template>

<lightning-input label={fieldLabel}></lightning-input> <div class={statusClass}></div>

// JavaScript - Use getters for computed values export default class MyComponent extends LightningElement { isActive = true; isRequired = true; status = 'complete';

get fieldLabel() {
    return this.isRequired ? 'Required Field' : 'Optional Field';
}

get statusClass() {
    return this.status === 'complete' ? 'green' : 'red';
}

}

❌ DON'T: Use Generic HTML Elements

<!-- WRONG --> <input type="text" /> <button onclick={handleClick}>Click</button> <select><option>Item</option></select>

✅ DO: Use Lightning Components

<!-- CORRECT --> <lightning-input></lightning-input> <lightning-button onclick={handleClick} label="Click"></lightning-button> <lightning-combobox options={options}></lightning-combobox>

❌ DON'T: Manual Form Validation

// WRONG - manual validation if (!this.template.querySelector('input').value) { alert('Required field'); }

✅ DO: Use Built-in Validation

// CORRECT - use reportValidity() const allValid = [...this.template.querySelectorAll('lightning-input')] .reduce((validSoFar, inputCmp) => { inputCmp.reportValidity(); return validSoFar && inputCmp.checkValidity(); }, true);

❌ DON'T: Direct DOM Manipulation

// WRONG this.template.querySelector('div').innerHTML = 'Text';

✅ DO: Use Reactive Properties

// CORRECT @track displayText = 'Text';

Component Communication

Parent to Child

// Parent passes data via public property <c-child-component record-id={recordId}></c-child-component>

// Child receives via @api export default class ChildComponent extends LightningElement { @api recordId; }

Child to Parent

// Child dispatches event this.dispatchEvent(new CustomEvent('select', { detail: { recordId: this.recordId } }));

// Parent handles event <c-child-component onselect={handleSelect}></c-child-component>

Lightning Data Service (LDS)

Use LDS for automatic data caching and synchronization:

import { LightningElement, wire, api } from 'lwc'; import { getRecord } from 'lightning/uiRecordApi';

const FIELDS = ['Account.Name', 'Account.Industry'];

export default class AccountDetail extends LightningElement { @api recordId;

@wire(getRecord, { recordId: '$recordId', fields: FIELDS })
account;

}

Navigation

import { NavigationMixin } from 'lightning/navigation';

export default class MyComponent extends NavigationMixin(LightningElement) { navigateToRecord() { this[NavigationMixin.Navigate]({ type: 'standard__recordPage', attributes: { recordId: this.recordId, actionName: 'view' } }); } }

Key Reminders

  • ALWAYS use lightning-* components - Never use generic HTML form elements

  • Use SLDS classes for styling - Avoid custom CSS when possible

  • Leverage LDS for data operations - Built-in caching and sync

  • Use @wire for reactive data - Automatic re-rendering

  • Report validity - Use built-in validation methods

  • Import only what you need - Keep bundle size small

  • Follow naming conventions - camelCase for properties, kebab-case for HTML attributes

  • Test with Salesforce data - Component behavior may differ with real records

File Structure

lwcComponentName/ ├── lwcComponentName.html # Template ├── lwcComponentName.js # JavaScript controller ├── lwcComponentName.js-meta.xml # Configuration └── lwcComponentName.css # Styles (optional)

Metadata Configuration (.js-meta.xml)

<?xml version="1.0" encoding="UTF-8"?> <LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata"> <apiVersion>60.0</apiVersion> <isExposed>true</isExposed> <targets> <target>lightning__AppPage</target> <target>lightning__RecordPage</target> <target>lightning__HomePage</target> </targets> <targetConfigs> <targetConfig targets="lightning__RecordPage"> <objects> <object>Account</object> <object>Contact</object> </objects> </targetConfig> </targetConfigs> </LightningComponentBundle>

Quick Reference: Most Common Components

Forms & Input:

  • lightning-input

  • Text, email, number, date, checkbox, toggle

  • lightning-textarea

  • Multi-line text

  • lightning-combobox

  • Searchable dropdown

  • lightning-button

  • Actions and submissions

Layout:

  • lightning-card

  • Content container

  • lightning-layout

  • lightning-layout-item
  • Responsive grid

  • lightning-accordion

  • Collapsible sections

Data Display:

  • lightning-datatable

  • Tables with sorting/selection

  • lightning-formatted-*

  • Display formatted values

  • lightning-icon

  • SLDS icons

Record Operations:

  • lightning-record-form

  • Quick create/edit/view

  • lightning-record-edit-form

  • Custom edit forms

  • lightning-record-view-form

  • Display records

Feedback:

  • lightning-spinner

  • Loading indicator

  • lightning-messages

  • Form validation messages

Remember: When in doubt, search for "lightning-" + functionality in the Salesforce Component Library. The lightning namespace has a component for almost everything!

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

sf-cli-deployment

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

apex-development

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

HTML to Markdown

Convert HTML↔Markdown for web clipping, clean notes, and batch content migration. Use when users ask 网页转Markdown/Markdown转HTML/批量转换. Supports local files, UR...

Registry SourceRecently Updated
Coding

Podfetcher Tools

Search podcasts, browse episodes, and fetch podcast transcripts from Podfetcher using the bundled Node.js CLI, SDK, or MCP server.

Registry SourceRecently Updated