Note: This release is in preview. Features described here don’t become generally available until the latest general availability date that Salesforce announces for this release. Before then, and where features are noted as beta, pilot, or developer preview, we can’t guarantee general availability within any particular time frame or at all. Make your purchase decisions only on the basis of generally available products and features.
Using Page References to Open Console Workspace Tabs and Subtabs
Use Page References in LWC
You can use a page reference to open different page types in a tab or subtab. This example opens a subtab using openTab() to display the view page on a specified PersonAccount record.
1import { LightningElement, wire } from 'lwc';
2import { EnclosingTabId, openSubtab } from 'lightning/platformWorkspaceApi';
3
4export default class MyComponent extends LightningElement {
5 @wire(EnclosingTabId) enclosingTabId;
6
7 openAnotherSubTab() {
8 if (!this.enclosingTabId) {
9 return;
10 }
11 openSubtab(this.enclosingTabId, {
12 pageReference: {
13 type: 'standard__objectPage',
14 attributes: {
15 recordId: '001xx000003DGg0AAG',
16 objectApiName: 'PersonAccount',
17 actionName: 'view'
18 }
19 }
20 });
21 }
22}Navigate to a URL Addressable Component in LWC
Making a component URL addressable provides the following benefits for console apps:
- Future-proofs your apps from changes in URL formats.
- Generates a user-friendly URL for your tabs.
- Opens an Aura component as a subtab, even if called from a utility, a hover, or another page.
- Allows a mechanism to conditionally open a given component more than once or redirect to an already open workspace or subtab using the uid parameter.
For example, you have a URL addressable myComponent component, and a workspaceOpenTab component that navigates to the addressable component.
To make myComponent available for navigation, set the <isExposed> tag to true in the myComponent.js-meta.xml configuration file. The <apiVersion> tag has no impact on the lightning__UrlAddressable target and can be set to an earlier version.
1<!-- myComponent.js-meta.xml -->
2<?xml version="1.0" encoding="UTF-8"?>
3<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
4 <apiVersion>61.0</apiVersion>
5 <isExposed>true</isExposed>
6 <targets>
7 <target>lightning__UrlAddressable</target>
8 </targets>
9</LightningComponentBundle>myComponent displays the URL and page reference information that the workspaceOpenTab component passes in.
1<!-- myComponent.html -->
2<template>
3 <div class="slds-var-m-around_medium">
4 <p>Component URL: {connectedCallbackUrl}</p>
5 <p>Current page reference:</p>
6 <pre><code>{currentPageRefFormatted}</code></pre>
7 </div>
8</template>The component's JavaScript uses the CurrentPageReference wire adapter to return page reference information. In this example, the URL returns https://MyDomainName.my.salesforce.com/lightning/cmp/c__myComponent?c__mystate=value&uid=_uniqueId_.
1// myComponent.js
2import { LightningElement, wire } from 'lwc';
3import { CurrentPageReference } from 'lightning/navigation';
4
5export default class MyComponent extends LightningElement {
6 @wire(CurrentPageReference)
7 currentPageRef;
8
9 connectedCallbackUrl;
10
11 connectedCallback() {
12 this.connectedCallbackUrl = window.location.href;
13 }
14
15 get currentPageRefFormatted() {
16 return JSON.stringify(this.currentPageRef, undefined, 2);
17 }
18}This workspaceOpenTab has a button that opens the URL addressable component in a new workspace tab. Its .js-meta.xml configuration file includes the lightning__AppPage target only. It assumes that you add the workspaceOpenTab component to a Lightning console app.
1<!-- workspaceOpenTab.html -->
2<template>
3 <div class="slds-m-around_medium">
4 <lightning-button label="Open Tab" onclick={handleOpen}>
5 </lightning-button>
6 </div>
7</template>The component's JavaScript calls the openTab() method from lightning/platformWorkspaceApi. To prevent the app from opening a new tab if the tab with the component is already opened, pass in a uid value to the state object.
1// workspaceOpenTab.js
2import { LightningElement, wire } from 'lwc';
3import { NavigationMixin } from 'lightning/navigation';
4import { IsConsoleNavigation, openTab } from 'lightning/platformWorkspaceApi';
5
6export default class WorkspaceOpenTab extends NavigationMixin(LightningElement) {
7 @wire(IsConsoleNavigation) isConsoleNavigation;
8
9 async handleOpen() {
10 if (!this.isConsoleNavigation) {
11 return;
12 }
13 try {
14 await openTab({
15 pageReference: {
16 type: 'standard__component',
17 attributes: {
18 componentName: 'c__myComponent',
19 },
20 state: {
21 c__stateKey: 'stateValue',
22 uid: "1",
23 },
24 },
25 icon: 'utility:sparkles',
26 label: 'My Component',
27 });
28 } catch (error) {
29 // handle error
30 }
31 }
32}Use Page References in Aura Components
1<aura:component implements="lightning:isUrlAddressable">
2 <aura:attribute name="name" type="String" description="The person that will be greeted" />
3 <aura:handler name="init" value="{!this}" action="{!c.init}" />
4 <aura:handler name="change" value="{!v.pageReference}" action="{!c.handlePageChange}" />
5 <h1>Greeting Page</h1>
6 <div>Hello, {!v.name}</div>
7</aura:component>1({
2 init: function(cmp, evt, hlp) {
3 var myPageRef = cmp.get("v.pageReference");
4 var name = myPageRef && myPageRef.state ? myPageRef.state.c__name : "World";
5 cmp.set("v.name", name);
6 },
7 handlePageChange: function(cmp, evt, hlp) {
8 var myPageRef = cmp.get("v.pageReference");
9 var name = myPageRef && myPageRef.state ? myPageRef.state.c__name : "World";
10 cmp.set("v.name", name);
11 }
12})1<aura:component>
2 <aura:attribute name="pageReference" type="Object"/>
3 <lightning:workspaceAPI aura:id="workspace"/>
4 <lightning:button label="Open Greeting in Subtab" onclick="{!c.openSubtab}"/>
5 <lightning:input label="Name" name="myname"/>
6</aura:component>The controller openGreetingsController.js uses openSubtab() and sets c__name to the value of the myname input field. You can use the uid parameter to conditionally dedupe tabs and subtabs. Omit the uid to open a new tab or subtab every time.
1({
2 openSubtab: function(component, event, helper) {
3 var workspaceAPI = component.find("workspace");
4 workspaceAPI.getEnclosingTabId().then(function(enclosingTabId) {
5 workspaceAPI.openSubtab({
6 parentTabId: enclosingTabId,
7 pageReference: {
8 "type": "standard__component",
9 "attributes": {
10 "componentName": "c__greetings"
11 },
12 "state": {
13 "uid": "1",
14 "c__name": component.get("v.myName")
15 }
16 }
17 }).then(function(subtabId) {
18 console.log("The new subtab ID is:" + subtabId);
19 }).catch(function(error) {
20 console.log("error");
21 });
22 });
23 }
24})Now that we have everything set up, we can test our components by creating a custom tab in Setup for openGreetings.cmp. Add the custom tab to a console app and open the console app. Select the custom tab from the nav menu to open openGreetings.cmp. Enter a name and click “Open Greeting in Subtab.” greetings.cmp opens as a subtab and displays its greeting with the provided name.