Welcome to the Future of Web Development with Lightning Web Components! Web development is always changing, and web components have taken the spotlight by enabling reusable UI components that work seamlessly across different frameworks. Salesforce's Lightning Web Components (LWC) have embraced this trend, making it easier for developers to incorporate third-party web components. This comprehensive guide will show you how to integrate third-party web components in LWC (Beta).
How to Use Third-Party Web Components in LWC
You can integrate third-party web components using one of these two methods:
Upload as a Static Resource
Upload the component as a static resource.
Load it using the `loadScript` method from the `lightning/platformResourceLoader` module.
Add the custom element to your template using `lwc:external`.
Note: You can upload up to 5 MB per static resource, and an org can have up to 250 MB of static resources.
Add as an LWC Module
Create an LWC module with a `.js-meta.xml` configuration file
The JavaScript file for the component can be up to 128 KB in size
In this guide, we'll focus on the first solution. Here are the steps:
Steps to Use Third-Party Components in LWC
Step 1: Find and Download the Web Component
Find the web component you want to use. For this example, we'll use a `countdown-timer` web component.
Step 2: Upload as a Static Resource
Upload the downloaded JavaScript file of the web component as a static resource in Salesforce. You can see here I have uploaded the countdown-timer js file as a static resource.
Step 3: Create the LWC Component
Create an LWC component. In this example, we name it `ThirdPartyWebComponentInLWC`.
Step 4: Import and Load the Script
In your LWC component, import `loadScript` from `lightning/platformResourceLoader` and the uploaded JS file from static resources.
Step 5: Embed the Web Component Tag
Add the web component tag to your LWC HTML template. Use the `lwc:external` attribute to indicate that this is an external web component tag. Without `lwc:external`, LWC will throw an error. Full Demo Code
ThirdPartyWebComponentInLWC.JS
import {LightningElement, track} from 'lwc';
import {loadScript} from 'lightning/platformResourceLoader';
import CountDown from '@salesforce/resourceUrl/CountDown';
import {ShowToastEvent} from 'lightning/platformShowToastEvent';
import ERROR from "@salesforce/label/c.ERROR";
import LOAD_SCRIPT_ERROR from "@salesforce/label/c.LOAD_SCRIPT_ERROR";
import COUNT_DOWN_HEADING from "@salesforce/label/c.COUNT_DOWN_HEADING";
import COUNT_DOWN_MESSAGE from "@salesforce/label/c.COUNT_DOWN_MESSAGE";
import COUNT_DOWN_SUB_HEADING from "@salesforce/label/c.COUNT_DOWN_SUB_HEADING";
import COUNT_DOWN_LINK_TEXT from "@salesforce/label/c.COUNT_DOWN_LINK_TEXT";
import AVENOIR_GOOGLE_URL from "@salesforce/label/c.AVENOIR_GOOGLE_URL";
export default class ThirdPartyWebComponentInLWC extends LightningElement {
scriptLoaded = false
@track showTimer = false;
time;
label = {
COUNT_DOWN_HEADING : COUNT_DOWN_HEADING,
COUNT_DOWN_MESSAGE : COUNT_DOWN_MESSAGE,
COUNT_DOWN_SUB_HEADING : COUNT_DOWN_SUB_HEADING,
COUNT_DOWN_LINK_TEXT : COUNT_DOWN_LINK_TEXT,
AVENOIR_GOOGLE_URL : AVENOIR_GOOGLE_URL
}
renderedCallback() {
if(this.scriptLoaded) {
return;
}
else {
loadScript(this, CountDown)
.then(() => {
this.getCurrentDateTimePlusTwoMinutes();
this.scriptLoaded = true;
this.showTimer = true;
})
.catch((error) => {
this.showToastEvent(
ERROR,
LOAD_SCRIPT_ERROR,
ERROR
);
})
}
}
getCurrentDateTimePlusTwoMinutes() {
let now = new Date();
now.setMinutes(now.getMinutes() + 1);
let year = now.getFullYear();
let month = String(now.getMonth() + 1).padStart(2, '0');
let day = String(now.getDate()).padStart(2, '0');
let hours = String(now.getHours()).padStart(2, '0');
let minutes = String(now.getMinutes()).padStart(2, '0');
let seconds = String(now.getSeconds()).padStart(2, '0');
this.time = `${year}-${month}-${day}T${hours}:${minutes}:${seconds}`;
}
showToastEvent(title, message, variant) {
this.dispatchEvent(
new ShowToastEvent({
title: title,
message: message,
variant: variant
})
);
}
}
ThirdPartyWebComponentInLWC.html
<template>
<lightning-card icon-name="standard:account">
<template if:true={scriptLoaded}>
<template if:true={showTimer}>
<countdown-timer date={time} heading={label.COUNT_DOWN_HEADING} subheading={label.COUNT_DOWN_SUB_HEADING}
message={label.COUNT_DOWN_MESSAGE} link={label.AVENOIR_GOOGLE_URL} linktext={label.COUNT_DOWN_LINK_TEXT}
lwc:external></countdown-timer>
</template>
</template>
</lightning-card>
</template>
ThirdPartyWebComponentInLWC.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>61.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
</targets>
</LightningComponentBundle>
Step 6: Use the LWC Component
You can now use this LWC component as needed. In our case, we’re using it on an AppPage.
These are the screenshots of the final output:-
Count Down Started
Count Down Running
Count Down Finished
Known Issues and Limitations
As this feature is in Beta, there are several known issues and limitations:
Shadow DOM: Only closed shadow mode is supported. If the third-party web component uses open mode, you’ll need to update it to close mode or work with a component that doesn’t use shadow DOM.
Script Loading: loadScript doesn’t support ECMAScript modules. Only pre-bundled JavaScript files in legacy formats like IIFE or UMD are supported.
Dependencies: Third-party web components with npm dependencies or those requiring compilation and bundling aren’t supported. Importing from npm is not currently supported.
Element References: Components that reference elements by ID using a document.getElementById('some-id') isn’t supported in shadow DOM. Use template refs instead.
Experience Builder Sites: Experience Builder sites don’t support third-party web components when LWS is enabled.
Conclusion
The ability to use third-party web components in LWC opens up a world of possibilities for Salesforce developers. While there are some limitations and known issues, the flexibility and reusability offered by web components can significantly enhance your Salesforce applications. As this feature evolves beyond its Beta phase, it’s expected to become even more robust and versatile. Happy coding!
If you'd like to see the code and resources used in this project, you can access the repository on GitHub.To access the AVENOIRBLOGS repository, click here. Feel free to explore the code and use it as a reference for your projects.
Thank You! You can leave a comment to help me understand how the blog helped you. If you need further assistance, please contact us. You can click "Reach Us" on the website and share the issue with me.
Reference
Blog Credit:
S. Chaudhary
Salesforce Developer
Avenoir Technologies Pvt. Ltd.
Reach us: team@avenoir.ai
Comments