<?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: Eduardo Ottaviani Aragão</title>
    <description>The latest articles on DEV Community by Eduardo Ottaviani Aragão (@javiani).</description>
    <link>https://dev.to/javiani</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%2F1151713%2F943225da-9975-45b5-bda5-2ca4faf971bf.jpeg</url>
      <title>DEV Community: Eduardo Ottaviani Aragão</title>
      <link>https://dev.to/javiani</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/javiani"/>
    <language>en</language>
    <item>
      <title>SSR and SSG in Web Components</title>
      <dc:creator>Eduardo Ottaviani Aragão</dc:creator>
      <pubDate>Sat, 19 Apr 2025 05:44:21 +0000</pubDate>
      <link>https://dev.to/javiani/ssr-and-ssg-in-web-components-3ibm</link>
      <guid>https://dev.to/javiani/ssr-and-ssg-in-web-components-3ibm</guid>
      <description>&lt;p&gt;As front-end developers, we eventually face a common challenge: &lt;strong&gt;how to distribute features in a tech-agnostic way&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When systems grow — especially in large organizations — it becomes necessary to integrate features built by different teams, sometimes even from different companies. The result? A mix of technologies and frameworks coexisting in the same ecosystem.&lt;/p&gt;

&lt;p&gt;So how do we share features effectively in such environments?&lt;/p&gt;

&lt;p&gt;One powerful option is to use &lt;strong&gt;Web Components&lt;/strong&gt;, especially when trying to stay framework-independent. And that’s where the real conversation begins.&lt;/p&gt;




&lt;h3&gt;
  
  
  😵 The Problem: Coupled HTML and JS
&lt;/h3&gt;

&lt;p&gt;Most modern Web Component solutions (and frameworks) couple &lt;strong&gt;HTML with JavaScript&lt;/strong&gt;. Whether through template strings or JSX, this coupling often creates friction when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You want to &lt;strong&gt;render HTML on the server&lt;/strong&gt; (SSR or SSG).&lt;/li&gt;
&lt;li&gt;You care about &lt;strong&gt;bundle size&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;You need flexibility for teams to &lt;strong&gt;modify the layout&lt;/strong&gt; independently from the logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Wouldn’t it be great if we could separate logic and HTML entirely?&lt;/p&gt;

&lt;p&gt;Spoiler: &lt;strong&gt;we can.&lt;/strong&gt; 😉&lt;/p&gt;




&lt;h3&gt;
  
  
  ✅ The Solution: Split HTML and Logic
&lt;/h3&gt;

&lt;p&gt;By separating HTML from your JavaScript logic, you unlock some serious advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📦 &lt;strong&gt;Smaller Bundles&lt;/strong&gt; – Only JS is shipped. HTML stays out of your JavaScript.&lt;/li&gt;
&lt;li&gt;✨ &lt;strong&gt;More Flexibility&lt;/strong&gt; – Frontend teams can modify layout freely.&lt;/li&gt;
&lt;li&gt;⚡️ &lt;strong&gt;SSR/SSG Friendly&lt;/strong&gt; – Static HTML can be rendered ahead of time without simulating the app on the server.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s walk through an example using a setup based on &lt;a href="https://github.com/jails-org/jails" rel="noopener noreferrer"&gt;Jails&lt;/a&gt;, a 9kb micro-framework focused on reactive components with minimal overhead.&lt;/p&gt;




&lt;h3&gt;
  
  
  🔧 The Setup
&lt;/h3&gt;

&lt;p&gt;I’ve created a demo repo that illustrates this concept using &lt;a href="https://parceljs.org/" rel="noopener noreferrer"&gt;Parcel&lt;/a&gt; with TypeScript and Pug:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mfes/
├── mfe-a
├── mfe-b
└── mfe-swiper/
    ├── app.ts        ← Logic
    ├── index.ts      ← Entry point
    ├── index.css     ← Styles
    ├── index.pug     ← HTML template
    └── page.pug      ← Shell page
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The build process outputs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://mfe-jails.netlify.app/mfe-swiper/index.js" rel="noopener noreferrer"&gt;&lt;code&gt;index.js&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mfe-jails.netlify.app/mfe-swiper/index.css" rel="noopener noreferrer"&gt;&lt;code&gt;index.css&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mfe-jails.netlify.app/mfe-swiper/index.html" rel="noopener noreferrer"&gt;&lt;code&gt;index.html&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mfe-jails.netlify.app/mfe-swiper/page.html" rel="noopener noreferrer"&gt;&lt;code&gt;page.html&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🧠 The Logic with Jails
&lt;/h3&gt;

&lt;p&gt;Let’s look at how a simple Banner component (like a Swiper) looks using Jails:&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="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;appSwiper&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;elm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dependencies&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;wrapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;elm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.swiper&lt;/span&gt;&lt;span class="dl"&gt;'&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;Swiper&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dependencies&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;swiper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Swiper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&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="nx"&gt;elm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt; 
    &lt;span class="nx"&gt;elm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;prev&lt;/span&gt; 
    &lt;span class="nx"&gt;elm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;goto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;goto&lt;/span&gt; 
    &lt;span class="nx"&gt;elm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useSwiper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useSwiper&lt;/span&gt;

    &lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&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;[data-next]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&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;[data-prev]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;swiper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;slideChange&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onchange&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;onchange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&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="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;swiper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activeIndex&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&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;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;swiper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slideNext&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;prev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;swiper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slidePrev&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;goto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;swiper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slideTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&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;useSwiper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;swiper&lt;/span&gt;&lt;span class="p"&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;const&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This small function connects your component’s logic to the HTML — &lt;strong&gt;without bundling the HTML itself&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It exposes methods like &lt;code&gt;next()&lt;/code&gt;, &lt;code&gt;prev()&lt;/code&gt;, and &lt;code&gt;goto(n)&lt;/code&gt;, while keeping the actual DOM markup flexible and customizable.&lt;/p&gt;

&lt;p&gt;Here’s how we register and start the component:&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="nx"&gt;Swiper&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;swiper&lt;/span&gt;&lt;span class="dl"&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;register&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;start&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;jails-js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;appSwiper&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;components/app-swiper&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-swiper&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;appSwiper&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Swiper&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Swiper&lt;/code&gt; dependency is injected externally — this means you don’t include the Swiper library in your bundle unless you need it. 💡&lt;/p&gt;




&lt;h3&gt;
  
  
  🧱 Using the Component
&lt;/h3&gt;

&lt;p&gt;Let’s see how to use it on a page:&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;app-swiper&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"swiper"&lt;/span&gt; &lt;span class="na"&gt;html-static&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"height: 300px"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"swiper-wrapper"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"swiper-slide"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://picsum.photos/800/300?random=1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"swiper-slide"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://picsum.photos/800/300?random=2"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"swiper-slide"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://picsum.photos/800/300?random=3"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"swiper-slide"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://picsum.photos/800/300?random=4"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Page: &lt;span class="nt"&gt;&amp;lt;strong&lt;/span&gt; &lt;span class="na"&gt;html-inner=&lt;/span&gt;&lt;span class="s"&gt;"page"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"d-flex justify-content-between"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn btn-primary"&lt;/span&gt; &lt;span class="na"&gt;data-prev&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Previous&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn btn-primary"&lt;/span&gt; &lt;span class="na"&gt;data-next&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Next&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/app-swiper&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives consumers full control over the HTML structure, styling, and layout — all while maintaining access to component logic and reactive state.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧪 Live Demo
&lt;/h3&gt;

&lt;p&gt;Wanna see it in action?&lt;br&gt;&lt;br&gt;
Try the live version here 👉&lt;br&gt;&lt;br&gt;
🔗 &lt;a href="https://stackblitz.com/edit/jails-web-component-app-swiper" rel="noopener noreferrer"&gt;StackBlitz Demo&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  ✍️ Final Thoughts
&lt;/h3&gt;

&lt;p&gt;Web Components are incredibly powerful — especially when designed with &lt;strong&gt;separation of concerns&lt;/strong&gt; in mind.&lt;/p&gt;

&lt;p&gt;By letting HTML live outside your logic, and exposing a clean API through JS, you empower teams to reuse features without framework lock-in, and without bloating bundles.&lt;/p&gt;

&lt;p&gt;This strategy is particularly useful in &lt;strong&gt;micro-frontend&lt;/strong&gt; environments, but works just as well in traditional apps that value performance, maintainability, and clarity.&lt;/p&gt;

&lt;p&gt;In a future post, I’ll show how to encapsulate this component into a &lt;strong&gt;remote micro-frontend&lt;/strong&gt; for full plug-and-play reuse.&lt;/p&gt;

&lt;p&gt;Until then, feel free to explore &lt;a href="https://github.com/jails-org/jails" rel="noopener noreferrer"&gt;Jails&lt;/a&gt; and give your components a lightweight, flexible edge 🚀&lt;/p&gt;

</description>
      <category>webcomponents</category>
      <category>jailsjs</category>
      <category>frontend</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Astro + Jails - A Perfect Match</title>
      <dc:creator>Eduardo Ottaviani Aragão</dc:creator>
      <pubDate>Sun, 23 Feb 2025 06:04:03 +0000</pubDate>
      <link>https://dev.to/javiani/astro-jails-a-perfect-match-365l</link>
      <guid>https://dev.to/javiani/astro-jails-a-perfect-match-365l</guid>
      <description>&lt;p&gt;Astro.js is a modern framework that prioritizes zero JavaScript by default for static pages, aiming to deliver faster load times and better performance. &lt;/p&gt;

&lt;p&gt;It allows developers to build dynamic websites with minimal JavaScript, only loading it when necessary. &lt;/p&gt;

&lt;p&gt;This "zero JavaScript" approach helps optimize user experience by reducing the amount of client-side code and improving page speed, while still enabling the flexibility to add interactivity when required. Astro’s focus is on efficiency and scalability.&lt;/p&gt;

&lt;p&gt;But you might be wondering: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;what can I use to make the static parts of my application more dynamic, taking advantage of Astro's island architecture concept?&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Zero Client Javascript + Only Client Javascript
&lt;/h2&gt;

&lt;p&gt;Jails is a library designed to bring best practices to software development, specifically in JavaScript for Fron-tend. It focuses solely on adding client-side functionality in the simplest and most elegant way possible, leveraging the full potential of the language.&lt;/p&gt;

&lt;p&gt;Jails offers a range of features for your web components, allowing you to choose between building your entire application based on web components or creating solutions that can be distributed agnostically to other projects.&lt;/p&gt;




&lt;h2&gt;
  
  
  How about taking a quick peek?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The markup:&lt;/strong&gt; src/pages/index.astro&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;script&amp;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;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;register&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;jails-js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;helloworld&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;components/hello-world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello-world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;helloworld&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;hello-world&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Hello World!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;A simple Counter&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn add"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;+&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;html-inner=&lt;/span&gt;&lt;span class="s"&gt;"counter"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;0&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn subtract"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;-&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;/hello-world&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Javascript:&lt;/strong&gt; src/components/hello-world/index.ts&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="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;helloWorld&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&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="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&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;button.add&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&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;button.subtract&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;subtract&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;add&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&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="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&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;subtract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&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="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&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;
  
  
  TodoMVC Example
&lt;/h2&gt;

&lt;p&gt;&lt;iframe src="https://stackblitz.com/edit/jails-todomvc?embed=1&amp;amp;file=todo-app.ts" width="100%" height="500"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  The Benefits
&lt;/h2&gt;

&lt;p&gt;Astro was built to deliver zero JavaScript and maximize performance. On the other hand, Jails was designed to minimize JavaScript by separating HTML from its JavaScript logic, resulting in smaller bundles and more efficient, streamlined code.&lt;/p&gt;

&lt;p&gt;Web components are a great solution for building more agnostic, cross-application compatible solutions, but developing applications with pure JavaScript can be time-consuming.&lt;/p&gt;

&lt;p&gt;Jails strikes a balance between developing solutions directly, as we typically do with pure JavaScript, and leveraging the power of modern frameworks for DOM updates, local and global state management, and functionality sharing.&lt;/p&gt;

&lt;p&gt;Check out a collection of examples using Jails here: &lt;a href="https://stackblitz.com/@Javiani/collections/jails-organization" rel="noopener noreferrer"&gt;https://stackblitz.com/@Javiani/collections/jails-organization&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;More: &lt;a href="https://jails-js.org/" rel="noopener noreferrer"&gt;https://jails-js.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you!&lt;/p&gt;

</description>
      <category>astro</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Dependency Injection, Inversion of Control &amp; Jails 5</title>
      <dc:creator>Eduardo Ottaviani Aragão</dc:creator>
      <pubDate>Sat, 09 Mar 2024 21:50:03 +0000</pubDate>
      <link>https://dev.to/javiani/dependency-injection-inversion-of-control-jails-5-252b</link>
      <guid>https://dev.to/javiani/dependency-injection-inversion-of-control-jails-5-252b</guid>
      <description>&lt;p&gt;Cover from: &lt;a href="https://www.linkedin.com/pulse/understanding-dependency-injection-alex-merced"&gt;https://www.linkedin.com/pulse/understanding-dependency-injection-alex-merced&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In software engineering, dependency injection is a programming technique in which an object or function receives other objects or functions that it requires, as opposed to creating them internally. ( Wikipedia )&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Alright, here's the deal: Dependency Injection is like the secret sauce for untangling your system. It's a straightforward method to loosen up the connections between components. With this approach, you're basically flipping the switch on who's calling the shots in a component or module. And trust me, it can totally revolutionize how you structure your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inversion of Control
&lt;/h2&gt;

&lt;p&gt;You know, Inversion of Control (IoC) is baked right into the core of JavaScript. It's like second nature for us JavaScript devs, and honestly, it's a breeze to pull off in this language, especially with callback functions.&lt;br&gt;
IoC lets us split up generic behavior from the nitty-gritty specifics, which gives us some awesome reusability perks too.&lt;/p&gt;
&lt;h2&gt;
  
  
  Example - Find a user by id from a list and remove it from the list.
&lt;/h2&gt;
&lt;h4&gt;
  
  
  Without Dependency Injection and Inversion of Control
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;findUserAndRemove&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;newlist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;newlist&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;user&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;newlist&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;There's nothing completely wrong with the code above, it's easy to understand and it does its job. However, we might encounter scenarios where we want to locate a user based on another property, or where we desire to do more than simply remove the user from a list; we may wish to modify or enhance the user with additional properties, for instance. In such cases, not only will the name of our function lose its relevance, but it will also expand with increasingly complex behaviors, potentially rendering it difficult to manage.&lt;/p&gt;

&lt;p&gt;There are at least two different behaviors on that code, the first is the iteration over a list, the second one is by identifying a case where we are looking for and do something with it. The findUserAndRemove function has 100% of control of what is going on on that task.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So how can we decouple those two behaviors and make it more reusable?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The solution is already inherent in the language. The &lt;code&gt;filter&lt;/code&gt; array method is an implementation that achieves &lt;strong&gt;Inversion of Control&lt;/strong&gt; by incorporating a &lt;strong&gt;callback&lt;/strong&gt; function. &lt;/p&gt;

&lt;p&gt;Therefore, the &lt;code&gt;filter&lt;/code&gt; function's purpose is to iterate over each element of the list and return a new list containing only elements that satisfy a given condition.&lt;/p&gt;

&lt;p&gt;In the initial code snippet, the findUserAndRemove function possesses complete control over the user selection process. &lt;/p&gt;

&lt;p&gt;However, the filter method reverses this control dynamic, empowering you to determine the criteria for selecting the user:&lt;/p&gt;
&lt;h4&gt;
  
  
  With Dependency Injection and Inversion of Control
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newlist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;With a single line we did exactly the same as we did before and filter can be reused for many other cenarios.&lt;br&gt;
If we want to find a particular user without changing the size of items of a particular list, we can use the map method for it:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newlist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; 
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  DI &amp;amp; IC in Frameworks
&lt;/h2&gt;

&lt;p&gt;Those concepts are so deeply ingrained in the language that they shouldn't become more complex when transitioning into Frameworks. &lt;/p&gt;

&lt;p&gt;Indeed, React lacks a dedicated Dependency Injection (DI) mechanism; it is inherently built into the framework due to the functional nature of its components. Consequently, all that's required is to anticipate a callback function within your generic component, and there you have it.&lt;/p&gt;

&lt;p&gt;In contrast, Angular doesn't offer such simplicity. To inject dependencies, you must invest time in understanding its mechanisms, and familiarize yourself with concepts like &lt;strong&gt;Services&lt;/strong&gt;, &lt;strong&gt;Decorators&lt;/strong&gt;, &lt;strong&gt;Injectable&lt;/strong&gt;, &lt;strong&gt;Providers&lt;/strong&gt;, if you haven't already done so.&lt;/p&gt;

&lt;p&gt;With that said, it's clearer, at least to me, that the more a framework or library aligns with the language's native features and functionality, the easier it becomes to accomplish tasks.&lt;/p&gt;




&lt;h2&gt;
  
  
  DI &amp;amp; IC in Jails
&lt;/h2&gt;

&lt;p&gt;Jails is all about simplicity, so naturally, those things should be straightforward in Jails, right? Yeah… and they are:&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;// at home.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;jails&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;jails-js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;router&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;jails.pandora/router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;store&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;jails.pandora/store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;myComponent&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;./components/my-component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;jails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&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;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;store&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="c1"&gt;//...other components registering&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Component usage&lt;/strong&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="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;myComponent&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dependencies&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dependencies&lt;/span&gt; 

  &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&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="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;log&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;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello World!&lt;/span&gt;&lt;span class="dl"&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;The injection occurs during the component registration phase, and the purpose of Dependency Injection (DI) and Inversion of Control (IC) in Jails aligns precisely with what we discussed earlier in this article. &lt;/p&gt;

&lt;p&gt;It's all about decoupling generic behavior from specific logic. Moreover, it involves sharing capabilities and instances between components, as illustrated in the example above.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Real World Use Case
&lt;/h2&gt;

&lt;p&gt;Form Validation poses an ongoing challenge in the Front End realm. Eventually, every framework and library will offer a general abstraction to handle this task, and Jails is no exception.&lt;/p&gt;

&lt;p&gt;Recently, I developed a validation component using Jails and shared it in a repository. While I don't anticipate creating numerous abstractions with Jails, as the philosophy of this application library prioritizes full interoperability with the Vanilla JavaScript ecosystem, there's an exception for Form Validation.&lt;/p&gt;

&lt;p&gt;The challenge in crafting such an abstraction lies in ensuring its generic nature, enabling anyone worldwide to utilize it irrespective of regional specificities. To achieve this, we must discern between what aspects should be generic and what should remain specific.&lt;/p&gt;

&lt;p&gt;The generic aspect entails attaching event handlers to validate functions, updating the view with error feedback when necessary, and removing errors upon validation. This segment manages events and applies classes to DOM elements for programmers to utilize in handling UI errors.&lt;/p&gt;

&lt;p&gt;Conversely, since validations can vary based on regions, business rules, etc., all validations should be externally provided to the component, adhering to a defined contract to ensure correct behavior of the generic abstraction. &lt;/p&gt;

&lt;p&gt;Additionally, dynamic configurations must be accessible to specify the validations a field requires.&lt;/p&gt;




&lt;h2&gt;
  
  
  Introducing - Form Validation Component
&lt;/h2&gt;

&lt;p&gt;So, to invert the control of the Form Validation component and ensure its generic usability across various scenarios, the &lt;strong&gt;Form Validation Component&lt;/strong&gt; leverages the Jails Dependency Injection system to inject specific validation rules. Additionally, it retrieves configuration data from &lt;code&gt;HTMLFormElement&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://stackblitz.com/edit/jails-form-validation?embed=1&amp;amp;file=app%2Frules.ts" width="100%" height="500"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;p&gt;So that's it… That's all I got for you guys.&lt;/p&gt;

&lt;p&gt;Checkout the Demo hosted on StackBlitz so you can learn more about that.&lt;/p&gt;

&lt;p&gt;See you!&lt;/p&gt;

</description>
      <category>web</category>
      <category>programming</category>
      <category>frontend</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Jails 5 - A Front-end Library for new (old) trends</title>
      <dc:creator>Eduardo Ottaviani Aragão</dc:creator>
      <pubDate>Sun, 10 Sep 2023 20:37:52 +0000</pubDate>
      <link>https://dev.to/javiani/jails-5-a-front-end-library-for-new-old-trends-e97</link>
      <guid>https://dev.to/javiani/jails-5-a-front-end-library-for-new-old-trends-e97</guid>
      <description>&lt;p&gt;In the not-so-distant past, crafting a simple rounded corner on a webpage was a formidable challenge, requiring intricate manipulation of layout grids, animations, and wrangling with browser limitations. However, today's web development landscape appears considerably less daunting. JavaScript has undergone numerous enhancements, the language itself has evolved, and DOM APIs, browser capabilities, CSS, bundlers, development tools, editors, and the entire platform have seen significant updates.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The Contemporary Era&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Modern JavaScript frameworks have introduced diverse solutions to address client-side complexities, but they've also ushered in a new era of intricacy that troubles many, myself included. I was never an advocate of JSX; I believed that embedding HTML within our JavaScript code blurred the lines between concerns. Yet, the influence of conferences and tech giants gradually led to wider acceptance of this practice, even though it never quite felt right to me.&lt;/p&gt;

&lt;p&gt;Time has a knack for illuminating the wisdom of certain ideas, and in the realm of software engineering, concepts tend to ebb and flow cyclically. Single Page Applications (SPAs) are no longer in vogue, and the idea of housing all HTML definitions inside JavaScript files has been recognized as detrimental to site performance due to the resulting bloated bundles.&lt;/p&gt;

&lt;p&gt;Static site generation and server-side rendering have gained momentum as more performant alternatives. Moreover, these frameworks tend to lock developers into their ecosystems. Once you choose a front-end library, you're compelled to embrace their entire stack. This can be a frustrating experience, as I've personally witnessed projects rewritten from the ground up solely because React was chosen as the client-side library, necessitating a shift from platforms like Rails or PHP to Node.js.&lt;/p&gt;

&lt;p&gt;But something is changing, a shift toward simplicity or greater agnosticism perhaps. I'm referring to emerging technologies like Astro and Htmx.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Astro and Htmx: The New Wave&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With Htmx, you can leverage any back-end language, enhancing your HTML applications with directives and using the library to seamlessly replace DOM elements and update them with HTML responses. This approach bears resemblance to the days of .NET MVC, where partial views were returned for XMLHttpRequest.&lt;/p&gt;

&lt;p&gt;Astro, on the other hand, allows you to remain within the Node.js realm for server-side rendering (SSR) while granting you the freedom to select any client-side library for static site generation (SSG).&lt;/p&gt;

&lt;p&gt;This 'new' trend instills a glimmer of hope that we are returning to a simpler approach to web development. Frameworks, it seems, are obstructing the progress of many applications. As senior engineers who recall simpler times, even amidst technological limitations, it's crucial that we retain the capacity for critical evaluation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My Contribution to the Community&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As a tech lead and principal, working with teams necessitates a pragmatic approach. While staying updated with new technologies is vital, it's equally crucial to empower teams with the autonomy to choose their preferred tech stack. I have immersed myself in the realm of modern front-end frameworks for some time now.&lt;/p&gt;

&lt;p&gt;However, I have steadfastly clung to the belief that we don't need the excessive complexities prevalent today. This conviction led me to initiate a project called "Jails" eight years ago. I had the privilege of testing this project in various applications within the companies I've collaborated with. The support and shared vision of like-minded developers encouraged me to pursue this indie project in critical applications.&lt;/p&gt;

&lt;p&gt;The intent behind Jails was to create a contemporary client-side library that embodies several key principles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agnosticism, enabling compatibility with any SSR or SSG system, as well as other vanilla JavaScript libraries.&lt;/li&gt;
&lt;li&gt;Simplicity and speed.&lt;/li&gt;
&lt;li&gt;Event-driven architecture with modern techniques like DOM diffing and local state management.&lt;/li&gt;
&lt;li&gt;Platform-oriented, aligning closely with vanilla JavaScript and browser compatibility.&lt;/li&gt;
&lt;li&gt;A functional approach, devoid of classes, 'this', decorators, private/public members, or inheritance. Functional, but deeply rooted in the JavaScript paradigm.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To utilize Jails, simply encapsulate the markup requiring dynamic behavior within a custom element and register a Component module in a separate JavaScript or TypeScript file containing the logic.&lt;/p&gt;

&lt;p&gt;In summary, I've been working diligently with Jails, and I wholeheartedly believe it provides an elegant and classic approach to crafting client-side applications. I invite you to explore it, offer your suggestions, and join in on this project. You can find more information at &lt;a href="https://jails-js.org/"&gt;https://jails-js.org/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thank you for your time, and until next time!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webcomponents</category>
      <category>frontend</category>
    </item>
  </channel>
</rss>
