Search code examples
javascriptecmascript-6web-component

What is the difference between window.customElements.define() and document.registerElement()


I have been reading some tutorials about web components (native, no polymer). I have seen two ways to register components and I'm a bit confused what to use. For the second one I actually receive a typescript error in vscode: [ts] Property 'registerElement' does not exist on type 'Document'. Did you mean 'createElement'?

/**
 * App
 */
export class App extends HTMLElement {

    constructor() {
        super();
    }

    connectedCallback() {
        this.innerHTML = this.template;
    }

    get template() {
        return `
        <div>This is a div</div>
        `;
    }
}

// What is the difference between these two methods?
window.customElements.define('vs-app', App);
document.registerElement('vs-app', App);

Solution

  • In terms of results, they accomplish pretty much the same. However, Document.registerElement() is deprecated, so you should use CustomElementRegistry.define() instead.

    In my eyes, the key difference is that .registerElement() returns a constructor for the new element, whereas .define() allows you to specify the constructor, allowing for greater versatility. Consider the folowing examples:

    var MyElement = document.registerElement('me-me');
    document.body.appendChild(new MyElement());
    var myElement = document.getElementsByTagName('me-me')[0];
    myElement.textContent = 'I am a custom element.';
    

    class MyElement extends HTMLElement {
      connectedCallback() {
        this.textContent = 'I am a custom element.';
      }
    }
    customElements.define('me-me', MyElement);
    document.body.appendChild(new MyElement());
    

    As you can see, using .define() allows you to specify the inner text beforehand, whereas you have to manually specify the text in the case of .registerElement(). Provided this is a very simple example to showcase my point, using .define(), you can add a lot more to the default behavior, appearance and content of a custom element than you can with .registerElement().