TypeScript (Developer Preview)
Use Third-Party Web Components in LWC
Work with Custom Elements
Pass Data to a Custom Element
Append Styles to a Custom Element
Mobile-Ready Components
Develop Secure Code
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.
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.
Be aware of 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.
See Also
Release Preview