Sibling Communication with Lightning Message Service
By the end of this lesson, you'll be able to:
- Explain why sibling (non-nested) components need a different communication mechanism
- Describe the publish/subscribe model of Lightning Message Service
- Use the basic LMS API to publish and subscribe to a message
Prerequisites: "Event Propagation: bubbles, composed, and Retargeting"
The Sibling Problem
@api and CustomEvent both rely on a direct parent/child relationship — a parent passing data down, or a child's event bubbling up to a listening ancestor. Two components that are not nested — for instance, two independent components both placed directly on the same Lightning Record Page — have no such relationship to lean on.
Lightning Message Service (LMS)
Lightning Message Service solves this with a publish/subscribe model, built around a Lightning Message Channel — a piece of metadata that defines a named "channel" any component can publish to or subscribe from, regardless of where it sits in the page.
A Short Primer: What Is @wire?
LMS's code below uses something called @wire for the first time in this course, so before that code makes sense, here's just enough to read it correctly:
@wire is a decorator (Module 4 introduced @api as a decorator; @wire is a different one) that connects a component property to a reactive Salesforce-provided data source or service — it automatically supplies a value to that property, and can automatically update it again later if the underlying source changes. Module 6 is the full, dedicated lesson on @wire for reading Salesforce record data specifically — this primer covers only what's needed here: @wire can also connect a component to non-record services the platform provides, and MessageContext is exactly one such service — the piece of infrastructure LMS's publish/subscribe functions need in order to work. Writing @wire(MessageContext) messageContext; is simply how a component obtains that infrastructure access.
Basic LMS Usage
// Publishing (in one component)
import { LightningElement, wire } from 'lwc';
import { publish, MessageContext } from 'lightning/messageService';
import RECORD_SELECTED_CHANNEL from '@salesforce/messageChannel/RecordSelected__c';
export default class FilterPanel extends LightningElement {
@wire(MessageContext) messageContext;
handleFilterClick(recordId) {
publish(this.messageContext, RECORD_SELECTED_CHANNEL, { recordId });
}
}
// Subscribing (in a completely unrelated component)
import { subscribe, MessageContext } from 'lightning/messageService';
import RECORD_SELECTED_CHANNEL from '@salesforce/messageChannel/RecordSelected__c';
connectedCallback() {
subscribe(this.messageContext, RECORD_SELECTED_CHANNEL, (message) => {
this.selectedRecordId = message.recordId;
});
}
@wire(MessageContext), per the primer above, gives access to the messaging infrastructure this all runs on top of — Module 6 covers @wire in full for reading actual Salesforce record data, a related but distinct use of the same decorator.
Why This Matters in Real Projects
Real Lightning pages commonly have several independent components — a filter panel, a results list, a detail panel — that all need to coordinate without being nested inside each other. LMS is the standard, supported way to make that happen.
Exercise
Explain, as a comment, why two sibling components placed independently on the same Record Page cannot simply use @api to share data.
Show hint
Think about what relationship @api actually requires.
Exercise
Challenge: name the LMS function used to send a message, and the one used to receive it.
Show hint
Both are imported from lightning/messageService.
Sibling Communication with Lightning Message Service Quiz
My Notes
Log in to keep private notes on this lesson.
Questions about this lesson
No questions yet — be the first to ask.
Log in to ask a question about this lesson.
Summary
@api and CustomEvent only work along a direct parent/child relationship — Lightning Message Service is how two unrelated components on the same page coordinate with each other.