URL Addressable Lightning Web Components (LWC)

by Jeff Cook, Trail Two

One of the many annoying limitations of Salesforce Lightning Web Components (LWC) is the inability to directly address the component via a composable URL.

You might have faced this issue and used some of the common work arounds such as wrapping the LWC in an Aura Component or created a Lightning App Page to get around this limitation. While this works, it seems like we can do better than creating wrappers for every one of our Lightning Web Components.

Well, we can!

By using a simple reusable Aura component, you will be able to wrap all of your Lightning Web Components and open up a whole new world of reusability!

When I mentioned that Lightning Web Components (LWC) are not URL addressable, that isn’t exactly true. You can hit an LWC, but you need an encoded Page Reference to add to the URL.

<your salesforce domain>/one/one.app#<your encoded page reference>

Example: <your salesforce domain>/one/one.app#eyJjb21wb25lbnREZWYiOiJUMkRvY3M6ZG9jdW1lbnRNZXJnZSIsImF0dKJpYnV0ZXMiOnsiY19fbHdjKjoiVDJEb2NzOmRvY3VtZW50TWVyZ2UiLCJjX19pZCI6IjAwNjUyMDAwMDBFTDE2T0FBVCIsImNfX2RvY3VtZW50RGV2ZWxvcGVyTmFtZSI6IkNPUl9EZXNpZ25fQWdyZWVtZW50X1KlbXBsYXRlIn0sInN0YXRlIjp7fX0%3D

Not exactly human readable (nor something you can construct in a URL field) but this is the key to enable our Addressable LWC Wrapper.

We will start by creating an Aura component. This will be a single Aura component that we can use to wrap all of our Lightning Web Components.

force-app/main/default/aura/AddressableLWC.cmp

  <aura:component implements="lightning:isUrlAddressable" description="c:AddressableLWC component">
	<aura:handler name="init" value="{!this}" action="{!c.init}"></aura:handler>
	<aura:handler name="change" value="{!v.pageReference}" action="{!c.init}"></aura:handler>
	<lightning:navigation aura:id="navService"></lightning:navigation>
</aura:component>

We need to implement lightning:isUrlAddressable (duh!) and ensure we have the “init” and “change” handlers defined to ensure our Aura component works properly. We also need to include Lightning Navigation Service to redirect to our LWC.

You can create a URL to this component and pass parameters. One of the parameters will be the name of the Lightning Web Component.

<your salesforce domain>/lightning/cmp/c__AddressableLWC?c__lwc=<lwc name>&<parameter>=<value>…

force-app/main/default/aura/AddressableLWC.js

  ({
    init : function(component, event, helper) {
		let pageRef = component.get("v.pageReference");

		let encodedCompDef = btoa(
			JSON.stringify({
				componentDef: pageRef.state.c__lwc,
				attributes: pageRef.state
			})
		);

		component.find("navService").navigate(
			{
				type: "standard__webPage",
				attributes: {
					url: "/one/one.app#" + encodedCompDef
				}
			},
			true
		);
    }
})

AddressableLWC javascript controller explained

We first get the PageReference so we can access the parameters passed to the AddressableLWC Aura Component.

Next, we construct a JSON Page Reference with the componentDef set to the Lightning Web Component Name, and pass along the rest of the parameters in the Page Reference state to the Aura Component in the attributes property.

We then encode the Page Reference using the javascript function bota(), Binary String to ASCII String.

  let pageRef = component.get("v.pageReference");

let encodedCompDef = btoa(
  JSON.stringify({
    componentDef: pageRef.state.c__lwc,
    attributes: pageRef.state
  })
);

Finally, we use the Navigation Service to navigate to the LWC using the constructed URL for Lightning Web Components

  component.find("navService").navigate(
  {
    type: "standard__webPage",
    attributes: {
      url: "/one/one.app#" + encodedCompDef
    }
  },
  true
);

Note: The second parameter for the Navigation Service, “replace”, is set to true. This ensures that the window for the initial navigation to the Aura Component is replaced with the navigation to the Lightning Web Component.

Putting it Together

Lets create a simple Lightning Web Component to test our AddressableLWC Aura Component.

force-app/main/default/lwc/helloWorld.html

  <template>
    <lightning-card title="Addressable LWC Hello World Example">
      {c__data}
    </lightning-card>
</template>

force-app/main/default/lwc/helloWorld.js

  import { LightningElement, api } from 'lwc';

export default class HelloWorld extends LightningElement {
    @api
	c__data;
}

force-app/main/default/lwc/helloWorld.js-meta.xml

  <?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>50.0</apiVersion>
    <isExposed>true</isExposed>
</LightningComponentBundle>

We can now address our helloWorld Lightning Web Component using the following URL:

<your salesforce domain>/lightning/cmp/c__AddressableLWC?c__lwc=c:helloWorld&c__data=Hello World!

One Lightning Web Component Aura Wrapper to RULE THEM ALL!

Previous
Previous

DevOps[0]: The one with consistent formatting

Next
Next

Salesforce Mobile App Improvement for Uploading Files