<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Andre Sander</title>
    <description>The latest articles on DEV Community by Andre Sander (@sanderand).</description>
    <link>https://dev.to/sanderand</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F739572%2F9c8a988a-b5e1-4574-8aa6-6f72342e1ad6.jpeg</url>
      <title>DEV Community: Andre Sander</title>
      <link>https://dev.to/sanderand</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sanderand"/>
    <language>en</language>
    <item>
      <title>Using sass/scss inside lit elements</title>
      <dc:creator>Andre Sander</dc:creator>
      <pubDate>Tue, 14 Oct 2025 07:01:07 +0000</pubDate>
      <link>https://dev.to/sanderand/using-sassscss-inside-lit-elements-ocp</link>
      <guid>https://dev.to/sanderand/using-sassscss-inside-lit-elements-ocp</guid>
      <description>&lt;p&gt;Recently, I was trying to use sass for my &lt;a href="https://lit.dev/" rel="noopener noreferrer"&gt;lit &lt;/a&gt; elements. Neither StackOverflow nor my LLM turned out to be helpful, but ultimately I figured it out! Here's a quick run down on what needs to be done.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For the record, I &lt;a href="https://dev.tourl"&gt;bootstrapped&lt;/a&gt; my project using &lt;code&gt;npm create vite@latest my-library -- --template lit-ts&lt;/code&gt; and am version 3.3.0 of lit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Install &lt;code&gt;sass&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://vite.dev/guide/features.html#css-pre-processors" rel="noopener noreferrer"&gt;Vite supports CSS preprocessors&lt;/a&gt;, but we need to make sure that they are installed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-D&lt;/span&gt; sass &lt;span class="c"&gt;# I'm using sass@1.93.2 but this might also work for newer versions&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuration in &lt;code&gt;vite.config.ts&lt;/code&gt; (optional)
&lt;/h2&gt;

&lt;p&gt;In my case, I wanted to provide some sass variables globally so that I could use them in my lit element styles.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vite&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;css&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;preprocessorOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;scss&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;additionalData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
          @use "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./scss/variables&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;";
        `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Adding component styles
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* file: /my-thing/styles.scss */&lt;/span&gt;
&lt;span class="nd"&gt;:host&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Integrating the styles
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// file: /my-thing/element.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;LitElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;unsafeCSS&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./styles.scss?inline&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyThing&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;LitElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;unsafeCSS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="s2"&gt;`
      &amp;lt;div&amp;gt;Hello World!&amp;lt;/div&amp;gt;
    `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Vite already has all it takes to preprocess sass. No additional plugins are necessary to achieve integrating sass styles into lit elements. &lt;/p&gt;

&lt;p&gt;One crucial point is importing styles using &lt;code&gt;?inline&lt;/code&gt;, which means importing &lt;a href="https://vite.dev/guide/features.html#disabling-css-injection-into-the-page" rel="noopener noreferrer"&gt;without automatic injection of CSS contents&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Having to use &lt;code&gt;unsafeCSS()&lt;/code&gt; is not pretty, but I don't consider it to be a security issue, because I am in control of the contents of the injected and processed styles.&lt;/p&gt;

&lt;p&gt;Hope this helps!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>typescript</category>
      <category>webcomponents</category>
      <category>css</category>
    </item>
    <item>
      <title>Running multiple versions of a Stencil Design System without conflicts</title>
      <dc:creator>Andre Sander</dc:creator>
      <pubDate>Fri, 05 Nov 2021 12:39:27 +0000</pubDate>
      <link>https://dev.to/sanderand/running-multiple-versions-of-a-stencil-design-system-without-conflicts-2f46</link>
      <guid>https://dev.to/sanderand/running-multiple-versions-of-a-stencil-design-system-without-conflicts-2f46</guid>
      <description>&lt;p&gt;Microfrontends and reusable Web Components are state-of-the-art concepts in Web Development. Combining both in complex, real-world scenarios can lead to nasty conflicts. This article explores how to run components in multiple versions without conflicts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Microfrontend Environments (MFE)
&lt;/h2&gt;

&lt;p&gt;In a MFE different product teams work on separate features of a larger application. One team might be working on the search feature, while another team works on the product detail page. Ultimately, all features will be integrated together in the final application.&lt;/p&gt;

&lt;p&gt;These features range from being very independent to being closely coupled to other features on the page. Generally speaking, teams try to work as independently as possible, meaning also that they can choose which package dependencies or even frameworks they use - and which versions thereof.&lt;/p&gt;

&lt;h2&gt;
  
  
  Custom Elements
&lt;/h2&gt;

&lt;p&gt;Web Components are a popular way of sharing and reusing components across applications and JavaScript frameworks today. Custom Elements lie at the heart of Web Components. They can be registered like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;customElements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You're now ready to use &lt;code&gt;&amp;lt;my-component&amp;gt;&lt;/code&gt; in the DOM. &lt;strong&gt;There can only be one Custom Element for a given tagName&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Let's imagine the following situation: The MFE features should reuse certain components, more specifically they should reuse the Web Components provided by the Design System (DS). The DS is being actively developed and exists in different versions.&lt;/p&gt;

&lt;p&gt;As each feature is independent, different teams might use different versions of the Design System. Separate features are developed in isolation and work fine with their specific version of the DS. Once multiple features are integrated in a larger application we'll have multiple versions of the DS running. And this causes naming conflicts because each Custom Element can only be registered once:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Feature-A uses &lt;code&gt;&amp;lt;my-component&amp;gt;&lt;/code&gt; in version &lt;code&gt;1.2.3&lt;/code&gt; and Feature-B uses &lt;code&gt;&amp;lt;my-component&amp;gt;&lt;/code&gt; in version &lt;code&gt;2.0.0&lt;/code&gt; 💥💥💥&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Oops! Now what? How do we address this problem? Is there a technical solution? Or maybe a strategic solution? &lt;/p&gt;

&lt;h3&gt;
  
  
  Forcing feature teams to use the same DS version
&lt;/h3&gt;

&lt;p&gt;One way to address this issue is to let the "shell application" provide one version of the DS. All integrated features would no longer bring their own DS version, but make use of the provided one. We no longer have multiple DS versions running.&lt;/p&gt;

&lt;p&gt;While this might work in smaller environments, it's unrealistic for many complex environments. All DS upgrades would now need to be coordinated and take place at exactly the same time. In our case &lt;strong&gt;dictating the version is not an option&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Design System
&lt;/h2&gt;

&lt;p&gt;The problem is common when reusing Custom Elements in a complex MFE. It's not specifically created by Custom Elements but it's one that can be addressed by making small adjustments in the right places of the Custom Elements.&lt;/p&gt;

&lt;p&gt;Our hypothetical Design System called "Things" has been built with Stencil - a fantastic tool for building component libraries. All components are using Shadow DOM. Some components are quite independent like &lt;code&gt;&amp;lt;th-icon&amp;gt;&lt;/code&gt;. Others are somewhat interconnected like &lt;code&gt;&amp;lt;th-tabs&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;th-tab&amp;gt;&lt;/code&gt;. Let's check out the tabs component and its usage:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgme6a444bf8ort8h6bk7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgme6a444bf8ort8h6bk7.png" alt="Picture of the tabs component"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;th-tabs&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;th-tab&lt;/span&gt; &lt;span class="na"&gt;active&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;First&lt;span class="nt"&gt;&amp;lt;/th-tab&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;th-tab&amp;gt;&lt;/span&gt;Second&lt;span class="nt"&gt;&amp;lt;/th-tab&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;th-tab&amp;gt;&lt;/span&gt;Third&lt;span class="nt"&gt;&amp;lt;/th-tab&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/th-tabs&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find the full code of the components in their initial state &lt;a href="https://github.com/Sanderand/dev-to-things-design-system/tree/6be6b89131d2ad0b05459ca8af8535772e55a87e/things/src/components" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Stencil solution
&lt;/h2&gt;

&lt;p&gt;The first thing we'll do is enable the &lt;code&gt;transformTagName&lt;/code&gt; flag in our &lt;code&gt;stencil.config.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="na"&gt;extras&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;tagNameTransform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows us to register Custom Elements with a custom prefix or suffix.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineCustomElements&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;things/loader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// registers custom elements with tagName suffix&lt;/span&gt;
&lt;span class="nf"&gt;defineCustomElements&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;transformTagName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tagName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;tagName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-v1`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great! Feature teams can now register their own custom instances of the components. This prevents naming conflicts with other components and each feature time can work a lot more independently. Alternatively, the "shell application"  could provide version-specific instances of the DS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- using v1 version of the tabs component --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;th-tabs-v1&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/th-tabs-v1&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- using v2 version of the tabs component --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;th-tabs-v2&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/th-tabs-v2&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's imagine having 2 versions available. Feature teams can now pick from the provided options without having to provide their own custom versions.&lt;/p&gt;

&lt;h2&gt;
  
  
  We're not done, yet
&lt;/h2&gt;

&lt;p&gt;Looking at &lt;code&gt;&amp;lt;th-tabs-v1&amp;gt;&lt;/code&gt; we can see that the icon component is no longer rendered. And the click handler even throws an error! So what's going on here? &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx4xxtxaywtke6c6rflh5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx4xxtxaywtke6c6rflh5.png" alt="Picture of the broken tabs component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wherever a component references other components we'll potentially run into problems because the referenced components might not exist.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;th-tab-v1&amp;gt;&lt;/code&gt; tries to render &lt;code&gt;&amp;lt;th-icon&amp;gt;&lt;/code&gt; internally, but &lt;code&gt;&amp;lt;th-icon&amp;gt;&lt;/code&gt; does not exist. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;th-tab-v1&amp;gt;&lt;/code&gt; tries to apply styles to the &lt;code&gt;th-icon&lt;/code&gt; selector which no longer selects anything&lt;/li&gt;
&lt;li&gt;on click, &lt;code&gt;&amp;lt;th-tab-v1&amp;gt;&lt;/code&gt; calls a function of &lt;code&gt;&amp;lt;th-tabs&amp;gt;&lt;/code&gt;, but &lt;code&gt;&amp;lt;th-tabs&amp;gt;&lt;/code&gt; does not exist&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;th-tabs-v1&amp;gt;&lt;/code&gt; provides a method &lt;code&gt;setActiveTab&lt;/code&gt; which no longer finds any &lt;code&gt;&amp;lt;th-tab&amp;gt;&lt;/code&gt; child element&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For every reference to another custom tagName we need to consider that the tagName might have been transformed using &lt;code&gt;transformTagName&lt;/code&gt;. As &lt;code&gt;transformTagName&lt;/code&gt; executes at runtime our component also need to figure out the correctly transformed tagNames during runtime. It would be great if Stencil provided a &lt;code&gt;transformTagName&lt;/code&gt; function that we could execute at runtime. Unfortunately, that's not the case. Instead, we can implement a (slightly ugly) solution ourselves.&lt;/p&gt;

&lt;h3&gt;
  
  
  transformTagName at runtime
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transformTagName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tagNameToBeTransformed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;knownUntransformedTagName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;knownUntransformedTagNameElementReference&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HTMLElement&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;actualCurrentTag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;knownUntransformedTagNameElementReference&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tagName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;suffix&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;actualCurrentTag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;knownUntransformedTagName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;prefix&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;tagNameToBeTransformed&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;suffix&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function is not pretty. It requires 3 parameters to return a transformed tagName:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;tagNameToBeTransformed&lt;/code&gt;: tagName that we want to transform, i.e. &lt;code&gt;th-tabs&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;knownUntransformedTagName&lt;/code&gt;: untransformed tagName of another component, i.e. &lt;code&gt;th-tab&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;knownUntransformedTagNameElementReference:&lt;/code&gt; reference to element with that untransformed tagName, i.e &lt;code&gt;this.el&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Usage example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// file: tab.tsx&lt;/span&gt;

&lt;span class="nf"&gt;transformTagName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;th-tabs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;th-tab&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 'th-tabs-v1'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note that &lt;code&gt;this.el&lt;/code&gt; is a reference to the host element of the Custom Element created by the &lt;a href="https://stenciljs.com/docs/host-element" rel="noopener noreferrer"&gt;Element Decorator&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Fixing our components
&lt;/h2&gt;

&lt;p&gt;Using our &lt;code&gt;transformTagName&lt;/code&gt; function we're now able to figure out which tagName transformation needs to be considered during runtime.&lt;/p&gt;

&lt;h3&gt;
  
  
  TypeScript call expressions
&lt;/h3&gt;

&lt;p&gt;A Custom Element tagName may be referenced in &lt;code&gt;querySelector(tagName)&lt;/code&gt;, &lt;code&gt;closest(tagName)&lt;/code&gt;, &lt;code&gt;createElement(tagName)&lt;/code&gt; or other functions. Before we call these, we need to find out the transformed tagName.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// file: tab.tsx&lt;/span&gt;

&lt;span class="c1"&gt;// before&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tabsEl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;closest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;th-tabs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// after&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ThTabs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;transformTagName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;th-tabs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;th-tab&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tabsEl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;closest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ThTabs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  JSX element rendering
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// file: tab.tsx&lt;/span&gt;

&lt;span class="c1"&gt;// before&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;th&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;icon&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// after&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ThIcon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;transformTagName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;th-icon&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;th-tab&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 'th-tabs-v1'&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ThIcon&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;icon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please note the &lt;code&gt;.icon&lt;/code&gt; class, which will be required for the next step.&lt;/p&gt;

&lt;h3&gt;
  
  
  CSS selectors
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="c1"&gt;// file: tab.css&lt;/span&gt;

&lt;span class="c1"&gt;// before&lt;/span&gt;
&lt;span class="nt"&gt;th-icon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* styles */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// after&lt;/span&gt;
&lt;span class="nc"&gt;.icon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* styles */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Wrapping it up
&lt;/h2&gt;

&lt;p&gt;And we're done! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8u09zuouawew0ibllj2g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8u09zuouawew0ibllj2g.png" alt="three variations of the tabs component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With a few small changes we've adjusted the codebase to support running multiple versions of the same Custom Elements. This is a huge step for complex Microfrontend Environments. It gives feature teams more freedom in choosing the versions they want to use and releasing when they want to release. It avoids  couplings of features or feature teams. It also reduces coordination and communication efforts.&lt;/p&gt;

&lt;p&gt;Find the code of the referenced example project in &lt;a href="https://github.com/Sanderand/dev-to-things-design-system" rel="noopener noreferrer"&gt;this Github repo&lt;/a&gt;. The second commit shows all required adjustments to support tagName transformations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance considerations
&lt;/h3&gt;

&lt;p&gt;Loading and running multiple versions of the same components at the same time will come with a performance cost. The amount of simultaneously running versions should be managed and minimal.&lt;/p&gt;

</description>
      <category>webcomponents</category>
      <category>stencil</category>
      <category>javascript</category>
      <category>designsystem</category>
    </item>
  </channel>
</rss>
