User Interface PD1 · Section 3 · 25% of exam

Overview

User Interface is ~25% of PD1 — nearly as heavy as Process Automation & Logic. The exam expects you to know why LWC is preferred, the MVC mapping, SLDS, security models, and — heaviest of all — LWC decorators, lifecycle hooks, and template directives.

LWCPreferred for new dev
SLDSPreferred styling
LWSPreferred security
3Required LWC files

Exam checklist

  • MVC mapping · Visualforce vs Aura vs LWC (know the comparison table cold)
  • SLDS & Base Components · Shadow DOM · Locker Service vs Lightning Web Security
  • LWC required files (HTML/JS/meta.xml) · @api/@wire/@track decorators
  • Lifecycle hook order · lwc:if / for:each / key · Wire vs Imperative
  • Data access hierarchy (LDS → UI API → Apex) · @AuraEnabled(cacheable=true) · refreshApex()
  • Communication: @api (parent→child), Custom Events (child→parent), LMS (sibling/cross-tech)
  • Visualforce controllers (Standard/Custom/Extension) · View State · transient
  • Aura bundle files (.cmp/Controller/Helper/Renderer) · Component Events vs Application Events · Aura-to-LWC migration
  • Security layers (record/object/field/UI) · with sharing vs WITH USER_MODE vs stripInaccessible() · LWS vs Locker
Top trapsAura is not recommended for new development (LWC is) · Visualforce is not deprecated, just legacy · renderedCallback() can run multiple times (watch infinite loops) · component root must be <template> · LWC uses one-way binding, not two-way · Wire Apex requires cacheable=true · child cannot modify parent directly (use Custom Events) · LMS works across LWC/Aura/Visualforce, not just LWC · Aura Component Events are for containment hierarchy only, Application Events broadcast app-wide · Aura and LWC can coexist · with sharing controls record visibility only, not CRUD/FLS · stripInaccessible() is not just for DML.

Part 1 — UI Fundamentals

Salesforce's UI stack evolved Visualforce → Aura → LWC. All three are still supported, but the exam consistently rewards choosing LWC.

Architecture & MVC

UserBrowserLightning FrameworkUI API / ApexDatabase

The browser never talks to the database directly — everything routes through Salesforce Platform APIs.

MVC layerExamples
ModelObjects, fields, database (Account, Contact, Custom Objects/Metadata)
ViewLWC, Aura, Visualforce, Lightning Record Page
ControllerApex, JavaScript controller, Wire adapters

Visualforce vs Aura vs LWC Memorize

FeatureVisualforceAuraLWC
ModernNoMediumYes
PerformanceLowGoodExcellent
Web StandardsNoPartialYes
Server RenderingYesNoNo
Recommended forLegacyExisting appsNew apps
Decision ruleNeed new UI → LWC. Maintaining existing Aura → Aura. Existing VF page → Visualforce. PD1's answer is almost always LWC.

SLDS — Salesforce Lightning Design System

  • Official CSS framework: buttons, cards, forms, icons, tables, spacing, typography, grid.
  • Gives consistent look, accessibility, responsiveness, and branding — with no custom CSS required.
<!-- Instead of -->
<button>Save</button>

<!-- Use (SLDS applied automatically) -->
<lightning-button label="Save"></lightning-button>

Shadow DOM

  • Each LWC gets its own isolated DOM — CSS from one component cannot leak into another.
  • Benefits: CSS isolation, no style conflicts, better performance, encapsulation.

Security: Locker Service vs Lightning Web Security (LWS)

Locker ServiceLightning Web Security
AgeOlderNewer
RestrictivenessMore restrictiveBetter compatibility
PerformanceBetter
Salesforce recommends✔ Preferred

Both aim to prevent XSS, unsafe DOM access, unsafe JavaScript, and cross-component attacks. CSP (Content Security Policy) additionally restricts external/inline scripts.

Accessibility

  • Keyboard navigation, screen readers, color contrast, labels, ARIA support, focus management.
  • Best practice: always provide labels, don't rely on color alone, meaningful alt text, proper headings.
  • aria-label, aria-hidden, aria-expanded — know purpose only.

Responsive & performance

  • Use lightning-layout instead of HTML tables — responsive, clean, reusable.
  • Salesforce encourages mobile-first design.
  • Performance: lazy loading, reuse components, minimize SOQL, use Lightning Data Service & Wire Service, prefer Base Components.

Base Components & declarative-first

  • Always prefer lightning-* Base Components over custom HTML — already tested, SLDS-ready, accessible, responsive, less code.
  • Declarative first: App Builder, Dynamic Forms, Record Pages, Flow Screens beat hand-written LWC/Apex when they can do the job.
NeedUse
Simple record pageLightning App Builder
Reusable custom UILWC
Standard CRUDlightning-record-form
Complete custom interfaceLWC + Apex
Trap bustersVisualforce is not deprecated (still supported) · Shadow DOM does not allow global CSS (isolation) · SLDS is technically optional but strongly recommended · custom HTML is not preferred over Base Components · Locker Service is not the latest security model (LWS is).

Part 2 — Lightning Web Components Basics

LWC is built on native web standards — Custom Elements, ES6 classes, Shadow DOM, and Modules — not a proprietary framework like Aura.

Component structure 3 required files

Only HTML, JS, and meta XML are mandatory — CSS is optional.

helloWorld/
├── helloWorld.html
├── helloWorld.js
├── helloWorld.js-meta.xml
└── helloWorld.css   (optional)

HTML file

Root element must be <template> — a div root is a common trap.

<template>
    <lightning-card title="Welcome">
        Hello World
    </lightning-card>
</template>

JavaScript file

Every component extends LightningElement.

import { LightningElement } from 'lwc';

export default class HelloWorld extends LightningElement {
}

Meta XML file

Controls exposure, targets, API version, and capabilities.

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>62.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>
  • isExposed = true → component visible; false → hidden.
  • Common targets: lightning__AppPage, lightning__RecordPage, lightning__HomePage, lightning__FlowScreen, lightning__Tab, lightning__UtilityBar.

Decorators High-yield — know all three

DecoratorPurposeBehavior
@apiPublic properties & methodsParent → child communication; parent can read/call it
@wireReactive Salesforce dataAutomatic, read-only, cached, refreshes on reactive param change
@trackLegacy reactivityHistorically needed for object/array mutations — mostly unnecessary today; primitives are reactive by default
import { api } from 'lwc';
@api recordId;

@api
refresh() { }          // callable by parent

@wire(getRecord, { recordId: '$recordId', fields: FIELDS })
account;
Wire vs ImperativeNeed a button click / manual control → Imperative. Need automatic loading + caching → Wire.

Reactivity rule

Changing a property re-renders the component automatically — but you must reference it via this.

// Wrong
count++;

// Correct
this.count++;

Lifecycle hooks Memorize the order

constructor()connectedCallback()render()renderedCallback()disconnectedCallback()errorCallback()
HookRuns whenGood for
constructor()First, on creationInitialize variables — cannot access DOM
connectedCallback()Inserted into DOMCall Apex, init data, navigation, subscriptions
renderedCallback()After every render (can run multiple times)Post-render logic — watch for infinite loops
disconnectedCallback()Component removedCleanup: remove listeners, unsubscribe LMS, clear timers
errorCallback()Child component throwsGraceful error handling (rarely tested)
Infinite-loop trapMutating reactive data inside renderedCallback() triggers a re-render → calls renderedCallback() again → infinite loop. Classic exam scenario.

Template directives

PD1 uses current syntax lwc:if (not the older if:true).

<template lwc:if={show}>
    Visible
</template>

<template for:each={accounts} for:item="acc">
    <p key={acc.Id}>{acc.Name}</p>
</template>

Every repeated item needs a unique key (usually Id) for render performance.

Getters, setters & querying

get fullName() {
    return this.first + ' ' + this.last;
}
// HTML: {fullName}  — no parentheses

@api
set record(value) { this._record = value; }
get record() { return this._record; }

this.template.querySelector('.foo');  // scoped to component

Static resources & custom labels

import logo from '@salesforce/resourceUrl/logo';
import LABEL from '@salesforce/label/c.MyLabel';

Custom Labels support translation — exam favorite.

Naming rules

  • Folder name = camelCase (e.g. accountCard)
  • HTML tag = kebab-case with c- prefix: <c-account-card>

Component communication overview

DirectionMechanism
Parent → Child@api property
Child → ParentCustom Events
Sibling / unrelatedLightning Message Service (LMS)

Navigation uses NavigationMixin, not window.location. Always prefer Base Components (lightning-input, lightning-datatable, lightning-record-form, etc.) over custom markup.

Trap bustersCSS is optional, not required · renderedCallback can run many times · constructor() cannot access the DOM · a parent needs @api to read a child's property · @wire is automatic, not imperative · HTML root must be <template>, never a div · LWC uses one-way binding · querySelector only searches the component's own template (Shadow DOM).

Part 3 — LWC Data Access

Most LWCs exist to display or modify data. Salesforce has a strict preference order, and Wire vs Imperative vs Cacheable Apex is one of the most exam-tested distinctions in this section.

Data access hierarchy Exam favorite

Lightning Data ServiceUI APIApex

Salesforce prefers declarative/standard solutions first — reach for Apex only when LDS/UI API can't do the job.

Lightning Data Service (LDS)

  • Access records without writing Apex. Automatically respects CRUD, FLS, and sharing.
  • Benefits: caching, automatic updates, better performance, less code.
  • Components built on LDS: lightning-record-form, lightning-record-view-form, lightning-record-edit-form.
<lightning-record-form
    record-id={recordId}
    object-api-name="Account"
    layout-type="Full"
    mode="view">
</lightning-record-form>

Record form comparison

ComponentBehavior
lightning-record-formFastest, all-in-one create/edit/view, least customization
lightning-record-view-formRead-only, more customization
lightning-record-edit-formCustom editable layout, most control, supports custom buttons

Wire adapters Know all four

AdapterRetrieves
getRecordRecord field data
getObjectInfoObject metadata — fields, record types, labels
getPicklistValuesPicklist values for one field + record type
getPicklistValuesByRecordTypeALL picklists for a record type (large forms)
import { getRecord, getFieldValue } from 'lightning/uiRecordApi';

@wire(getRecord, { recordId: '$recordId', fields: [NAME_FIELD] })
account;

// preferred way to read a field:
get name() {
    return getFieldValue(this.account.data, NAME_FIELD);
}
TrapDon't read account.Name directly — use account.data.fields.Name.value or, preferably, getFieldValue().

Wire: property vs function style

  • Property style — simple, just assigns to a property.
  • Function style — use when you need custom processing; gives access to both result.data and result.error in one place.
@wire(getRecord, {...})
wiredAccount(result) {
    if (result.data) { /* ... */ }
    if (result.error) { /* ... */ }
}

'$recordId' (with $) marks a reactive parameter — when it changes, the wire re-runs.

Wire vs Imperative

WireImperative
AutomaticManual
ReactiveNot reactive
Read dataRead/write
CachedDepends
SimplerMore control

Use imperative for button clicks, manual refresh, complex logic, or DML.

Cacheable Apex High-yield rule

@AuraEnabled(cacheable=true)
public static List<Account> getAccounts() {
    return [SELECT Id, Name FROM Account];
}
  • Wire Apex requires cacheable=true — without it, the wire fails.
  • Cacheable methods must be read-only — DML inside a cacheable method is never allowed.
  • Imperative Apex calls don't need cacheable=true (though marking read-only methods cacheable is still good practice for client caching).
import getAccounts from '@salesforce/apex/AccountController.getAccounts';

getAccounts()
    .then(result => { /* ... */ })
    .catch(error => { /* ... */ });

refreshApex()

  • Wire data is cached — after a DML (create/update/delete) call refreshApex() to force fresh data.
import { refreshApex } from '@salesforce/apex';
refreshApex(this.wiredResult);

Security: LDS vs Apex

  • LDS automatically respects CRUD, FLS, and sharing.
  • Apex is NOT automatic — the developer must enforce security via WITH USER_MODE, stripInaccessible(), or Describe methods.

User feedback: toasts & spinners

import { ShowToastEvent } from 'lightning/platformShowToastEvent';

this.dispatchEvent(new ShowToastEvent({
    title: 'Success',
    message: 'Saved',
    variant: 'success'   // success | error | warning | info
}));

Use <lightning-spinner> with an isLoading flag while data loads, and handle onsuccess/onerror on record forms plus .then()/.catch() on imperative calls.

Scenario → answer

NeedUse
Simple Account pagelightning-record-form
Custom save buttonlightning-record-edit-form
Record metadatagetObjectInfo
Picklist valuesgetPicklistValues
Button-triggered queryImperative Apex
Automatic record loadingWire
Cache refresh after DMLrefreshApex()
Standard CRUDLDS
Trap bustersWire cannot perform DML (read-only) · cacheable Apex cannot insert records · Apex does not automatically enforce FLS · LDS needs no Apex · Imperative Apex is not reactive · refreshApex() does not perform DML, it refreshes cache · Wire Apex fails without cacheable=true.

Part 4 — LWC Communication

Components rarely work alone. Which mechanism to use depends entirely on the relationship between the two components.

Communication decision table Memorize

RelationshipMechanism
Parent → Child@api (property or method)
Child → ParentCustom Event
Sibling / unrelatedLightning Message Service (LMS)
LWC ↔ Aura, LWC ↔ VisualforceLightning Message Service (LMS)

Parent → Child

Uses @api — the most common communication method. A parent can set a public property or call a public method.

// Child
export default class Child extends LightningElement {
    @api recordId;
    @api refresh() { /* ... */ }
}

// Parent template
<c-child record-id={recordId}></c-child>

// Parent JS — calling a public method
const child = this.template.querySelector('c-child');
child.refresh();

Child → Parent

A child cannot directly modify its parent. It dispatches a Custom Event; the parent listens and decides.

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

// Parent listens (lowercase, "on" + event name)
<c-child onselected={handleSelected}></c-child>

handleSelected(event) {
    const id = event.detail;   // data always in .detail
}
TrapEvent names are always lowercase (selectedonselected), never camelCase like onSelected.

Event options

OptionPurpose
detailCarries the data payload
bubblesAllows the event to travel upward (default false)
composedAllows the event to cross the Shadow DOM boundary
cancelableLets a listener prevent the default action
new CustomEvent('selected', {
    detail: data,
    bubbles: true,
    composed: true,
    cancelable: true
});

event.stopPropagation() stops bubbling; event.preventDefault() prevents the default action — know the difference.

Lightning Message Service (LMS) Recommended

PublisherMessage ChannelSubscriber

Modern messaging framework — works across LWC, Aura, Visualforce, Utility Bar, and Console with no parent-child relationship required.

// Publish
publish(messageContext, MESSAGE_CHANNEL, { recordId: this.recordId });

// Subscribe
subscribe(messageContext, MESSAGE_CHANNEL, (message) => {
    const id = message.recordId;
});
CriticalAlways unsubscribe inside disconnectedCallback() to avoid memory leaks. Message channels are defined as *.messageChannel-meta.xml metadata.

LMS vs Pub/Sub

LMSPub/Sub
Official, cross-technologyLegacy
RecommendedLWC only, older projects

Slots & composition

<!-- Child -->
<slot></slot>

<!-- Parent -->
<c-card>
    <p>Hello</p>
</c-card>

<!-- Named slot -->
<slot name="footer"></slot>
<div slot="footer">Save</div>

Salesforce prefers composition (many small components) over inheritance (extending a class) — rare in LWC.

Querying children

this.template.querySelector('c-child');     // first match
this.template.querySelectorAll('c-child');  // NodeList of all matches

const child = this.template.querySelector('c-child');
child.recordId;   // must be @api
child.refresh();  // must be @api
Trap bustersA parent cannot read a child's private property or call a private method — both need @api · a child cannot directly change a parent's variable (use a Custom Event) · LMS is not LWC-only · Pub/Sub is not the current recommendation · event data lives in event.detail, never event.value · forgetting to unsubscribe from LMS is a real memory-leak risk.

Part 5 — Visualforce

Visualforce is Salesforce's original server-side UI framework — legacy but still fully supported, widely used in existing orgs, and still tested on PD1.

Architecture

BrowserVisualforce PageControllerDatabaseHTML Response

Unlike LWC, rendering happens primarily server-side. Pages use the .page extension and <apex:...> components.

<apex:page>
    Hello World
</apex:page>

Controllers Know the comparison cold

TypeBehavior
Standard ControllerAutomatic CRUD, navigation, validation, security — no Apex needed
Custom ControllerDeveloper writes the entire controller — complete control, no automatic CRUD/security
Controller ExtensionAdds custom logic on top of the Standard Controller — best of both
<apex:page standardController="Account"></apex:page>

<apex:page controller="AccountController"></apex:page>

<apex:page standardController="Account"
           extensions="AccountExtension"></apex:page>
TrapAn Extension does not replace the Standard Controller — it extends it. Need standard save plus extra logic → use an Extension, not a full Custom Controller.

Common components

  • apex:form — required for any input/button to submit
  • apex:pageBlock / apex:pageBlockSection — Salesforce-styled sections
  • apex:inputField vs apex:outputField — editable vs read-only, both metadata-aware
  • apex:commandButton / apex:commandLink — submit actions
  • apex:repeat / apex:dataTable — loops and tables
  • apex:pageMessages — shows errors, warnings, success, and info

inputField vs inputText

inputFieldinputText
Salesforce field — validation, picklists, FLS automaticPlain text, no metadata awareness
<apex:inputField value="{!Account.Name}"/>
<apex:outputField value="{!Account.Name}"/>
<apex:commandButton value="Save" action="{!save}"/>
<apex:pageMessages/>

View State Exam favorite

  • Stores page state between requests: field values, component state, controller variables, selections.
  • Large View State → slow page → poor performance. Salesforce's practical limit is ~170 KB.
  • Use transient to exclude a variable from View State — reduces size, improves performance.
transient List<Account> accounts;
TrapView State does not store database records permanently — it's temporary page memory. transient reduces View State, it doesn't increase it.

Misc features

  • Expressions: {!Account.Name}, {!message}
  • Static resources: {!$Resource.logo}
  • PDF rendering: <apex:page renderAs="pdf"> (LWC has no native PDF equivalent)
  • URL params: ApexPages.currentPage().getParameters().get('id')

Security

  • Standard Controller automatically respects sharing, CRUD, and FLS.
  • Custom Controller — developer is responsible for enforcing all security.

Visualforce vs Aura vs LWC

FeatureVisualforceAuraLWC
RenderingServer-sideClient-sideClient-side
Web StandardsNoPartialYes
PerformanceLowestBetterBest
MobileLimitedGoodExcellent
PDF supportYesNoNo (native)
Standard ControllersYesNoNo
Recommended for new devNo — legacyExisting appsYes
Trap bustersVisualforce is not deprecated · a Custom Controller does not automatically provide CRUD (developer writes it) · only inputField respects picklists, not inputText · pageMessages shows more than just errors (also warnings/success/info).

Part 6 — Aura Components

Aura is Salesforce's older Lightning framework — still supported, still common in existing orgs, and still tested via legacy/migration scenarios. LWC remains the answer for new development.

PD1 answer rule Decision shortcut

Question phrasingAnswer
"new custom UI"LWC
"existing Aura component"Aura
"migration from Aura to modern framework"LWC migration

Aura component bundle

Resources are auto-wired by naming convention — not every file is required, but the bundle concept matters.

myComponent/
├── myComponent.cmp
├── myComponentController.js
├── myComponentHelper.js
├── myComponentRenderer.js
├── myComponent.css
├── myComponent.auradoc
├── myComponent.design
└── myComponent.svg

Core files

FilePurpose
.cmpComponent markup — defines UI & attributes
Controller.jsClient-side event entry point (most commonly used)
Helper.jsShared/reusable logic — callable from controller or renderer
Renderer.jsCustom rendering behavior (rarely needed)
One-linerController = event entry point · Helper = shared logic · Renderer = rendering customization.

Component attributes

Attributes hold component state, referenced with the v. value provider — a frequent exam clue.

<aura:component>
    <aura:attribute name="message" type="String" default="Hello"/>
    {!v.message}
</aura:component>

Aura events High-yield

Event typeScope
Component EventHandled by the firing component or one in its containment hierarchy (supports capture & bubble)
Application EventPublish-subscribe, app-wide — every component with a registered handler is notified, regardless of hierarchy
PD1 ruleParent-child containment → Component Event. Broadcast across the app / unrelated components → Application Event. When the question compares to modern LWC cross-technology communication, the answer is Lightning Message Service.

Common Aura tags to recognize

TagPurpose
aura:componentRoot tag for Aura markup
aura:attributeDeclares component state
aura:handlerHandles an event
aura:registerEventRegisters an event the component can fire
aura:applicationEventDeclares an application-wide event type

Design resources & base components

  • A design resource exposes attributes to builder tools (Lightning App Builder, Experience Builder, Flow Builder) — a classic Aura-vs-LWC clue.
  • Salesforce still prefers standard Base Components and SLDS-backed UI over custom raw markup, regardless of framework.

Coexistence & migration

  • Aura and LWC can coexist in the same application — Salesforce documents this explicitly.
  • Modernization direction: move existing Aura toward LWC over time; new development always targets LWC.
  • Developer Console still works with Aura, but modern tooling (Code Builder, VS Code) is the strategic direction.

Aura vs LWC comparison

TopicAuraLWC
StatusLegacy but supportedPreferred for new dev
Programming modelAura frameworkWeb standards
Event modelComponent / Application eventsCustom Events / LMS
Best useExisting appsNew UI
Migration directionMove away over timeTarget framework
Trap bustersAura is not recommended for new development · Aura is not fully deprecated (still supported) · Application Events are not limited to parent-child (they broadcast app-wide) · Component Events are not for unrelated components anywhere (containment hierarchy only) · Aura and LWC can coexist in the same app.

Part 7 — UI Security & Best Practices

Security is layered — record, object, field, and UI/browser level. PD1's safe default: prefer standard/LDS solutions first, and when Apex is unavoidable, pick the right access mode explicitly.

The security mindset Default order

Standard UI / LDSCorrect Apex access modeLWS over LockerBase Components

LDS handles sharing, CRUD, and FLS for you. Apex runs in user mode by default in API 67.0+ — record sharing is enforced unless you declare without sharing.

The 4 security layers

LayerControlsMechanisms
Record-levelWhich records a user sees/editsSharing rules, role hierarchy, ownership, with/without/inherited sharing
Object-levelWhether the user can access the object at allProfile / Permission Set object permissions
Field-level (FLS)Whether specific fields are visible/editableWITH USER_MODE, WITH SYSTEM_MODE, stripInaccessible()
UI-levelHow components run in the browserLWS, Locker, CSP, safe 3rd-party library handling

Sharing keywords Record-level only

KeywordEffect
with sharingEnforces sharing rules for record access — respects the user's record visibility
without sharingBypasses sharing rules — use only when elevated record access is truly required
inherited sharingInherits the caller's sharing context (Salesforce still recommends explicit keywords for maintainability)
Critical trapSharing keywords control record-level security only — they do NOT enforce object-level or field-level security (CRUD/FLS).

WITH USER_MODE vs WITH SYSTEM_MODE Newer high-yield topic

  • In API 67.0+, Apex runs in user mode by default — the current user's object/field permissions are enforced automatically.
  • WITH USER_MODE on a SOQL query → enforce object & field permissions.
  • WITH SYSTEM_MODE → explicitly bypass those permissions (elevated access).
SELECT Id, Name
FROM Expense__c
WITH USER_MODE
PD1 rule"Respect the user's object/field permissions" → WITH USER_MODE. "Bypass those permissions intentionally" → WITH SYSTEM_MODE.

stripInaccessible()

  • Checks records for fields the current user cannot access and returns sanitized records.
  • Use it after you already have records, to avoid leaking restricted field values back to the UI.
DistinctionstripInaccessible() sanitizes records you already have. WITH USER_MODE makes the query itself obey user permissions.

Apex class access for @AuraEnabled

  • Even with correct code, an @AuraEnabled method is only callable when the user's Profile or Permission Set grants access to that Apex class.
  • Modern guidance favors WITH USER_MODE/stripInaccessible() over manual Schema.Describe checks.

Lightning Web Security (LWS) vs Locker Exam favorite

LockerLightning Web Security
RolePredecessorCurrent recommendation
Default for new orgsNoYes (Winter '23+, GA Summer '23)
RestrictionsMore restrictiveReduced, better JS compatibility
3rd-party codeHarder to use safelyEasier to isolate & secure

LWS runs components in isolated JS environments while keeping namespace isolation transparent. Always test before moving LWS-only features to production.

CSP & third-party libraries

  • Lightning apps should use the stricter CSP setting to prevent unsafe/inline script execution and protect org security controls.
  • LWS makes third-party libraries easier to isolate safely — it does not make every library automatically safe.

Base components & accessibility

  • Base components (lightning-button, lightning-input, lightning-card, etc.) ship with accessible HTML, SLDS styling, keyboard support, and correct ARIA roles — following W3C best practices.
  • They are the safest PD1 answer whenever a base component exists for the job, over hand-rolled markup.

Scenario → best answer

RequirementBest answer
Standard UI, security handled automaticallyLightning Data Service
Enforce user permissions in SOQLWITH USER_MODE
Sanitize inaccessible fields on recordsstripInaccessible()
Control record-level visibility in Apexwith sharing / without sharing
Modern Lightning component securityLightning Web Security
Accessible UIBase Components + SLDS
Safer third-party component executionLWS + CSP
Trap busterswith sharing does NOT enforce CRUD/FLS · without sharing does NOT change object/field permissions, only record sharing · stripInaccessible() is NOT only for DML — it sanitizes any record for field access · LWS is NOT the same as Locker (LWS is newer) · base components are NOT just convenience — they're built accessible by design · accessibility is NOT optional trivia on PD1.

Flashcards

Active recall

Answer in your head first, then reveal. Use "Reveal all" in the header to read straight through.