TypeScript (Developer Preview)
Use Third-Party Web Components in LWC (Beta)
Work with Custom Elements (Beta)
Pass Data to a Custom Element (Beta)
Append Styles to a Custom Element (Beta)
Mobile-Ready Components
Develop Secure Code
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.
Note
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.
Note
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.
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..js-meta.xml configuration file. A component's JavaScript file can have a maximum file size of 1 MB (1,000,000 bytes).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.
1<!--externalExample.html-->
2<template>
3 <p>
4 Relative time (auto-updated every minute):
5 <relative-time datetime={date} lwc:external></relative-time>
6 </p>
7</template>Import the static resource using the loadScript function from lightning/platformResourceLoader. When the script is loaded, you can initialize the properties for the component.
1//externalExample.js
2import { LightningElement } from "lwc";
3import { loadScript } from "lightning/platformResourceLoader";
4import timeElements from "@salesforce/resourceUrl/timeElements";
5
6export default class extends LightningElement {
7 isCmpInitialized = false;
8 error;
9 date;
10
11 async renderedCallback() {
12 if (this.isCmpInitialized) {
13 return;
14 }
15 this.isCmpInitialized = true;
16
17 try {
18 await loadScript(this, timeElements);
19 this.initializeComponent();
20 } catch (error) {
21 this.error = error;
22 }
23 }
24 initializeComponent() {
25 this.date = new Date();
26 }
27}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.
Tip
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.
1<!-- popupInfo.html -->
2<template>
3 <popup-info
4 lwc:external
5 img={logo}
6 data-text="Here's some popup text for your logo'"
7 ></popup-info>
8</template>In your JavaScript file, create a shadow root and define your element. 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. For more information on custom element syntax, see Work with Custom Elements (Beta).
1//popupInfo.js
2import { LightningElement } from "lwc";
3import trailheadLogo from "@salesforce/resourceUrl/trailhead_logo";
4
5// Create a class for the element
6class PopUpInfo extends HTMLElement {
7 constructor() {
8 // Always call super first in constructor
9 super();
10
11 // Create a shadow root
12 this.shadow = this.attachShadow({ mode: "closed" });
13 }
14
15 connectedCallback() {
16 // Create spans
17 const wrapper = document.createElement("span");
18 wrapper.setAttribute("class", "wrapper");
19
20 const icon = document.createElement("span");
21 icon.setAttribute("id", "test");
22 icon.setAttribute("class", "icon");
23 icon.setAttribute("tabindex", 0);
24
25 const info = document.createElement("span");
26 info.setAttribute("class", "info");
27
28 // Take attribute content and put it inside the info span
29 const text = this.getAttribute("data-text");
30 info.textContent = text;
31
32 // Insert icon
33 const img = document.createElement("img");
34 img.src = this.hasAttribute("img") ? this.getAttribute("img") : `{$logo}`;
35 icon.appendChild(img);
36
37 // Create some CSS to apply to the shadow dom
38 const style = document.createElement("style");
39
40 style.textContent = `
41 .wrapper {
42 position: relative;
43 }
44 .info {
45 font-size: 0.8rem;
46 width: 200px;
47 display: inline-block;
48 border: 1px solid black;
49 padding: 10px;
50 background: white;
51 border-radius: 10px;
52 opacity: 0;
53 transition: 0.6s all;
54 position: absolute;
55 bottom: 20px;
56 left: 10px;
57 z-index: 3;
58 }
59 img {
60 width: 1.2rem;
61 }
62 .icon:hover + .info, .icon:focus + .info {
63 opacity: 1;
64 }
65 `;
66
67 // Attach the created elements to the shadow dom
68 this.shadow.appendChild(style);
69 this.shadow.appendChild(wrapper);
70 wrapper.appendChild(icon);
71 wrapper.appendChild(info);
72 }
73}
74
75// Register the new element
76customElements.define("popup-info", PopUpInfo);
77
78export default class PopupInfo extends LightningElement {
79 logo = trailheadLogo;
80}While we don't recommend using JavaScript manipulating the DOM, some third-party web components manipulate the DOM using Web APIs like appendChild and removeChild. For an alternative way to interact with a third-party web component using template directives, see Example: Generate a Square with Random Attributes.
This beta release comes with several known issues.
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).document.getElementById('some-id'), LWC can't access the global HTML document. Use template refs where possible.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.
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.<template> tags only. If the third-party component requires a nested <template> tag, use document.createElement('template') in your JavaScript file instead.addEventListener().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).
See Also