Use Third-Party Web Components in LWC (Beta)

This feature is a Beta Service. Customer may opt to try such Beta Service in its sole discretion. Any use of the Beta Service is subject to the applicable Beta Services Terms provided at Agreements and Terms.

Use third-party web components in an LWC app. Third-party web components render as native web components in LWC templates. Although you can use third-party web components in an LWC template file using an iframe or lwc:dom="manual", we recommend rendering the third-party web component as native web components in your LWC templates using lwc:external.

Salesforce doesn't provide support for third-party web components. Documentation and examples that demonstrate using a third-party web component don't constitute an endorsement of the third-party web component. We recommend that you check the third-party web component documentation for usage information.

Third-party web components can be of various JavaScript frameworks or those written in pure vanilla JS. The MDN web components are examples of third-party web components that you can use with the LWC framework. Similarly, webcomponents.org provides a collection of web components that are based on custom elements and shadow DOM standards.

If you're working with third-party JavaScript libraries, see Use Third-Party JavaScript Libraries instead.

Before you use a third-party web component, we recommend that you check AppExchange for third-party LWC apps or components and install a managed package with your desired functionality. Alternatively, check if a base component is suitable for your requirements.

To use non-LWC third-party web components, follow one of these solutions.

  • Upload the files as a static resource and load the component using the loadScript method from the lightning/platformResourceLoader module. You can upload up to 5 MB per static resource. An org can have up to 250 MB of static resources.
  • Add a third-party web component as an LWC module with a .js-meta.xml configuration file. A component's JavaScript file can have a maximum file size of 128 KB.

This beta release comes with several known issues.

  • Only the attachShadow({ mode: "closed" }); closed shadow root is supported for third-party web components using shadow DOM. If the third-party web component uses an open mode, update the source to make the component LWS compliant. Alternatively, work with a third-party web component that doesn't use shadow DOM. See Light DOM.
  • loadScript doesn't currently support ECMAScript Modules (ESM). For example, <script type="module"> isn't supported. Import third-party web components using pre-bundled JavaScript files with custom elements in a legacy format such as IIFE (Immediately-Invoked Function Expression) or UMD (Universal Module Definition).
  • Third-party web components with npm and other dependencies or those that require compilation and bundling aren't supported. LWC doesn't currently support importing from npm.
  • Third-party web components that reference an element by ID aren't supported in shadow DOM. For example, if the component uses document.getElementById('some-id'), LWC can't access the global HTML document. Use template refs where possible.
  • Experience Builder sites don't currently support third-party web components when LWS is enabled.
  • Lightning Web Security doesn't currently support customized built-in elements using the extends option. Customized built-in elements are also not supported in WebKit browsers such as Safari. To learn more about what you can do in a class that extends HTMLElement, see HTML Spec: Custom Elements.

Follow these guidelines when working with third-party web components.

  • Pass data to a third-party web component using an attribute, property, or the lwc:spread directive. When passing data to the web component, LWC sets the data as attributes by default, and sets properties only if they exist.
  • Pass markup to a slot in a third-party web component similar to passing markup to a slot in a Lightning web component. Slotting for synthetic shadow isn’t supported in third-party web components.
  • LWC templates support root <template> tags only. If the third-party component requires a nested <template> tag, use document.createElement('template') in your JavaScript file instead.
  • Declarative event bindings in the LWC template can use lowercase event names only. If the third-party web component uses non-lowercase characters or a hyphen in an event name, add the event listener programmatically using addEventListener().
  • Observe attribute changes after a third-party web component is rendered by using observedAttributes() and attributeChangedCallback().
  • lwc:external doesn't support dynamic component creation. Custom elements are rendered similarly to a Lightning web component and native HTML elements.

For more information, see Pass Data to a Custom Element (Beta).

The third-party web component in this example is similar to the lightning-relative-date-time base component. Check if a base component meets your requirements before using a third-party web component.

This example uses the time-elements JavaScript file, which is available as an IIFE.

time-elements provides several web components - local-time, relative-time, time-ago, and time-until.

Before you can use any of these web components, upload the JavaScript file as a static resource in your org. In this example, the name of the static resource is timeElements.

Import the static resource using the loadScript function from lightning/platformResourceLoader.

The third-party web component in this example is similar to the lightning-helptext base component. Check if a base component meets your requirements before using a third-party web component.

This example uses the popup-info component from MDN. To add the component as an LWC module, create a Lightning web component in the force-app/main/default/lwc folder. Let's name it popupInfo.

In your template, include the lwc:external directive on the popup-info element.

In your JavaScript file, make sure you create a shadow root in closed mode. This example uses a trailheadLogo static resource on which the popup-info attaches. It also replaces the "img/default.png" image path with {$logo}, which references the logo that's uploaded as a static resource.

See Also