People working on laptops

Lightning Web Components Dynamic Import and URL-Addressable

by Nikita Verkhoshintcev

I'm glad the Lightning Web Component framework constantly evolves, improving user and developer experience.

Recently, I completed a JavaScript certification maintenance module on Trailhead and had a chance to try out some of the new features.

In this post, I want to share a few of the latest Lightning Web Components framework updates that I find interesting.

Dynamic Component Import

One of the most exciting updates is the introduction of lazy loading in the LWC framework. That means components are only loaded when needed, reducing the initial load time and improving overall performance.

It is essential for large and complex component architectures.

I worked with customer applications that had substantial and interactive components, such as UI builders and custom data tables.

In those cases, from the UX perspective, users only need some components loaded and initialized when they first access the application.

With dynamic imports, we can improve the performance and user experience by deferring the initialization of some modules.

The typical scenario could be a lightning component with multiple tabs. You only need to load all components in the hidden tabs once users access them.

Another use case could be making the components more dynamic so that they load specific modules based on the enabled features or configurations.

For example, I tried to dynamically load components based on the config set in the page builder.

Unfortunately, it didn't work.

The important part is that the code for importing must be statically analyzable. It means that it doesn't allow the use of variables.

You can dynamically import LWC only using string literals, like import('c/componentName').

You can still have a switch or a set of if statements to load components based on the config with predefined values. However, in this case, whenever you want to load or introduce a new component, you need to include its name in the source code.

import { LightningElement, api } from "lwc";

export default class MyComponent extends LightningElement {
  @api config;

  componentConstructor;

  handleComponentLoad({ default: ctor }) {
    this.componentConstructor = ctor;
  }

  connectedCallback() {
    if (this.config?.featureA) {
      import("c/featureA").then(this.handleComponentLoad);
    }
    if (this.config?.featureB) {
      import("c/featureB").then(this.handleComponentLoad);
    }
  }
}

Another cool thing is that dynamic import supports different namespaces. It can be helpful when working with packages.

For example, you can have a core package with an extendable component that dynamically injects components from your satellite packages installed in the Salesforce organization.

For more details on the LWC dynamic imports, please refer to Lightning Web Components Developer Guide.

URL-Addressable Components

Another exciting update is that lightning navigation now supports lightning web components as targets.

Important note: this feature does not work with the Experience Cloud sites because it interferes with the custom domains.

Ensure the component you want to make URL-addressable has the isExposed property set to true and add the lightning__UrlAddressable target to the .js-meta.xml.

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

You can navigate to the component via NavigationMixin. Create a method to navigate to the component and use the type standard__component. Set the component name attribute with the namespace prefix and pass state variables if needed.

import { LightningElement } from 'lwc';
import { NavigationMixin } from 'lightning/navigation';

export default class NavToComponentWithState extends NavigationMixin(LightningElement) {
  navigateToComponent() {
    this[NavigationMixin.Navigate]({
      type: 'standard__component',
      attributes: {
        componentName: 'c__myComponent',
      },
      state: {
        'c__propertyValue: '2000',
      },
    });
  }
}

As a result of that method, the system generates the URL for the component like /lightning/cmp/c__myComponent?c__propertyValue=2000 and redirects you there.

Note that it passes all state properties as string query parameters in the URL. It means that you can read those via CurrentPageReference.

import { LightningElement, wire, api } from "lwc";
import { CurrentPageReference } from "lightning/navigation";

export default class MyComponent extends LightningElement {
  @wire(CurrentPageReference)
  currentPageRef;

  @api propertyValue;

  get propertyValue() {
    return this.currentPageRef.state.c__propertyValue;
  }
}

Conclusion

I shared new LWC capabilities in this post, such as dynamic component import and URL addressable components.

The dynamic import allows you to improve your applications' performance by offloading the component initialization of unneeded modules and making existing components more dynamic and extendable.

With the URL-addressable feature, you can now expose lightning components via URL and directly access these components via lightning navigation without relying on the aura components.

I'm keen to use those great new features in my Salesforce projects.

Nikita Verkhoshintcev photo

Nikita Verkhoshintcev

Salesforce Freelance Developer / Solution Architect

I'm a senior freelance Salesforce and full-stack web developer based in Helsinki, Finland. I help companies, consulting agencies, and ISV partners build custom Salesforce applications.

Let's work together!

We help Salesforce customers and SI/ISV partners build custom Salesforce applications. Let's discuss how we can help you!

Contact us