DEV Community


Discussion on: Webcomponents: It's really that easy!

justinfagnani profile image
Justin Fagnani

What is the purpose of using a <template> in your example? You never clone it, you're just getting it's innerHTML as a string. This makes it a very expensive string holder.

You could simplify what you have to roughly this without the template:

export class AllCaps extends HTMLElement {
    constructor() {
        this.attachShadow({mode: 'open'});
        let toUpper = this.firstChild.nodeValue.toUpperCase();
        this.shadowRoot.innerHTML = `
             color: red;
Enter fullscreen mode Exit fullscreen mode

But not that with both a <slot> and copying the text content, you'll be displaying the content twice. You're also reading the attribute in the constructor, but it may not be set there yet.

dannyengelman profile image
Danny Engelman • Edited

Or maybe simplify it to:

<all-caps>this is uppercase</all-caps>
  customElements.define("all-caps", class extends HTMLElement {
    constructor() {
      const toUpper = x => x.firstChild.nodeValue.toUpperCase();
      const style = "<style>:host{color:red}</style>";
        .attachShadow({mode: "open"})
        .innerHTML = style + toUpper(this);
Enter fullscreen mode Exit fullscreen mode
sroehrl profile image
neoan Author

Yes, you are absolutely right. As mentioned in several disclaimers throughout this post, this is not the structure you would go for. This example element is meant to introduce several concepts and by no means represents an actual custom element.
I carefully chose this setup to accommodate for progression throughout this tutorial and made some crude decisions to maintain overview yet somewhat of a separation.
As I am also concerned about potential readers imitating such a pattern: do you think I haven't mentioned used anti-patterns enough, or is your feedback only based on the actual code snippets?

Forem Open with the Forem app