Communicate Across Salesforce UI Technologies with Lightning Message Service (Developer Preview)

Use the Lightning Message Service API to communicate across the DOM, between Aura components, Visualforce pages, and Lightning web components. Lightning Message Service also enables communication between a component in a main Lightning page with one in a pop-out utility bar. If you’re switching from Salesforce Classic to Lightning Experience, you can now build Lightning web components that can communicate with existing Visualforce pages or Aura components.

A Lightning web component uses a Lightning Message Channel to access the Lightning Message Service API. Reference Lightning Message Channel with the scoped module @salesforce/messageChannel. In Visualforce, use the global variable $MessageChannel. In Aura, use lightning:messageChannel in your component.

Where: This change applies to available in Lightning Experience.

Note

Note

This feature is available as a developer preview for Developer Edition and scratch orgs. It isn’t generally available unless or until Salesforce announces its general availability in documentation or in press releases or public statements.

Why: In Lightning Experience, you often have multiple components on a page. Previously, if you wanted a Visualforce page to communicate with a Lightning web component in Lightning Experience, you needed to implement a custom publish-subscribe solution. Now, you can use the Lightning Message Service API to handle that communication.

How: Assuming you have created a message channel called SampleMessageChannel__c using the Metadata API, here's how to subscribe a Visualforce page to a message channel on which a Lightning web component publishes.

Create a Lightning web component called publisherComponent that publishes on SampleMessageChannel__c, which is the API name of the message channel. The component imports methods to publish on a message channel from the lightning/messageService module. This module accesses the Lightning Message Service API. Next, import the message channel from @salesforce/messageChannel/SampleMessageChannel__c and assign it to the identifier SAMPLEMC.

The handleClick() method holds the data to be published on the message channel. Here, the data is a recordId with the value "some string" and recordData, whose value is the key-value pair value: "some data". Publish the data by calling the publish() method imported from the lightning/messageService module.

// publisherComponent.js
import { LightningElement } from 'lwc';
import { publish,createMessageContext,releaseMessageContext } from 'lightning/messageService';
import SAMPLEMC from "@salesforce/messageChannel/SampleMessageChannel__c";

export default class PublisherComponent extends LightningElement {
    context = createMessageContext();
    subscription = null;
    @track receivedMessage = '';
    handleClick() {
        const message = {
            recordId: "some string",
            recordData: {
                value: "some data"
            }
        };
        publish(this.context, SAMPLEMC, message);
    }
    disconnectedCallback() {
        releaseMessageContext(this.context);
    }
}

In your component’s HTML template file, include a Publish button that calls the handleClick() method. Clicking the button publishes the record data to SampleMessageChannel__c. The subscribing Visualforce page then receives that data.

<-- publisherComponent.html -->
<template>
    <lightning-card title="MyLwcPublisher" icon-name="custom:custom14">
        <div class="slds-m-around_medium">
            <p>MessageChannel: SampleMessageChannel</p>
            <br>
            <lightning-button label="Publish" onclick={handleClick}></lightning-button>
        </div>
    </lightning-card>
</template>

Here’s how to subscribe and unsubscribe a Visualforce page from a message channel SampleMessageChannel__c on which a Lightning web component publishes.

<apex:page>
    <div>
        <p>Subscribe to SampleMessageChannel</p>
        <button onclick="subscribeMC()">Subscribe</button>
        <p>Unsubscribe from SampleMessageChannel</p>
        <button onclick="unsubscribeMC()">Unsubscribe</button>
        <br/>
        <br/>
        <p>Received message:</p>
        <textarea id="MCMessageTextArea" rows="10" style="disabled:true;resize:none;width:100%;"/>
    </div>
    <script>
        // Load the MessageChannel token in a variable
        var SAMPLEMC = "{!$MessageChannel.SampleMessageChannel__c}";
        var subscriptionToMC;
        // Display message in the textarea field
        function onMCPublished(message) {
            var textArea = document.querySelector("#MCMessageTextArea");
            textArea.innerHTML = message ? JSON.stringify(message, null, '\t') : 'no message payload';
        }

        function subscribeMC() {
            if (!subscriptionToMC) {
                subscriptionToMC = sforce.one.subscribe(SAMPLEMC, onMCPublished);
            }
        }

        function unsubscribeMC() {
            if (subscriptionToMC) {
                sforce.one.unsubscribe(subscriptionToMC);
                subscriptionToMC = null;
            }
        }
    </script>

</apex:page>