SalesforceBlue

Feel the rhythm of Salesforce

LWC

Communicate Across DOM In Lightning Web Components

We can use Lightning Message Service to communicate across the DOM within a Lightning page. We can even use it to communicate between Visualforce pages embedded in the same Lightning page, Aura components, and Lightning web components, including components in a utility bar and pop-out utilities.

Here you declare a component as a publisher that will publish the message on the message channel and declare component(s) to subscribe to a message channel that will listen to the messages published by publisher components.

Let’s explore the steps required to communicate across the DOM as follows:

Create a Message Channel:

Follow the below steps to create a message channel.

Step 1: Create a folder name as messageChannels under the directory force-app > main > default. Inside the folder, messageChannels create a file with a name as messageChannelName.messageChannel-meta.xml

Step 2: Add the following XML to the newly created file messageChannelName.messagChannel-meta.xml. In this post, we have created a message channel file with the name as myMessageChannel.messageChannel-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata">
    <description>This is a sample Lightning Message Channel For Communicating Across DOM.</description>
    <isExposed>true</isExposed>
    <lightningMessageFields>
        <description>This is a payload field</description>
        <fieldName>greetingMessage</fieldName>
    </lightningMessageFields>
    <masterLabel>myMessageChannel</masterLabel>
</LightningMessageChannel>

Step 3: Deploy this message channel file myMessageChannel.messageChannel-meta.xml into your org.

Define the scope of the Message Service:

The Lightning message service lets you define the scope of where subscribing components receive messages in your application. You can limit the scope to the active area of the application or set the scope to the entire application.

The application’s active area includes selected navigation tabs and items, utility items, and ES6 libraries.

Publish on a Message Channel:

In your component’s JavaScript file which will act as a publisher component, import the message channel and the Lightning message service functions necessary for working with a message channel.

Use @wire(MessageContext) to create a MessageContext object, which provides information about the Lightning web component that is using the Lightning message service.

We would be seeing the exact code with an example in this post further below once we are familiar with the different parts around it.

Subscribe and Unsubscribe from a Message Channel:

To subscribe and unsubscribe from messages on a message channel, import the message channel from the @salesforce/messageChannel scoped module into your Lightning web component. Call the Lightning message service’s subscribe() and unsubscribe() functions.

Lightning Message Service Limitation:

The Lightning message service supports only the following experiences:

  • Lightning Experience standard navigation
  • Lightning Experience console navigation
  • Salesforce mobile app for Aura and Lightning Web Components, but not for Visualforce pages
  • Lightning components used in Experience Builder sites. Support for Experience Builder sites is beta (As of writing).

Please note that Lightning Message Service doesn’t work with Salesforce Tabs + Visualforce sites or with Visualforce pages in Experience Builder sites.

In containers that don’t support the Lightning messaging service, use the pubsub module. Download the module from github.com/developerforce/pubsub.

Lightning Message Service Example:

For this example, we would be using the myMessageChannel created above.

Let’s create two components(LWC) named as subscriberLwc and publisherLwc.

Please add the below code in publisherLwc component as given below:

import { LightningElement, wire } from 'lwc';
import { publish, MessageContext } from 'lightning/messageService';
import myMessageChannel from '@salesforce/messageChannel/myMessageChannel__c';

export default class PublisherLwc extends LightningElement {
 
    @wire(MessageContext)
    messageContext;

    buttonHandler(event) {
        const payload = {greetingMessage: "This message is send from the publisher component"};
        publish(this.messageContext, myMessageChannel, payload);

    }
}

Let’s understand the above code line by line.

On Line 2-3 we are importing the message service features required for publishing and the respective message channel

On Line 7 we are creating a MessageContext object, which provides information about the Lightning web component that is using the Lightning message service.

On Line 12 To publish the message on the message channel we are calling the Lightning message service’s publish() function.

<template>
    
    <lightning-card title="title">
        <p class="slds-p-horizontal_small">
            <lightning-button variant="brand" label="Click Me" title="Click Me" onclick={buttonHandler}></lightning-button>
        </p>
    </lightning-card>

</template>
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>55.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>

Now let’s also add the below code in subscriblerLwc component:

import { LightningElement, wire } from 'lwc';
import { subscribe, unsubscribe, APPLICATION_SCOPE, MessageContext} from 'lightning/messageService';
import myMessageChannel from '@salesforce/messageChannel/myMessageChannel__c';

export default class SubscriberLwc extends LightningElement {
    message;
    subscription = null;

    @wire(MessageContext)
    messageContext;
   
    connectedCallback() {
        this.subscribeToMessageChannel();
    }

    disconnectedCallback() {
        this.unsubscribeToMessageChannel();
    }

    subscribeToMessageChannel() {
        if (!this.subscription) {
            this.subscription = subscribe(
                this.messageContext,
                myMessageChannel,
                (message) => this.handleMessage(message),
                { scope: APPLICATION_SCOPE }
            );
        }
    }

    unsubscribeToMessageChannel() {
        unsubscribe(this.subscription);
        this.subscription = null;
    }

    handleMessage(message) {
        this.message = message.greetingMessage;
    }
}

Let’s understand the above code line by line:

On Line 2-3 we are Importing message service features required for subscribing and the message channel.

On Line 10 we are using @wire(MessageContext) to create a Context object, which provides information about the Lightning web components that are using the Lightning message service.

On Line 12-18 we are using Standard lifecycle hooks to subscribe and unsubscribe to the message channel

On Line 20-34 we are encapsulating logic for Lightning message service subscribe and unsubscribe. Here we call the Lightning message service’s subscribe() and unsubscribe() functions respectively.

On Line 26 to receive messages on a message channel from anywhere in the application we are passing { scope: APPLICATION_SCOPE } as the subscribe() method’s optional fourth parameter.

On Line 36-38 we are defining the handler function for the message received by component

<template>
    <lightning-card title="subscriber">
        <p class="slds-p-horizontal_small">
            {message}
        </p>
    </lightning-card>
</template>
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>55.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>

Once you are done creating these two components add them to a lightning app page. You may see an output like the below:

Before we wrap up this post please note that If you create a service component that isn’t a LightningElement, you can’t use @wire(MessageContext) to create the MessageContext object. Instead, import createMessageContext() and releaseMessageContext() methods from lightning/messageService.

Use createMessageContext() to create the Context object and assign it to a field, like messageContext. Then, pass messageContext into the subscribe() method. The context isn’t automatically released for service components. Call releaseMessageContext(messageContext) to remove any subscriptions associated with your component’s message context.

Thank you for visiting SalesforceBlue.com
If you have any queries feel free to write down a comment below 🙂


4 thoughts on “Communicate Across DOM In Lightning Web Components

  • l6ilge

    Excellent article. I certainly appreciate this website. Stick with it!

    Reply
  • 79efplss

    I was extremely pleased to discover this site. I wanted to thank you for ones time for this particularly wonderful read!! I definitely loved every little bit of it and I have you bookmarked to see new stuff on your blog.

    Reply
  • Gal Jerman

    Top ,.. top top … post! Keep the good work on !

    Reply
  • Gal Jerman

    Top site ,.. amazaing post ! Just keep the work on !

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *