SfSkills Domains Docs GitHub

Home / lwc / lwc-toast-and-notifications

lwc-toast-and-notifications

Show toast, platform, and in-app notifications from LWC — ShowToastEvent, lightning/platformShowToastEvent, Custom Notification types. Triggers: ShowToastEvent, toast LWC, custom notification LWC, toast not showing in Experience Cloud, lightning/toast vs platformShowToastEvent, Messaging.CustomNotification from Apex. NOT for modal overlays — use lwc/lwc-modal-and-overlay.

Open the skill folder on GitHub


Use this skill when a component needs to communicate feedback, status, or a decision prompt to the user and the team must choose the right platform primitive. Toast is the default for non-blocking success, warning, and error messages in Lightning Experience; lightning/alert, lightning/confirm, and lightning/prompt replace the browser-native dialogs with promise-based equivalents; a custom notification sent from Apex reaches a user who is not looking at the page at all.


Before Starting

Gather this context before working on anything in this domain:


Questions to Ask Before Configuring

Ask these before writing the handler. Each one traces to a failure in references/gotchas.md, and an agent that skips them produces a component that works in the sandbox page it was built on and nowhere else.

AskWhy it mattersWhat a good answer adds
"Which containers will this bundle be exposed to — record page, Aura site, LWR site, Flow screen, quick action?"lightning/platformShowToastEvent renders nothing on LWR sites, Aura-site login pages, or standalone apps, and throws no error (Gotcha 1)The <target> list for .js-meta.xml and the module choice that follows from it
"What apiVersion is this bundle on, and can we raise it?"lightning/toast needs API 59.0; the event module works from 45.0 (Gotcha 2)Either a version bump in the deploy, or a documented fallback for a pinned org
"Is the recipient looking at this page when the event happens?"No in-page primitive reaches an absent user; that case is a custom notification sent from ApexA decision between a toast and a CustomNotificationType plus its Apex sender
"Does this message carry a link or a substituted value?"Inline links are supported in both lightning/toast properties but not in the event module's title (Gotcha 11)The module choice, and whether the message needs placeholder substitution at all
"Is the action reversible, and what does the user lose if they clicked by mistake?"Irreversible actions need the promise gate before the call, not a toast after itAn explicit LightningConfirm.open() boundary and the branch for false
"How many of these fire per operation — one, or one per record?"The toast container caps the page at three and queues the rest until one is dismissed (Gotcha 4)A summarised single message plus somewhere the per-record detail actually lives
"Who gets the custom notification: named users, a queue, or a team, and who may send it?"Recipient ids expand differently and cap at 500 per send; the sender needs Send Custom Notifications (Gotchas 7, 8)The recipient strategy, the chunking, and the permission set that has to ship with it

What a proper configuration adds over just calling dispatchEvent: the notification renders in every container the bundle is exposed to, a destructive action cannot fire without a decision, the message survives the platform's own length and count limits, and the Jest suite asserts something that is actually true about the component.


Core Concepts

Notification design in LWC is two decisions in order: which surface, then which module for that surface. Most defects in this domain come from making the second decision first.

Choosing the surface

The user is…SurfaceWhy
On the page, and the message is informational or a receiptToastNon-blocking; the user keeps working
On the page, and must read the message before continuinglightning/alert.open() returns a promise that resolves when they dismiss it
On the page, and must answer yes or no firstlightning/confirmResolves true on OK and false on Cancel
On the page, and must supply a value firstlightning/promptResolves to the entered value, or null on Cancel
On the page, and the message belongs to a field or a formInline message, not a notificationA toast that scrolls away cannot be re-read next to the field it describes
On the page, and the interaction needs a form or multiple stepsLightningModal — see lwc/lwc-modal-and-overlayNotification primitives are not containers
Not on the pageCustom notification sent from ApexDesktop and mobile channels, delivered by the platform

The two toast modules

Both require a module import, and they are not interchangeable.

lightning/toastlightning/platformShowToastEvent
MechanismImperative show() call on the moduleDispatch ShowToastEvent from the component
First availableAPI 59.0API 45.0
LWR Experience Cloud sitesSupportedNot supported
Aura-site login pages, standalone apps—Not supported
Inline links in the titleSupportedNot supported
--slds-c-toast-* styling hooksSupportedNot supported
Salesforce's own recommendationPreferred"We recommend that you use lightning/toast instead"

Sources for every row: lwc_guide base-components-all L4649, L4651, L4652; lwc_guide use-toast L10448–L10452; lwc_guide base-components-patterns L4773; lwc_guide create-components-css-custom-properties L1721.

// Event module — created with title, message, variant, and mode, then dispatched.
// (lwc_guide use-toast L10456)
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

this.dispatchEvent(
    new ShowToastEvent({
        title: 'Contacts updated',
        message: 'Your changes were saved.',
        variant: 'success'
    })
);

UNVERIFIED (2026-09-05): the crawled Developer Guide names variant and mode as properties but never prints their accepted values or defaults. Only variant: 'success' and variant: 'error' appear in its own samples (lwc_guide data-table-inline-edit L5694, L5746). The familiar info / warning variants and the dismissable / sticky / pester modes come from the Component Library specification pages, which are not in the corpus — see Gotcha 10.

The rule that follows from the table is not "detect the container at run time". It is: default to lightning/toast, and treat the event module as the exception you take only on an org pinned below API 59. references/code-examples.md § 1 implements that as a notify.js helper taking the surface as a declared parameter rather than sniffing for it.

Toast container behaviour is page-level, not component-level

lightning/toastContainer controls position and how many toasts a page shows at once. The defaults are three toasts, top-center, fixed; only one container instance is supported per page; and its configuration governs toasts from both modules (lwc_guide use-toast L10457–L10463). A page over its cap does not drop the extra toast — it holds it until one is dismissed (L10464). Design for one notification per operation.

The promise-returning dialogs

lightning/alert, lightning/confirm, and lightning/prompt (all API 54.0) exist because "the HTML specification has deprecated support for the window.alert(), window.confirm(), and window.prompt() methods when used in a third-party context" (lwc_guide base-components-patterns L4768), and because the native calls "aren't supported for cross-origin iframes in Chrome and Safari" (lwc_guide use-dialog-alert L10401). The behavioural difference that changes your code: "these modules' .open() method don't halt execution on the page, and they each return a promise" (L4769). Code that used to run after a native confirm() must move inside the await.

The parameter names differ between the three — alert takes message, theme, label; confirm takes message, variant, label; prompt takes message, theme, label, defaultValue (use-dialog-alert L10404, use-dialog-confirm L10418, use-dialog-prompt L10432).

Custom notifications: the surface for an absent user

Messaging.CustomNotification "is used to create, configure, and send custom notifications from Apex code" (Apex Reference Guide L166556). The declarative half is a CustomNotificationType with its desktop and mobile channels — owned by admin/custom-notification-type-design. The Apex half belongs here: set the type id, title, body, and a target, then send(Set<String> users). Its limits are hard and quiet — 250-character title, 750-character body, 500 recipient values per send — and send() throws when no target is set at all. See Gotchas 7–9 and references/code-examples.md § 5.

Notification surfaces this skill does not own


Common Patterns

Toast After Apex DML

When to use: A component calls an Apex method to save, update, or delete a record and needs to confirm the outcome without interrupting navigation.

How it works: Report success in the then/await branch and failure in the catch branch. Read the message out of the error rather than stringifying it — the guide's own samples read error.body.message (lwc_guide data-table-inline-edit L5703). Normalising the many shapes an LWC error can take is lwc/lwc-error-boundaries' job; import its utility rather than re-deriving one.

Why not the alternative: A blocking dialog for a routine save trains users to dismiss dialogs unread, which is exactly the reflex you need intact when something serious appears.

Confirm Before Destructive Action

When to use: A delete, archive, or bulk overwrite the user cannot undo.

How it works: await LightningConfirm.open({...}) before the Apex call, and return early when it resolves false. The gate is visible in the diff and testable in Jest by mocking the resolved value both ways — see references/code-examples.md § 4.

Why not the alternative: A full LightningModal is a container for a task, not a question; and a post-hoc toast reporting "12 records deleted" is a receipt for a mistake.

Reporting a Batch Outcome

When to use: One user action produces many per-record results.

How it works: One notification summarising the operation, plus a place — a datatable of failures, a section on the page — where the detail is still readable a minute later. The container caps concurrent toasts at three by default and queues the rest (Gotcha 4), so a per-record toast loop is a design that hides its own output.


Decision Guidance

SituationRecommended ApproachReason
Confirm a save succeeded, Lightning pageToast via lightning/toastNon-blocking, and the same code works if the component is later exposed to a site
Any component exposed to lightningCommunity__* targetslightning/toast onlyThe event module is not supported in LWR sites
Org pinned below API 59.0ShowToastEvent, and no LWR placementlightning/toast does not exist below 59.0
Message must be read before the user proceedslightning/alertPromise resolves after dismissal; control flow stays explicit
Irreversible actionlightning/confirm before the callResolves true/false; cheaper than a modal for one question
A value is needed before proceedinglightning/promptResolves to the input value, or null on Cancel
Message belongs to one fieldInline messageA notification cannot be re-read beside the field
Recipient is not on the pageMessaging.CustomNotification from ApexDesktop and mobile delivery, with a CustomNotificationType behind it
Multi-step or form-bearing dialogLightningModal (lwc/lwc-modal-and-overlay)Notification primitives are not form containers
Toast appearance must be themedlightning/toastThe event module ignores --slds-c-toast-*

  1. Read the bundle's .js-meta.xml first — record its apiVersion and every <target>. Those two lines decide the module before any handler is written; the container matrix in Core Concepts turns them into a choice.
  2. Pick the surface, then the module — walk the surface table (absent user → custom notification; decision → confirm; receipt → toast), then the two-module table. Write down which row you used; that sentence is the whole justification a reviewer needs.
  3. Build the bundle from references/code-examples.md — § 1 for notify.js, § 2 for the confirm-gated component, § 3 for the dual-target .js-meta.xml, § 5 for the Apex sender when the surface is a custom notification. Reference templates/lwc/component-skeleton/ and templates/lwc/jest.config.js rather than re-deriving them.
  4. Write the two Jest cases that matter — the toast event detail (detail.title, detail.message, detail.variant) and both branches of the confirm promise. § 4 has the moduleNameMapper entries; without them the imports resolve to the stock stubs.
  5. Run the checker over the source tree — python3 scripts/check_lwc_toast_and_notifications.py --manifest-dir force-app/main/default. It reads each bundle together with its .js-meta.xml, which is the only way the LWR/event-module pairing is visible.
  6. Deploy in the order in § 7 — notification type, Apex, then LWC — and run the verification steps there, including the deliberate LWR placement that proves the silent-failure mode is understood rather than assumed.
  7. Walk references/gotchas.md against the finished component, and record which UNVERIFIED claims you relied on so the reviewer can check them against the Component Library.

Review Checklist

Run through these before marking work in this area complete:


Salesforce-Specific Gotchas

The full set, each with what happens, when it occurs, how to avoid it, and its guide line, is in references/gotchas.md. The five that cause the most rework:

  1. The event module renders nothing in LWR sites, Aura-site login pages, and standalone apps — and throws no error. Discovered in QA, after the deploy (Gotcha 1).
  2. lightning/toast needs API 59.0. Following the recommendation on a pinned org fails to save (Gotcha 2).
  3. Three toasts per page by default; the fourth waits for a dismissal. A per-record toast loop silently withholds most of its output (Gotcha 4).
  4. send() throws when both targetId and targetPageRef are omitted, although neither field is required. The exception reads like a permission problem (Gotcha 7).
  5. A green Jest toast test proves the event was dispatched, not that anyone saw it. Two different claims (Gotcha 6).

Output Artifacts

ArtifactDescription
notify.js helperSurface-aware module that routes to lightning/toast or the event module from a declared flag
Confirm-gated componentBundle with .html, .js, and dual-target .js-meta.xml
Jest suiteTests asserting the toast event detail and both branches of the confirm promise
CustomNotificationSender.cls + testApex sender with target validation, recipient chunking, and length truncation
package.xml + deploy orderManifest naming the CustomNotificationType explicitly, with retrieve/deploy/test commands
Checker reportERROR/WARN/ADVISORY findings from scripts/check_lwc_toast_and_notifications.py

Reference Files

FileRead it when
references/code-examples.mdYou are building: the notify.js helper, the confirm-gated component, its .js-meta.xml, the Jest tests, the Apex sender, the manifest, and the deploy and verification steps
references/gotchas.mdA notification does not appear, appears late, truncates, or throws — twelve grounded platform behaviours with guide line citations
references/examples.mdYou want a worked before/after narrative for a save flow and a destructive bulk action
references/llm-anti-patterns.mdYou are reviewing generated code, or self-checking your own output, for the mistakes assistants make in this domain
references/well-architected.mdYou are justifying the surface choice in a design review, or need the source list behind the claims here

Package files