DEV Community

Pasquale De Lucia
Pasquale De Lucia

Posted on

Web Components Debut: My First Dive In

Recently, I had the opportunity to explore web components for the first time in my web development career. This adventure was inspired by @maxart2501's speech at Codemotion Milan 2023 and a new work challenge that required the implementation of a third-party payment method.

I fully understood their extraordinary potential, particularly the ability to create cross-framework components, eliminating the need to develop custom libraries for each framework.

You might think that the need for cross-framework components is rare, especially if you work in an environment where only one framework is used. However, many companies find themselves running multiple frameworks simultaneously, often with duplicate code to replicate the same widgets in different applications. Also, when considering open source libraries intended for use by third parties, the ability to support a wide range of frameworks becomes a significant advantage.

In my specific case, I am currently developing an open source library that I will soon share with the community (so stay tuned if you are interested). The decision to adopt web components was motivated by a desire to support as many frameworks as possible without having to know them all and without having to write specific code for each.

While this flexibility is certainly a strength, it is important to note that there is a disadvantage to using web components. Because everything is written in HTML, CSS, and vanilla JavaScript, it is not possible to take full advantage of the advanced features of some frameworks. However, this trade-off may be acceptable, especially when aiming to maximize compatibility and ease of use in a heterogeneous context.

I do not want to impose a specific perspective on the use of web components, but rather to offer a new perspective when approaching the development of something new. The ability to create cross-framework components can be a valuable ally in certain contexts, and my experience with web components has opened new perspectives in my approach to web development.

HELP

It should be acknowledged that if a large amount of data is to be transmitted to the web component, the approach is not particularly elegant, and the end result in the HTML looks as follows:
Image description

Currently, the only method I have identified for passing a complex object to my web component is to use JSON.stringify() to convert the object to a string and then parse the object within the web component using JSON.parse().

SMALL EXAMPLE

I prefer to avoid repeating common instructions on creating web components, since there are already numerous guides on the subject. Below, I present an example of an essential but working web component, designed as a starting point for anyone wishing to use it as a base:

class CustomComponent extends HTMLElement {
  static get observedAttributes() {
    return ['title']
  }

  attributeChangedCallback(name, oldValue, newValue) {
    switch (name) {
      case 'title':
     this.shadowRoot.querySelector('.component').innerHTML = newValue
        break
    }
  }

  constructor() {
    super()

    this.attachShadow({ mode: 'open' })

    this.shadowRoot.innerHTML = `
      <style>
      </style>  

      <div class="component">
      </div>
    `
  }

  get title() {
    return this.getAttribute('title')
  }

  set title(newValue) {
    this.setAttribute('title', newValue)
  }
}

customElements.define('custom-component', CustomComponent)
Enter fullscreen mode Exit fullscreen mode

To integrate it, simply import the .js file into your web platform and use the new HTML tag <custom-component title="Section title"></custom-component>.

Top comments (3)

Collapse
 
maxart2501 profile image
Massimo Artizzu

Hello Pasquale! Thank you for your kind words.

I may suggest that passing large, serialized objects into attributes is less than optimal, as it bloats your markup and you have to manually parse the data in the component. So you might prefer to get a reference to the element and pass the data as a property instead.

This requires JavaScript, of course, but it would be needed anyway. A simple inline <script> element is sufficient of you want to pass the data as soon as the page loads, but this approach would also allow you to hydrate your component later if needed. Of course, your component would need to handle missing data nicely and defer the action only when everything has been passed.

Collapse
 
nyruchi profile image
Pasquale De Lucia

Thanks so much, I'll definitely give it a try!

Collapse
 
dannyengelman profile image
Danny Engelman

Why would you want to pass HTML and SVG inside a JSON Object; just put it in lightDOM, need be in a <template>.

If this is SSR, just put the JSON Object in a <script> and init it from there.