Custom Element
Embed a web component as a Liferay widget.
# description
Registers an HTML custom-element tag as a Liferay widget. Liferay handles the widget lifecycle, friendly URLs, and menu category; your extension only ships JS that defines the element and (optionally) CSS. Custom Element is the primary path to embedding modern web components — React, Vue, LitElement, Svelte, or vanilla `HTMLElement` classes — inside Liferay DXP without writing a portlet. Liferay renders your `<my-tag>` element on the page with a unique instance id per placement, so component state stays scoped to each widget instance. Widgets appear in Liferay's widget menu under the `portletCategoryName` you specify (default: `category.client-extensions`).
UI extensions that render on Liferay pages or modify page appearance.
# when to use
- →You want to ship a React / Vue / vanilla web component to Liferay pages.
- →You need per-page-instance widgets that users can add via the widget menu.
- →You already have a component and want to expose it inside DXP without writing a portlet.
# how to use
- 01Build your component as an ES module that calls
customElements.define('my-tag', MyClass). - 02Deploy the built JS bundle behind
${portalURL}/o/<name>/index.js(assemble it understatic/). - 03Reference it in
urls:and put the tag name inhtmlElementName:. - 04Users add the widget from the widget menu; instances render your tag with a unique id.
# required fields
| field | type | description |
|---|---|---|
htmlElementNamerequired | string | The HTML tag Liferay renders on the page. |
urlsrequired | string[] | JS module URLs; at least one must define + register the element. |
# optional fields
| field | type | description |
|---|---|---|
name | string | Display name in the widget menu. |
cssURLs | string[] | CSS added to <head> when the widget is on the page. |
friendlyURLMapping | string | Friendly-URL prefix for widget state. |
instanceable | boolean | Allow multiple instances on the same page. |
portletCategoryName | string | Category in the widget menu. |
properties | string[] | Attributes to add to the rendered element, e.g. ["theme=dark"]. |
useESM | boolean | Load urls with type="module". |
# example
my-widget:
type: customElement
name: My Widget
htmlElementName: my-widget
urls:
- ${portalURL}/o/my-widget/index.js
cssURLs:
- ${portalURL}/o/my-widget/styles.css
instanceable: false
portletCategoryName: category.client-extensions
useESM: true