Earlier when we had to send data from one component to another component that is not within the hierarchy then we were relying upon PubSub.

It's a library that Salesforce provided that's dependent on Publish and Subscribe model.

But that approach is a bit roundabout and tedious for developers to use.

So Salesforce came up with Lightning Message Service which is used to send data from one LWC Component to another LWC Component. Also, it's used for communication between LWC, Aura, and Visualforce pages too.

Let's look at how to send data using Lightning Message Service in LWC.

The first thing that we need to create is a Message Channel. We cannot create a Message Channel (via an XML file) from the Salesforce Developer Org or Sandbox. We need to create it from VS Code and push it to the respective org.

Here is the XML file used to create a MessageChannel.

<?xml version="1.0" encoding="UTF-8" ?>
<LightningMessageChannel>
    <masterLabel>AccountData</masterLabel>
    <isExposed>true</isExposed>

    <description
  >This is a channel which is used by LWC component to send data</description>
        <!-- Am creating two fields that will be eventually 
        used to send data -->
    <lightningMessageFields>
        <description>This is the Id of the record</description>
        <fieldName>recordId</fieldName>
    </lightningMessageFields>
    <lightningMessageFields>
        <description>This is the  of the record</description>
        <fieldName>name</fieldName>
    </lightningMessageFields>
</LightningMessageChannel>
AccountDataMessageChannel.messageChannel-meta.xml
Create an XML file with the extension .messageChannel-meta.xml

This is the template file that transmits the data on click of the button.

<template>
  <lightning-button label="send data" onclick={handleClick}></lightning-button>
</template>
publisherComponent.html

This is the JavaScript file of the Web Lightning Web Component.

import { LightningElement, wire } from "lwc";

//1. Importing the named imports 
//[library to publish data and the message channel]

import { publish, MessageContext } from "lightning/messageService";
import ACCOUNT_CHANNEL from "@salesforce/messageChannel/AccountDataMessageChannel__c";

export default class PublisherComponent extends LightningElement {
  //2. Wiring the MessageContext to a property
  @wire(MessageContext)
  messageContext;

  //3. Handling the user input.
  //which in our case is going to be a button click
  handleClick() {
    const messaage = {
      recordId: "001xx000003NGSFAA4",
      name: "Burlington Textiles of America"
    };

    //4. Publishing the message
    publish(this.messageContext, ACCOUNT_CHANNEL, messaage);
  }
}
publisherComponent.js

This is a template that is going to receive the data that the other component publishes using the Message Channel.

We will only be receiving the data when we subscribe.

<template>
  <lightning-button
    label="subscribe"
    onclick={handleSubscribe}
  ></lightning-button>
  <lightning-button
    label="unsubscribe"
    onclick={handleUnsubscribe}
  ></lightning-button>
  <lightning-button label="clear" onclick={handleClear}></lightning-button>

  {receivedMessage}
</template>
subscriberComponent.html

This is the JavaScript controller of the Web Component that subscribes to the Message Channel (on click of the button on the template file).

import { LightningElement, wire } from "lwc";

//1. Import all the named imports

import {
  subscribe,
  unsubscribe,
  MessageContext
} from "lightning/messageService";
import ACCOUNT_CHANNEL from "@salesforce/messageChannel/AccountDataMessageChannel__c";

export default class SubscriberComponent extends LightningElement {
  //2. Wiring MessageContext to a property
  @wire(MessageContext)
  messageContext;

  receivedMessage;
  subscription = null;
  //3. Handling the user input
  handleSubscribe() {
    console.log("in handle subscribe");
    if (this.subscription) {
      return;
    }

    //4. Subscribing to the message channel
    this.subscription = subscribe(
      this.messageContext,
      ACCOUNT_CHANNEL,
      (message) => {
        this.handleMessage(message);
      }
    );
  }

  handleMessage(message) {
    this.receivedMessage = message
      ? JSON.stringify(message, null, "\t")
      : "no message";
  }

  handleUnsubscribe() {
    console.log("in handle unsubscribe");

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

  handleClear() {
    this.receivedMessage = null;
  }
}
subscriberComponent.js

Hope this is helpful!