Pass Data to a Custom Element (Beta)

Custom elements are the building blocks of third-party web components. Pass data to a custom element using an attribute, property, or the lwc:spread directive. When passing data, LWC sets the data as attributes by default, and sets properties only if they exist.

The constructor that initializes your shadow content using this.attachShadow({ mode: 'closed' }) is only invoked once. Consider these guidelines when working with an attribute or property.

After a third-party web component is rendered, attribute changes are ignored. To observe attributes and ensure the third-party web component renders your changes, use the observedAttributes() static getter and attributeChangedCallback() method. The attributeChangedCallback() callback runs when an observed attribute is changed. To handle serializing and deserializing of the attribute data, use a getter and setter such as in this example.

See an example that increments a button with an attribute change.

To work with properties, use a getter and setter.

For example, you have a custom element with a property that's passed to the custom element using the lwc:spread directive.

The custom element displays a button. To add an event listener to the button, use addEventListener().

Consider a parent component that contains a child component that defines a custom element. Pass the properties to a child component using the lwc:spread directive.

Use an object with key-value pairs.

In your child component, create an instance of the custom element.

Call the constructor() in your JavaScript and expose your properties to the parent component.

The custom element renders like this.

Passing markup to a slot in a third-party web component behaves similarly to a slot in an LWC component.

Slotting implementation for synthetic shadow is not supported in third-party web components.

Consider a third-party web component with some markup.

The following slotted content appears in the <slot> element.

The component renders in the DOM like this.

Similarly, you can use a named slot like this.

Include the named slot in your markup.

The component renders in the DOM like this.

In native shadow components, slotted content is preserved in top-level CustomElementConstructor elements.

For example, this top-level <slot> element in an index.html file includes slotted content.

The component renders in the DOM like this. It retains the original slotted content.

Events in third-party web components behave similarly with events in LWC. The event bindings support only lowercase events. To use events with non-lowercase names, add an event listener using the addEventListener() API.

Add your event listeners in the constructor().

A custom element that isn't registered renders as an instance of the native HTMLUnknownElement interface, which extends HTMLElement without adding any properties or methods. The browser then treats the external component as a native component no different from a span or a div.

For registered components, the engine renders the associated third-party web component and defers the upgrading to the browser.

For more information, see HTML Spec: Upgrading elements after their creation.

Additionally, consider these upgrade behaviors on third-party web components.

  • If a third-party web component is not upgraded, LWC sets its attributes on mount and on update.
  • If there's a delayed upgrade, the attribute is set instead of the property.
  • After the upgrade, the property is set instead of the attribute, if the property exists.

See Also