Salesforce Console APIs (Navigation Item API, Workspace API, Utility Bar API) in Lightning Web Component using Aura and Lightning Message Channel

As of winter 21, There are no alternative for Salesforce Console APIs (Navigation Item API, Workspace API, Utility Bar API) in Lightning Web Component which are available in Aura Lightning Component. There is an idea available on IdeaExchange for the same. As an Salesforce Lightning Developer, we want to minimize the technical debt of using Aura Component in Lightning Console Apps. We are going to look workaround for Salesforce Console APIs (Navigation Item API, Workspace API, Utility Bar API) in Lightning Web Component to minimize the technical debt.

Workaround – Salesforce Console APIs (Navigation Item API, Workspace API, Utility Bar API) in LWC

We are going to use Lightning Message Service along with two separate components(An Aura Component and a Lightning Web Component). Aura Component will be used as a service component to provide Salesforce Console APIs (Navigation Item API, Workspace API, Utility Bar API) features to Lightning Web Component. The Lightning Web Component and Aura Component will be communicating with the help of Lightning Message Service. You can understand from below diagram:-

Creating Lightning Message Channel Using XML and VS CODE

To create a Lightning message channel, use the LightningMessageChannel metadata type.

Include the XML definition in the force-app/main/default/messageChannels/ directory. The LightningMessageChannel file name follows the format messageChannelName.messageChannel-meta.xml. Once you have created the file, paste the below XML code in messagechannel metadata file and deploy it to your connected org. In our case, i have named the channel as connector. It has two fields – recordId and recordData. It will be used to send data along with message.

<?xml version="1.0" encoding="UTF-8"?>
<LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata">
    <masterLabel>ConnectAuraAndLWC</masterLabel>
    <isExposed>true</isExposed>
    <description>Connect between Aura and LWC to communicate</description>
    <lightningMessageFields>
        <fieldName>recordId</fieldName>
        <description>This is the record Id that changed</description>
    </lightningMessageFields>
    <lightningMessageFields>
        <fieldName>recordData</fieldName>
        <description>The current data representing the record that changed</description>
    </lightningMessageFields>
</LightningMessageChannel>

Aura Component – A Service Component with Salesforce Console APIS (NAVIGATION ITEM API, WORKSPACE API, UTILITY BAR API)

We are going to create an Aura Component named ReusableConsoleJavaScriptAPI which will be a kind of service component. It will listen to message channel and handle it.

ReusableConsoleJavaScriptAPI.cmp

The Aura Component register for Lightning Message Channel using lightning:messageChannel and handles it using handleChanged method in JS controller.

<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global">
    <lightning:navigationItemAPI aura:id="navigationItem" />
    <lightning:workspaceAPI aura:id="workspace" />
    <lightning:utilityBarAPI aura:id="utilityBar" />
    <aura:attribute name="message" type="String" />
    <lightning:messageChannel type="connector__c" onMessage="{!c.handleChanged}" scope="APPLICATION" />
</aura:component>

ReusableConsoleJavaScriptAPIController.js

handleChanged method fetch the message received via message channel and then used workspaceAPI to change the tab label in Lightning console. Just to showcase the capability, I have changed the label to recordId received with message channel.

({
    handleChanged: function(component, message, helper) {
        // Read the message argument to get the values in the message payload
        component.set("v.message", message.getParam("recordId"));
        var workspaceAPI = component.find("workspace");
        workspaceAPI.getFocusedTabInfo().then(function(response) {
            var focusedTabId = response.tabId;
            workspaceAPI.setTabLabel({
                tabId: focusedTabId,
                label: component.get("v.message")
            });
        }).catch(function(error) {
            console.log(error);
        });
    }
})

Lightning Web Component – consoleApiWithLwc

We are going to create a Lightning Web Component which will utilize the Lightning Message Service using message channel to communicate with Aura Component and utilize the SALESFORCE CONSOLE APIS (NAVIGATION ITEM API, WORKSPACE API, UTILITY BAR API).

consoleApiWithLwc.html

We have a button to publish the message using message channel.

<template>
    <lightning-button label="Publish from LWC" onclick={publishMessageFromLWC}></lightning-button>
</template>

consoleApiWithLwc.js

The JS file imports the messageService library and messageChannel. It publish the message that will be listened by Aura Component.

import { LightningElement, wire, api } from 'lwc';
// Import message service features required for publishing and the message channel
import { publish, MessageContext } from 'lightning/messageService';
import CONNECTOR_CHANNEL from '@salesforce/messageChannel/connector__c';
export default class ConsoleApiWithLwc extends LightningElement {
    @wire(MessageContext)
    messageContext;

    @api recordId;

    // Respond to UI event by publishing message
    publishMessageFromLWC(event) {
        const payload = { recordId: this.recordId };
        publish(this.messageContext, CONNECTOR_CHANNEL, payload);
    }
}

consoleApiWithLwc.js-meta.xml

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

Demo – Salesforce Console APIS in Lightning Web Component

You need to place both the component on the record page in console apps. You can test it by clicking the button available on the Lightning Web Component.

Check out interesting articles on this blog here :- Lightning Web Component Blog Post

Leave a Reply