Using Web Components in Angular, React, Preact, Vue and Svelte
Web Components allow us to build reusable, customizable elements. A web component’s greatest strength is its interoperability: being natively supported by browsers, web components can be used in any HTML environment, with any framework, or with no framework at all.
A major aspect of web components is encapsulation. You can separate and hide markup structure, style, and behavior so that different page parts don’t clash.
Therefore, web components are perfect for developing design systems, shareable components, and embedded widgets. Let’s look at how to use a native web component with the top libraries in the industry:
Create Web Components with Lit
Building a web component from scratch in plain Javascript can quickly become a huge mess that’s hard to scale and maintain. Luckily, we can build fast, lightweight web components with the help of Lit.
At Lit’s core is a boilerplate-killing component base class that provides reactive state, scoped styles, and a declarative template system that’s tiny, fast, and expressive.
Even though we’ll be using Lit, I recommend learning how to develop web components using native JS.
Let’s build a minimal custom select
element and see how we can work with primitive and object input values. Please note that we’ll not discuss building tools. You are free to use whatever you wish.
Let’s start with the select
element:
We create a SelectElement
and define three inputs — The data
, idKey
, and valKey
. We also define an activeItem
state to track the currently selected item. Let’s add the template:
We use the repeat directive to render our elements efficiently. It receives three parameters — The collection
, a keyFunction
that takes a single item as an argument and returns a unique key for it, and an itemTemplate
that takes the item and its current index as arguments and returns a TemplateResult
.
Clicking on an item sets it as the active item and dispatches a custom event that the parent can listen to.
We use a nice feature from Lit called boolean attribute expressions. The active
attribute will be added or removed based on the result of the expression. We use it to style the active
element.
You may find this library useful if you’re looking for a lit file generator:
Now that we have a basic custom element, let’s use it in each library:
Using Web Components in Angular
First, we need to use the CUSTOM_ELEMENTS_SCHEMA
schema. Angular ignores custom elements (named with dashes) that it doesn’t recognize rather than throwing an error.
Now we can use our ui-select
web component inside the TodosComponent
component:
There’s not much we need to do. Angular integration with custom elements works out of the box. It binds the todos
component property to the data
property in the ui-select
element. The event binding listens for the select-item
event and calls the component’s onSelectItem()
method whenever it’s dispatched.
Using Web Components in Vue
As with Angular, we need to tell Vue to ignore custom elements so that it won’t throw errors when it encounters a custom element. Here’s how we can do that in Vite:
See the docs for alternative approaches. Now we can use our custom element inside our component:
Vue makes it a breeze to use custom elements. We bind the element’s data
property to the todos
ref and listen for the select-item
event, which runs the onSelect
function when it is dispatched.
Using Web Components in Svelte
To use custom elements in Svelte components, we don’t need to do anything special. Import the custom element and use it:
Using Web Components in React
React has the least friendly support for custom elements. Let’s see how we use it with React:
As custom elements aren’t React components, they’re treated as standard HTML elements. We need to use JSON.stringify
because the data
attribute value is treated as a string. Lit will handle the parsing since we set the data
property converter to an Array
.
We need to get a reference to the custom element and register the event manually because React doesn’t support custom elements events.
To make it a bit cleaner, you can use libraries such as use-custom-element:
Using Web Component in Preact
Preact’s support for web components is much better than React. The renderer of Preact determines whether to use a property or attribute by inspecting the DOM element.
Unrecognized event handler props passed to a DOM Element are registered using their casing exactly as specified:
Follow me on Medium or Twitter to read more about Angular and JS!