0

The lightning/navigation service doesn't support lightning out. Does anyone have a technique to detect that a LWC is running within Lightning out Visualforce and provide the correct navigation. The goal here is to have a single LWC component that functions correctly in both Lightning Experience and Classic. Believe this would allow us to migrate functionality to the Lightning experience but continue to allow users to work in classic.

Thanks!

1 Answer 1

4

As far as I have searched documentation, there is no standard way of knowing in which container a component is being loaded.

Solution: We can create a @api property called container through which we can tell the component about the container it is being loaded in. You can check the below sample LWC component which has been designed for both visualforce and lightning:

HTML:

<template>
    <div>
        recordPageUrl - {recordPageUrl}
    </div>
    <div>
        <a href={recordPageUrl}>Go to Url</a>
    </div>
    <div>
        <lightning-button label="Navigate to account" onclick={navToAcc}></lightning-button>
    </div>
</template>

JS:

import { LightningElement, wire, api, track } from 'lwc';
import { NavigationMixin } from 'lightning/navigation';

export default class Poc extends NavigationMixin(LightningElement) {
    @api container = 'Lightning';
    @track recordPageUrl;
    pageRef = {
        type: 'standard__recordPage',
        attributes: {
            recordId: '0010K00001eKzKgQAK',
            actionName: 'view',
        },
    };

    connectedCallback() {
        switch (this.container) {
            case 'Lightning':
                this[NavigationMixin.GenerateUrl](this.pageRef).then(url => {
                    this.recordPageUrl = url;
                }).catch(err => {
                    console.error("ERROR => ", JSON.stringify(err))
                });
                break;
            case 'Visualforce':
                this.recordPageUrl = '/0010K00001eKzKgQAK';
                break;
            default:
                console.error('container context not provided');
        }
    }

    navToAcc() {
        switch (this.container) {
            case 'Lightning':
                this[NavigationMixin.Navigate](this.pageRef);
                break;
            case 'Visualforce':
                window.open('/0010K00001eKzKgQAK');
                break;
            default:
                console.error('container context not provided');
        }
    }
}

We are saying it will be loaded in Lightning by default unless stated other-wise.

When loading the component in visualforce, we can specify it as 'Visualforce' container:

vf page:

<apex:page >
    <apex:includeLightning />

    <div id="lightningvf" />

    <script>
        $Lightning.use("c:TestCompApp", function() {
          $Lightning.createComponent("c:poc",
              { container:'Visualforce' },
              "lightningvf",
              function(cmp) {
                console.log("poc was created");
                // do some stuff
              }
          );
        });
    </script>
</apex:page>

added based on comments

You can use NavigationMixin for navigations in LWC. As shown in documentation you should be using methods Navigate for immediate navigation and GenerateUrl for getting the nav URLs for navigating later

2
  • Thank you! Appear to be what I am looking for. The connectedCallback() method fires when this component is added to the DOM. Can you please speak a little more about this segment of code and what it is doing. do not fully understand. 'this[NavigationMixin.GenerateUrl](this.pageRef).then(url => { this.recordPageUrl = url; }).catch(err => { console.error("ERROR => ", JSON.stringify(err)) }); also any chance you can provide an example where the recordId is dynamic. Imagine list selection.. THANK YOU!! Commented Aug 23, 2019 at 21:51
  • added in answer at last Commented Aug 24, 2019 at 3:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .