Using Web Components and HTMX

A little excursion in using Web Components with and in HTMX. The results will... confuse you (or me).

I was wondering if Web Components are rendered automatically when they appear in an HTMX response, or if I need to "activate" them somehow. Yes, they are rendered when they are added to the DOM, which is great. Simply send them, and they will take care of themselves.

In the following Codepen demo, I reused my HTMX/Bootstrap tabs demo and return two custom HTML elements. First Paul Irish's lite-youtube-embed and second a custom element that renders a list of my Github Gists.

<lite-youtube videoid="RgA81-HvXVE" playlabel="Play"></lite-youtube>
<mo-gist username="marcus-at-localhost"></mo-gist>

I guess the next step is to figure out when not to use Web Components, what's up with the shadow DOM, and whether it's all worth it. (see the update below)

When I consider the previous usage, the lite YouTube embed is a perfect fit for Web Components. A single element that improves HTML (rather than using <iframe>).

On the other hand, my list of the most recent GitHub Gists is doing too much and is possibly not flexible enough. In this case, I treat the Web Component more like a template engine.

Should Web Components be used only for portable bits of HTML that can be used in another context? Can they be linked to my project without?

I'm still undecided.

Update 2023-06-01

I was building a Web Component to reduce noise in the rendered page.

Noise in terms of having this:

<mo-bookmark id="12345678" saved="true">

compared to this:

<button id="btn_bookmark_item_463556218" class="btn btn-light p-0 border-0 d-inline-flex align-items-center justify-content-center" hx-delete="/bookmark/61f7e4a8b3c66bcf4">
    <span class="fs-8 text-uppercase mx-2">saved</span>
    <span class="fs-6 bg-dark text-white d-flex align-items-center justify-content-center" style="width:1.75rem;height:1.75rem">
        <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"><path fill="currentColor" d="M24 2H8a2 2 0 0 0-2 2v26l10-5.054L26 30V4a2 2 0 0 0-2-2Z"></path></svg>
        <span class="htmx-indicator fs-7 spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
    </span>
</button>

...several times on the page.

All the styling and functionality will be implemented in JavaScript and executed on the client-side.

However, how can you maintain the component framework-agnostic approach when using HTMX? I prefer not to include hx-* attributes within the component definition (although, why not?).

Then, I discovered a method to inject custom attributes into the component, like <mo-bookmark hx-post="/bookmark/1234" saved="true">. It seemed to work to some extent, but it led to additional complications that significantly increased the complexity. In the end, the effort to save a few kilobytes of redundant HTML wasn't worth it.

During my exploration, I came across two intriguing blog posts by Christopher Prohm. He created htmx Web Components, enabling reusability (Reusable htmx components with custom elements - Christopher Prohm), and even integrated htmx with React (Mixing React and htmx - Christopher Prohm), which is quite a bold move, given the ongoing trend to port React to htmx.

Taking it a step further, there are React components with HTMX available (reggi/htmx-components: 🧩 Async HTMX + JSX). Although I don't have experience with React, I find it amusing that HTMX aims to replace certain uses of React, only to potentially be absorbed by it.

Nevertheless, these are just my thoughts expressed spontaneously, and they may have deviated slightly from the main topic. However, I now have a clearer understanding, and it appears that integrating Web Components within HTMX works effectively. The real question is, do you truly require Web Components?