Study guide

12.3 Lightning Web Components Fundamentals

Salesforce Certified Platform Developer I Exam

Track your progress as you read

Finished sections get a check mark.

1 Introduction & Exam Overview

1.1 Current Exam Facts 1.2 Blueprint Weights & Study Strategy

2 Platform Fundamentals

2.1 Multi-Tenant Architecture & Shared Resources 2.2 MVC Mapping on the Lightning Platform 2.3 Declarative vs Programmatic Decisions 2.4 Agentforce for Developers: Use Cases & Limitations

3 Data Modeling & Schema

3.1 Objects, Fields & Schema Design 3.2 Relationship Types & Implications 3.3 Schema Design Impact on Apex 3.4 Data Import & Export for Development

4 Platform Data Features

4.1 Formula Fields & Roll-Up Summaries 4.2 Core CRM Objects & Standard Schema 4.3 AppExchange Extensions & Platform Boundaries

5 Declarative Process Automation

5.1 Record-Triggered Flows & Declarative Automation 5.2 Approval Processes & Business Rules 5.3 When to Use Apex vs Declarative Tools

6 Apex Language Basics

6.1 Variables, Constants & Apex Data Types 6.2 Lists, Sets & Maps 6.3 Control Flow & Exception Handling 6.4 Classes, Interfaces & OOP Patterns

7 SOQL, SOSL & DML

7.1 SOQL Query Fundamentals 7.2 SOSL Search Fundamentals 7.3 DML Operations & Bulkification 7.4 Governor Limits & Transaction Boundaries

8 Apex Triggers & Order of Execution

8.1 Trigger Structure & Context Variables 8.2 Bulk Trigger Patterns & Best Practices 8.3 Save Order of Execution 8.4 Recursion, Cascading & Transaction Control

9 Asynchronous Apex

9.1 @future Methods 9.2 Queueable Apex 9.3 Batch Apex 9.4 Schedulable Apex & Job Orchestration

10 Security, Events & Schema Access

10.1 Sharing, FLS, CRUD & Injection Prevention 10.2 Platform Events Publish & Subscribe 10.3 Programmatic Schema Access (Describe)

11 Visualforce

11.1 Visualforce Pages & Markup 11.2 Standard, Custom Controllers & Extensions 11.3 Visualforce in Lightning Experience

12 Lightning Components

12.1 Lightning Component Framework Benefits 12.2 Aura Component Structure & Resources 12.3 Lightning Web Components Fundamentals 12.4 LWC Data Access: Wire, Imperative & Events

13 UI Composition & Apex Integration Patterns

13.1 Composing UI in Lightning Apps 13.2 UI Security, Performance & Accessibility Patterns 13.3 Apex Actions for Flow, LWC, and Agentforce

14 Apex Testing

14.1 Testing Framework & Coverage Requirements 14.2 Writing Unit Tests for Triggers & Classes 14.3 Test Data Strategies & Isolation 14.4 Executing Tests & Execute Anonymous Differences

15 Debugging & Developer Tools

15.1 Debug Logs & Monitoring 15.2 Developer Console, CLI, VS Code & Workbench 15.3 Sandboxes, Scratch Orgs & Environment Strategy

16 Deployment & Release

16.1 Change Sets & Metadata Deployment 16.2 Unlocked Packages, Metadata API & Salesforce DX 16.3 Release Readiness & Credential Maintenance

12.3 Lightning Web Components Fundamentals

Key Takeaways Explain This Topic AI

An LWC bundle typically includes .html template, .js module, optional .css, and .js-meta.xml configuration

@api exposes public properties; modern LWC reactivity tracks field changes without legacy @track on primitives/objects in most cases; @wire declaratively provisions data

Shadow DOM encapsulates component markup and CSS so styles do not leak in or out by default

Prefer base Lightning components and SLDS patterns for consistent, accessible UI

js-meta.xml controls isExposed, targets (App Builder pages, record pages, utilities), and public property definitions for admins

Last updated: August 2026

12.3 Lightning Web Components Fundamentals

Quick Answer: A Lightning Web Component is a folder with componentName.html , componentName.js , optional componentName.css , and componentName.js-meta.xml . Use @api for public properties, modern reactive fields (and @track only when still required for legacy nested mutation patterns), and @wire for declarative data. Shadow DOM encapsulates DOM/CSS. Expose components to App Builder with isExposed and targets in the meta file. Prefer base Lightning components and SLDS .

This section is the core LWC vocabulary for Platform Developer I User Interface questions. Section 12.4 extends into Apex wire, imperative calls, LDS, and events.

  • LWC File Structure
  • Example bundle accountSummary : accountSummary/
  • accountSummary.html
  • accountSummary.js
  • accountSummary.css
  • accountSummary.js-meta.xml

File Purpose

.html Template markup with directives ( lwc:if , for:each , etc. depending on API version patterns you study) and bindings

  • .js ES module exporting a class extending LightningElement
  • .css Styles scoped to the component via Shadow DOM
  • .js-meta.xml Metadata: API version, exposure, targets, properties

Naming rules matter: the folder name, HTML root tag usage, and JavaScript class naming follow LWC conventions (kebab-case in markup, camelCase class names).

  • HTML template essentials <!-- accountSummary.html -->
  • <template>
  • <lightning-card title={cardTitle}>
  • <div class="slds-p-around_medium">
  • <p>{accountName}</p>
  • <lightning-button label="Refresh" onclick={handleRefresh}></lightning-button>
  • </div>
  • </lightning-card>
  • </template>

Notes:

  • The root is a <template> wrapper
  • Bind properties with {propertyName} (no this. in the template)
  • Bind event handlers with {handlerName}
  • Use base components like lightning-card and lightning-button when possible
  • JavaScript module essentials // accountSummary.js
  • import { LightningElement, api } from 'lwc';
  • export default class AccountSummary extends LightningElement {
  • @api recordId;
  • @api cardTitle = 'Account Summary';

accountName = 'Loading…';

  • handleRefresh() {
  • // imperative logic or refresh wires (see 12.4)
  • }
  • }
  • One default export class extending LightningElement
  • Import decorators and modules from 'lwc' or Lightning platform modules
  • Class fields hold reactive state for the template
  • CSS /* accountSummary.css */
  • :host {
  • display: block;
  • }
  • p {
  • font-weight: 600;
  • }

Styles apply inside the component’s shadow tree. They do not freely style parent page DOM, and outer CSS does not casually restyle your internal elements the way global Visualforce stylesheets often did.

  • Meta configuration ( js-meta.xml ) <?xml version="1.0" encoding="UTF-8"?>
  • <LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
  • <apiVersion>62.0</apiVersion>
  • <isExposed>true</isExposed>
  • <masterLabel>Account Summary</masterLabel>
  • <targets>
  • <target>lightning__RecordPage</target>
  • <target>lightning__AppPage</target>
  • <target>lightning__HomePage</target>
  • </targets>
  • <targetConfigs>
  • <targetConfig targets="lightning__RecordPage">
  • <property name="cardTitle" type="String" label="Card Title" />
  • </targetConfig>
  • </targetConfigs>
  • </LightningComponentBundle>
  • Meta concept Meaning
  • isExposed true makes the component available for selection in supported builders when targets allow
  • targets Where it can be placed (record page, app page, home page, utility bar, Flow screens, etc.)
  • properties App Builder-configurable public inputs (align with @api fields)
  • apiVersion Component API version

Exam trap: A component with perfect JS/HTML but isExposed=false (or missing the right target) will not appear in App Builder for that page type.

  • Decorators and Reactivity
  • @api — public reactive properties

@api marks a field as a public property that parents (or App Builder) can set: import { LightningElement, api } from 'lwc';

  • export default class ChildPanel extends LightningElement {
  • @api heading;
  • @api recordId; // often provided on record pages when configured
  • }
  • Parent markup: <c-child-panel heading="Details" record-id={recordId}></c-child-panel>

HTML attribute names are kebab-case ; JavaScript properties are camelCase ( record-id ↔ recordId ).

Public properties are part of the component’s contract. Prefer @api for inputs; keep internal state on non- @api fields.

Modern reactivity and @track

In modern LWC, class fields used in the template are reactive for reassignment. Historically, @track was required to make objects/arrays deeply reactive. Today:

Reassigning a field ( this.contacts = [...newList] ) triggers rerender

Mutating a nested property in place ( this.contacts[0].Name = 'x' ) may not trigger UI updates unless you use patterns that establish reactivity correctly

@track still appears in older code and some exam materials for tracking mutations on plain objects/arrays

Exam-ready guidance:

  • Prefer immutable updates (spread new objects/arrays) so reactivity is obvious
  • Recognize @track when shown on an object field in legacy snippets

Do not confuse @track (internal reactivity) with @api (public surface) import { LightningElement, track } from 'lwc';

  • export default class FilterPanel extends LightningElement {
  • // Modern style: reassign fields
  • filters = { status: 'Open', ownerId: null };
  • // Legacy-style annotation still seen in materials
  • @track draft = { name: '' };
  • setStatus(status) {
  • this.filters = { ...this.filters, status }; // reactive reassignment
  • }
  • }
  • @wire — declarative data provisioning

@wire connects a property or function to a Lightning data adapter (Apex wire-enabled method, uiRecordApi , and others): import { LightningElement, api, wire } from 'lwc';

  • import { getRecord, getFieldValue } from 'lightning/uiRecordApi';
  • import NAME_FIELD from '@salesforce/schema/Account.Name';
  • export default class AccountSummary extends LightningElement {
  • @api recordId;
  • @wire(getRecord, { recordId: '$recordId', fields: [NAME_FIELD] })
  • account;
  • get accountName() {
  • return getFieldValue(this.account.data, NAME_FIELD);
  • }
  • }

Wire fundamentals:

  • Reactive parameters use '$recordId' syntax so the wire re-fires when recordId changes
  • Wired property receives { data, error } shape
  • Wired function form lets you handle data/error in a method body
  • Section 12.4 covers Apex wire, imperative Apex, and error patterns in depth
  • Other common imports (recognize on sight)
  • Import Role
  • LightningElement Base class
  • api , wire , track Decorators
  • lightning/uiRecordApi LDS-style record access
  • @salesforce/schema/... Compile-time field/object references
  • @salesforce/apex/... Import Apex methods
  • Shadow DOM Encapsulation

LWC renders into Shadow DOM , which:

  • Scopes CSS to the component
  • Hides internal DOM structure from casual external queries
  • Encourages communication via @api and events , not DOM scraping

Implications:

  • Global page CSS should not be your primary styling strategy for component internals
  • Parent components should not rely on querySelector into a child’s private DOM for business logic
  • Use this.template.querySelector inside the component to access its own template elements when needed

Lightning Web Security / Locker-related constraints reinforce isolation between namespace components. Exam language often frames this as encapsulation and security of the component boundary .

Base Lightning Components and SLDS

Base Lightning components ( lightning-* ) wrap SLDS and platform behavior:

  • Inputs: lightning-input , lightning-combobox , lightning-textarea
  • Data: lightning-datatable , lightning-tree-grid

Record UI: lightning-record-form , lightning-record-view-form , lightning-record-edit-form , lightning-input-field

  • Layout/chrome: lightning-card , lightning-layout , lightning-tabset
  • Feedback: lightning-spinner , toast via ShowToastEvent

Why exams prefer them: accessibility hooks, SLDS consistency, less custom CSS, and tighter platform integration (especially record forms with FLS-aware fields).

You may still apply SLDS utility classes in markup ( slds-grid , slds-p-around_medium ) for layout. Prefer utilities + base components over reinventing Salesforce look-and-feel with ad-hoc CSS.

  • Composition and Lifecycle (High-Yield)
  • Nest components as custom elements: <c-child-panel></c-child-panel>
  • Pass data down with @api
  • Send data up with CustomEvent (12.4)

Lifecycle hooks such as connectedCallback , disconnectedCallback , and renderedCallback appear in scenarios about initialization and cleanup—use them carefully ( renderedCallback can run often; avoid infinite loops) connectedCallback() {

  • // runs when component is inserted into the DOM
  • }
  • Common Exam Traps
  • Trap Correction
  • Forgetting js-meta.xml targets Component never shows in App Builder
  • Using @api for private temporary state Use internal fields instead
  • Expecting in-place array mutation to always refresh UI Reassign arrays/objects
  • Styling parent page from component CSS Shadow DOM scopes styles
  • Building custom HTML tables when lightning-datatable fits Prefer base components
  • Confusing Aura v. / c. expressions with LWC {field} bindings Different template languages
  • Minimal End-to-End Picture
  • Author html/js/css/meta bundle
  • Expose with isExposed + targets
  • Accept recordId / config via @api
  • Load data with @wire or imperative Apex (12.4)
  • Render with base components + SLDS utilities
  • Communicate with events and public properties

Bottom line: LWC fundamentals are four key files , decorators ( @api , reactivity/ @track , @wire ) , Shadow DOM encapsulation , base Lightning components + SLDS , and meta.xml exposure/targets . Master these before drilling data access patterns in the next section.