Metal.js HomeMetal.js
  • Documentation
Docs Menu
  • Tutorials
    • Todo App: JSX
    • Todo App: Soy
  • Guides
    • Alias
    • State
    • Component Lifecycle
    • Rendering Components
    • Inline Events
    • Importing a Third Party Component
    • Soy Components
    • JSX Components
    • Portals
    • Progressive Enhancement
    • Yeoman Generator
    • Building
    • Performance
    • Web Components
    • Isomorphic Rendering

Web Components Guide

Web Components

Metal components are generally invoked in one of three ways:

  • JavaScript
new metal.MyComponent({
    title: 'Hello, World!'
}, '#element');
  • Soy
{call MyComponent.render}
    {param title: "Hello, World!" /}
{/call}
  • JSX
<MyComponent title="Hello, World" />

However, with the help of the metal-web-component package, Metal components can be invoked as Custom Elements in plain HTML.

<my-component title="Hello, World"></my-component>

Install

First you must install the metal-web-component package:

npm i --save metal-web-component

Currently, web components don't work on every browser, so a polyfill must be used. Include the webcomponents-lite polyfill if you intend to use web components on Firefox, Edge, or IE11.

Define web components

This package exposes a single helper function that can be used to wrap any Metal component in a web component. It receives two arguments: the tag name you want the web component to receive, and the constructor of the Metal component:

import JSXComponent from 'metal-jsx';
import defineWebComponent from 'metal-web-component';

class MyComponent extends JSXComponent {
    render() {
        return <h1>{this.props.message}</h1>
    }
}

MyComponent.PROPS = {
    message: {
        value: ''
    }
};

defineWebComponent('my-component', MyComponent);

Now that the web component is defined, it can be invoked in plain html:

<my-component message="This is a web component"></my-component>

This results in the following HTML on the page:

<h1>This is a web component</h1>

If you would like the component's markup to be rendered using the Shadow DOM, simply set the useshadowdom attribute to true when calling the web component:

<my-component message="This is a web component" useshadowdom="true"></my-component>

This means that any styling on the page will not cascade to your component's markup. See MDN's documentation for more info.

Contribute on Github! Edit this section.