Using Lightning Message Service (LMS) to communicate between components
In modern Salesforce development, Lightning Web Components (LWCs) have become the preferred method for building fast, modular, and reactive user interfaces. However, as applications scale in complexity, developers often encounter a common challenge: enabling seamless communication between components that are not directly related, such as siblings in different DOM trees, components on separate pages, or even across browser tabs.
That’s where Lightning Message Service (LMS) comes in. LMS is a powerful, often underutilized feature that allows for decoupled, event-driven communication across the Salesforce UI layer, including LWCs, Aura components, and Visualforce pages. Whether you're working within a single Lightning page or across different experiences, LMS ensures your components can stay in sync, clean, and efficient.
What is Lightning Message Service (LMS)?
At its core, Lightning Message Service is Salesforce’s implementation of the publish-subscribe (pub-sub) design pattern. It provides a framework for components to send and receive messages via a centralized message channel, without requiring any direct references or dependencies between them.
Key Benefits
-
Decoupling: Components can communicate without being tightly bound by parent-child relationships or DOM hierarchy.
-
Cross-Technology Communication: Enables messaging between Visualforce, Aura, and Lightning Web Components
-
Maintainability: By reducing direct dependencies between components, LMS helps create a more modular and testable codebase.
Use Case: Refreshing a Component After a User Action
Let’s walk through a practical example. Imagine you have two components:
• Component A: A form that updates a record.
• Component B: A summary view that needs to refresh whenever the record changes.
Instead of introducing tightly coupled logic or using custom events (which can get messy across component hierarchies), we’ll use LMS to broadcast a message from Component A and subscribe to it in Component B.
Step 1: Create a Message Channel
In your Salesforce DX project, create a message channel metadata file:
<!-- force-app/main/default/messageChannels/RecordUpdate__c.messageChannel-meta.xml --> <?xml version="1.0" encoding="UTF-8"?> <LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata"> <masterLabel>Record Update</masterLabel> <isExposed>true</isExposed> <description>Notifies when a record is updated</description> </LightningMessageChannel>
Deploy the file to your org using your preferred deployment tool (e.g., VS Code or the Salesforce CLI).
Step 2: Publish a Message from the Updating Component
In Component A, publish a message when the record update is successful:
/* recordForm.js */ import { LightningElement, wire, api } from 'lwc'; import { publish, MessageContext } from 'lightning/messageService'; import RECORD_UPDATE from '@salesforce/messageChannel/RecordUpdate__c'; export default class RecordForm extends LightningElement { @wire(MessageContext) messageContext; @api recordId; handleSaveSuccess() { publish(this.messageContext, RECORD_UPDATE, { recordId: this.recordId }); } }
Step 3: Subscribe to the Message in the Listening Component
In Component B, subscribe to the message and refresh data accordingly:
/* recordSummary.js */ import { LightningElement, wire, api } from 'lwc'; import { subscribe, MessageContext } from 'lightning/messageService'; import RECORD_UPDATE from '@salesforce/messageChannel/RecordUpdate__c'; export default class RecordSummary extends LightningElement { @wire(MessageContext) messageContext; @api recordId; connectedCallback() { this.subscribeToMessages(); } subscribeToMessages() { subscribe(this.messageContext, RECORD_UPDATE, (message) => { this.handleMessage(message); }); } handleMessage(message) { const updatedId = message.recordId; if (updatedId === this.recordId) { this.refreshSummary(); // Reload data or call Apex } } }
Why You Should Use LMS
LMS can become a core part of your Salesforce development toolkit, especially for complex applications. Here’s why:
• Cleaner Architecture: Eliminates the need for prop-drilling or excessive custom event wiring.
• Scalability: Components remain independent, making it easier to scale and refactor your app.
• Improved Testability: Since components don’t directly depend on one another, unit testing becomes simpler and more focused.
Best Practices When Using LMS
• Keep message payloads minimal and focused. Avoid overloading messages with unnecessary data.
• Use meaningful names for your message channels (e.g., RecordUpdate__c) to clearly convey your intent.
• Unsubscribe when needed (e.g., in disconnectedCallback) to avoid memory leaks, though LMS handles most of this under the hood.
• Avoid overusing LMS for tightly coupled components, where custom events or shared state may be simpler solutions.
Conclusion
Lightning Message Service provides a clean and robust way to enable inter-component communication in your Salesforce applications. Whether you’re bridging the gap between LWCs and Aura components or simply avoiding overly coupled code, LMS is a game-changer.
If you haven’t used it yet, try introducing it in a minor feature or refactor. It’s one of those tools that, once adopted, becomes an indispensable part of your development approach.