I think I have found the following solution which would require n
tabs and 1 Visualforce page with 1 Lightning Out Container app.
Web tabs will have relative URLS referring to different LWC components like
/apex/LWCCont?cmpName=c:fls
or /apex/LWCCont?cmpName=c:ols
.
Visualforce page will have the following code
<apex:page controller="LWCContController" sidebar="false">
<apex:includeLightning />
<div id="lightning" />
<script>
$Lightning.use("c:lwcOut", // name of the Lightning app
function() { // Callback once framework and app loaded
$Lightning.createComponent(
"{!cmpName}", // top-level component of your app
{ }, // attributes to set on the component when created
"lightning", // the DOM location to insert the component
function(cmp) {
// callback when component is created and active on the page
}
);
}
);
</script>
</apex:page>
with Apex Controller
public inherited sharing class LWCContController {
public String cmpName { get{
return ApexPages.currentPage().getParameters().get('cmpName');
} set; }
}
Also lwcOut.app
will contain code of dummy lightning-out app
<aura:application access="GLOBAL" extends="ltng:outApp">
</aura:application>
In total, this approach would need 3 custom container-related component to serve any number of LWC components to be exposed ( 1 Apex Class, 1 Visualforce Page, 1 Lightning Out Standalone App).
One drawback of this approach that on switching tab currently selected tab is not marked as selected which is disappointing. However, I don't know how to fix that.
If someone finds more elegant or sophisticated solution please share.
You can use the data-
attribute of an HTML component.
Everything that is passed to data-*
attributes is converted to a
string.
<template>
<header class="header">
<h1 class="header_logo"><img src="" alt="Logo"></h1>
<ul class="header_nav">
<template for:each={megaMenuData} for:item="item">
<li class="nav-bar_list" key={item.name} onclick={openMega} data-item={item.name}>
</li>
</template>
</ul>
</header>
</template>
You can access the same using the event.target.dataset
of a js method. I have passed the item name as a data attribute and fetched using event.target.dataset
. Then I searched the item object using the find
method from the array.
openMega(event){
let itemname = event.target.dataset.item;
console.log(itemname);
let menuItemObject = this.megaMenuData.find(element => element.name === itemname)
console.log(JSON.stringify(menuItemObject));
}
Here is the playground demo.
Best Answer
I'm pretty sure, you would need to use the Lightning Out feature of the Aura framework. This would render an Aura Component App, which would then in turn render an Aura component wrapper around an LWC.
So essentially, the architecture would be:
Given React's strong ownership of the DOM and rendering, honestly, I'm not sure how well all of this would work together. For instance having LWC and the React app interact for instance.
If you think about this, it is the same interoperability structure as using an Aura component, just that you'd use the LWC in place of the Aura component.
My guess is that you'd hoped that there was some way to stand up LWC and have them work directly with React. That's not possible as of today.