<?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: Jakub Andrzejewski</title>
    <description>The latest articles on DEV Community by Jakub Andrzejewski (@jacobandrewsky).</description>
    <link>https://dev.to/jacobandrewsky</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%2F652576%2F71679021-521f-4d3b-b57f-af2d4ad055d9.png</url>
      <title>DEV Community: Jakub Andrzejewski</title>
      <link>https://dev.to/jacobandrewsky</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jacobandrewsky"/>
    <language>en</language>
    <item>
      <title>State-Driven Animations in Vue: Create Smooth UI Transitions with Reactive State</title>
      <dc:creator>Jakub Andrzejewski</dc:creator>
      <pubDate>Mon, 01 Jun 2026 09:54:37 +0000</pubDate>
      <link>https://dev.to/jacobandrewsky/state-driven-animations-in-vue-create-smooth-ui-transitions-with-reactive-state-d3i</link>
      <guid>https://dev.to/jacobandrewsky/state-driven-animations-in-vue-create-smooth-ui-transitions-with-reactive-state-d3i</guid>
      <description>&lt;p&gt;Animations can make an application feel faster, smoother, and more polished. However, many developers think animations are only useful for things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;page transitions&lt;/li&gt;
&lt;li&gt;modals&lt;/li&gt;
&lt;li&gt;enter/leave effects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But Vue provides another powerful pattern - State-driven animations. Instead of animating when elements are added or removed from the DOM, you animate changes in reactive state. This allows you to create rich interactive experiences while keeping your code declarative and easy to maintain.&lt;/p&gt;

&lt;p&gt;In this article, we'll explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What state-driven animations are&lt;/li&gt;
&lt;li&gt;How they differ from regular Vue transitions&lt;/li&gt;
&lt;li&gt;What problems they solve&lt;/li&gt;
&lt;li&gt;How to implement them in Vue&lt;/li&gt;
&lt;li&gt;Best practices for creating smooth UI interactions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 What Are State-Driven Animations?
&lt;/h2&gt;

&lt;p&gt;Most Vue developers are familiar with the &lt;code&gt;&amp;lt;Transition&amp;gt;&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Transition&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;Modal&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"isOpen"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Transition&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This animates an element when it enters or leaves the DOM.&lt;/p&gt;

&lt;p&gt;But what if the element already exists and only its state changes? For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a progress bar grows&lt;/li&gt;
&lt;li&gt;a card expands&lt;/li&gt;
&lt;li&gt;a chart updates&lt;/li&gt;
&lt;li&gt;a panel changes size&lt;/li&gt;
&lt;li&gt;a value changes position&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where &lt;strong&gt;state-driven animations&lt;/strong&gt; shine.&lt;/p&gt;

&lt;p&gt;Instead of animating DOM insertion or removal, you animate changes caused by reactive state.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 What Problem Do State-Driven Animations Solve?
&lt;/h2&gt;

&lt;p&gt;Without animations, state changes can feel abrupt.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;:style=&lt;/span&gt;&lt;span class="s"&gt;"{ width: progress + '%' }"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When &lt;code&gt;progress&lt;/code&gt; changes:&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;progress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The width instantly jumps.&lt;/p&gt;

&lt;p&gt;This works technically... but it doesn't feel great.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 A Simple Example
&lt;/h2&gt;

&lt;p&gt;Let's create an animated progress bar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;progress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;increase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;progress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&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="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"increase"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Increase Progress
  &lt;span class="nt"&gt;&amp;lt;/button&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;"progress-container"&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;"progress-bar"&lt;/span&gt;
      &lt;span class="na"&gt;:style=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;{ width: `${progress}%` }"
    /&amp;gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.progress-container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#eee&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.progress-bar&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#42b883&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt; &lt;span class="n"&gt;ease&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;Now whenever &lt;code&gt;progress&lt;/code&gt; changes, the bar animates smoothly.&lt;/p&gt;

&lt;p&gt;The animation is entirely driven by reactive state.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Animating Multiple Properties
&lt;/h2&gt;

&lt;p&gt;State-driven animations are not limited to width.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&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;"card"&lt;/span&gt;
  &lt;span class="na"&gt;:style=&lt;/span&gt;&lt;span class="s"&gt;"{
    transform: expanded
      ? 'scale(1.1)'
      : 'scale(1)',
    opacity: expanded
      ? 1
      : 0.7
  }"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;transform&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;opacity&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt; &lt;span class="n"&gt;ease&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;Now changing:&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;expanded&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;animates &lt;code&gt;scale&lt;/code&gt; and &lt;code&gt;opacity&lt;/code&gt; at the same time.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Using Vue Reactivity with Animations
&lt;/h2&gt;

&lt;p&gt;One of the biggest advantages is that animations stay connected to Vue's reactivity system.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isActive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&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="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"isActive = !isActive"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Toggle
  &lt;span class="nt"&gt;&amp;lt;/button&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;"box"&lt;/span&gt;
    &lt;span class="na"&gt;:class=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;{ active: isActive }"
  /&amp;gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.box&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt; &lt;span class="m"&gt;0.4s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.box.active&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;180deg&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;Vue handles state.&lt;/p&gt;

&lt;p&gt;CSS handles animation.&lt;/p&gt;

&lt;p&gt;The result is clean and maintainable.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Keep animations subtle and purposeful&lt;/li&gt;
&lt;li&gt;Prefer CSS transitions for simple effects&lt;/li&gt;
&lt;li&gt;Avoid animating expensive properties when possible&lt;/li&gt;
&lt;li&gt;Use transforms instead of layout-changing properties when appropriate&lt;/li&gt;
&lt;li&gt;Don't animate everything&lt;/li&gt;
&lt;li&gt;Keep durations short (typically 200–400ms)&lt;/li&gt;
&lt;li&gt;Use animations to communicate state changes, not distract users&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📖 Learn more
&lt;/h2&gt;

&lt;p&gt;If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this &lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2Fj7hlfz848ut2d9ly8i8q.png" alt="Vue School Link" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Advance skills
&lt;/h2&gt;

&lt;p&gt;A certification boosts your skills, builds credibility, and opens doors to new opportunities. Whether you're advancing your career or switching paths, it's a smart step toward success.&lt;/p&gt;

&lt;p&gt;Check out Certificates.dev by clicking this &lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2F9iledpqv69huancwg283.png" alt="Certificates.dev Link" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Invest in yourself—get certified in Vue.js, JavaScript, Nuxt, Angular, React, and more!&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Summary
&lt;/h2&gt;

&lt;p&gt;State-driven animations are a powerful way to create smooth and engaging user experiences in Vue.&lt;/p&gt;

&lt;p&gt;While &lt;code&gt;&amp;lt;Transition&amp;gt;&lt;/code&gt; is perfect for entering and leaving elements, state-driven animations excel when existing elements need to react smoothly to changing data.&lt;/p&gt;

&lt;p&gt;Used thoughtfully, they can make your applications feel significantly more responsive and professional.&lt;/p&gt;

&lt;p&gt;Take care!&lt;br&gt;
And happy coding as always 🖥️&lt;/p&gt;

</description>
      <category>vue</category>
      <category>css</category>
      <category>animation</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Avoid Cross Module Dependencies with Dependency Cruiser</title>
      <dc:creator>Jakub Andrzejewski</dc:creator>
      <pubDate>Mon, 25 May 2026 06:27:43 +0000</pubDate>
      <link>https://dev.to/jacobandrewsky/avoid-cross-module-dependencies-with-dependency-cruiser-3b0b</link>
      <guid>https://dev.to/jacobandrewsky/avoid-cross-module-dependencies-with-dependency-cruiser-3b0b</guid>
      <description>&lt;p&gt;As applications grow, maintaining a clean architecture becomes increasingly difficult.&lt;/p&gt;

&lt;p&gt;At first, everything feels manageable but after a few months (or years), projects often become full of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;circular dependencies&lt;/li&gt;
&lt;li&gt;deeply coupled modules&lt;/li&gt;
&lt;li&gt;messy import paths&lt;/li&gt;
&lt;li&gt;forbidden cross-layer imports&lt;/li&gt;
&lt;li&gt;architectural chaos&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The worst part is that these problems usually grow silently over time.&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;dependency-cruiser&lt;/strong&gt; becomes incredibly useful. It helps you visualize and enforce rules for your project dependencies before things become unmaintainable.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What dependency-cruiser is&lt;/li&gt;
&lt;li&gt;What problems it solves&lt;/li&gt;
&lt;li&gt;How to set it up&lt;/li&gt;
&lt;li&gt;Practical examples&lt;/li&gt;
&lt;li&gt;How to enforce architectural boundaries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 What Is dependency-cruiser?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/sverweij/dependency-cruiser" rel="noopener noreferrer"&gt;dependency-cruiser&lt;/a&gt; is a powerful tool for analyzing and validating dependencies in JavaScript and TypeScript projects.&lt;/p&gt;

&lt;p&gt;It scans your project imports and helps you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;detect circular dependencies&lt;/li&gt;
&lt;li&gt;enforce architecture rules&lt;/li&gt;
&lt;li&gt;visualize dependency graphs&lt;/li&gt;
&lt;li&gt;identify unused modules&lt;/li&gt;
&lt;li&gt;prevent bad import patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it like:&lt;/p&gt;

&lt;p&gt;👉 “ESLint for your project architecture.”&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 What Problem Does dependency-cruiser Solve?
&lt;/h2&gt;

&lt;p&gt;In large applications, dependencies can quickly become messy.&lt;/p&gt;

&lt;p&gt;Example problems:&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Circular dependencies
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A → B → C → A
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These can cause:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;runtime issues&lt;/li&gt;
&lt;li&gt;undefined values&lt;/li&gt;
&lt;li&gt;difficult debugging&lt;/li&gt;
&lt;li&gt;unpredictable behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ❌ Layer violations
&lt;/h3&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;components → api → components
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ui → backend → ui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This breaks separation of concerns.&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Shared modules becoming dumping grounds
&lt;/h3&gt;

&lt;p&gt;You often end up with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/utils
/shared
/helpers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;containing everything.&lt;/p&gt;

&lt;p&gt;Over time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dependencies become tangled&lt;/li&gt;
&lt;li&gt;architecture loses structure&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ✅ dependency-cruiser helps enforce boundaries
&lt;/h3&gt;

&lt;p&gt;You can define rules like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“UI cannot import backend”&lt;/li&gt;
&lt;li&gt;“Feature modules cannot depend on each other”&lt;/li&gt;
&lt;li&gt;“No circular dependencies allowed”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And automatically validate them in CI.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Installing dependency-cruiser
&lt;/h2&gt;

&lt;p&gt;Setup is very simple.&lt;/p&gt;

&lt;p&gt;Install it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; dependency-cruiser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🟢 Generating Your First Dependency Graph
&lt;/h2&gt;

&lt;p&gt;One of the coolest features is visualization.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx depcruise src &lt;span class="nt"&gt;--include-only&lt;/span&gt; &lt;span class="s2"&gt;"^src"&lt;/span&gt; &lt;span class="nt"&gt;--output-type&lt;/span&gt; dot | dot &lt;span class="nt"&gt;-T&lt;/span&gt; svg &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dependency-graph.svg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This generates a visual graph of your project dependencies.&lt;/p&gt;

&lt;p&gt;You can quickly spot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;circular dependencies&lt;/li&gt;
&lt;li&gt;overly connected modules&lt;/li&gt;
&lt;li&gt;problematic architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In large projects, this is incredibly eye-opening.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Creating Rules
&lt;/h2&gt;

&lt;p&gt;The real power comes from architecture validation.&lt;/p&gt;

&lt;p&gt;Example config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;forbidden&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;no-circular&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;severity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
      &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;circular&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="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;Now dependency-cruiser will fail whenever circular dependencies appear.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Real-World Example: Enforcing Layered Architecture
&lt;/h2&gt;

&lt;p&gt;Imagine this structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├── components/
├── features/
├── api/
├── utils/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may want:&lt;/p&gt;

&lt;p&gt;👉 &lt;code&gt;components&lt;/code&gt; should never import from &lt;code&gt;api&lt;/code&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;forbidden&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;no-components-to-api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;^src/components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;^src/api&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;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;Now architecture rules become automated.&lt;/p&gt;

&lt;p&gt;This is extremely valuable for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;large teams&lt;/li&gt;
&lt;li&gt;enterprise projects&lt;/li&gt;
&lt;li&gt;monorepos&lt;/li&gt;
&lt;li&gt;long-term maintainability&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🟢 Using dependency-cruiser with Vue Projects
&lt;/h2&gt;

&lt;p&gt;dependency-cruiser works great with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vue&lt;/li&gt;
&lt;li&gt;Nuxt&lt;/li&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;Angular&lt;/li&gt;
&lt;li&gt;Node.js&lt;/li&gt;
&lt;li&gt;TypeScript monorepos&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For Vue apps, it’s especially useful when managing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;composables&lt;/li&gt;
&lt;li&gt;feature modules&lt;/li&gt;
&lt;li&gt;shared UI components&lt;/li&gt;
&lt;li&gt;store architecture&lt;/li&gt;
&lt;li&gt;layered frontend structure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example issue it can prevent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;components → composables → components
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which can become very difficult to maintain later.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 CI Integration
&lt;/h2&gt;

&lt;p&gt;One of the best things about dependency-cruiser:&lt;/p&gt;

&lt;p&gt;👉 It can run automatically in CI/CD pipelines.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx depcruise src &lt;span class="nt"&gt;--validate&lt;/span&gt; .dependency-cruiser.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now pull requests fail when architecture rules are violated.&lt;/p&gt;

&lt;p&gt;This prevents technical debt from growing silently.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Common Mistakes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ❌ Creating overly strict rules too early
&lt;/h3&gt;

&lt;p&gt;Start simple.&lt;/p&gt;

&lt;p&gt;Too many restrictions can frustrate teams.&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Ignoring the reports
&lt;/h3&gt;

&lt;p&gt;The tool is only useful if rules are actually enforced.&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Not visualizing dependencies
&lt;/h3&gt;

&lt;p&gt;Graphs often reveal architecture problems immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Allowing shared folders to grow uncontrollably
&lt;/h3&gt;

&lt;p&gt;dependency-cruiser helps expose this early.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Start with circular dependency detection&lt;/li&gt;
&lt;li&gt;Gradually add architectural rules&lt;/li&gt;
&lt;li&gt;Integrate validation into CI&lt;/li&gt;
&lt;li&gt;Use dependency graphs regularly&lt;/li&gt;
&lt;li&gt;Keep rules aligned with real architecture decisions&lt;/li&gt;
&lt;li&gt;Avoid massive shared utility folders&lt;/li&gt;
&lt;li&gt;Use the tool proactively — not only after problems appear&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📖 Learn more
&lt;/h2&gt;

&lt;p&gt;If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this &lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2Fj7hlfz848ut2d9ly8i8q.png" alt="Vue School Link" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Advance skills
&lt;/h2&gt;

&lt;p&gt;A certification boosts your skills, builds credibility, and opens doors to new opportunities. Whether you're advancing your career or switching paths, it's a smart step toward success.&lt;/p&gt;

&lt;p&gt;Check out Certificates.dev by clicking this &lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2F9iledpqv69huancwg283.png" alt="Certificates.dev Link" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Invest in yourself—get certified in Vue.js, JavaScript, Nuxt, Angular, React, and more!&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Summary
&lt;/h2&gt;

&lt;p&gt;dependency-cruiser is an incredibly valuable tool for keeping project architecture healthy as applications grow.&lt;/p&gt;

&lt;p&gt;Good architecture rarely happens accidentally.&lt;/p&gt;

&lt;p&gt;Tools like dependency-cruiser help teams maintain structure, reduce technical debt, and prevent dependency chaos before it becomes a serious problem.&lt;/p&gt;

&lt;p&gt;Take care!&lt;br&gt;
And happy coding as always 🖥️&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>frontend</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Avoid Unnecessary Re-renders in Vue with `v-memo`</title>
      <dc:creator>Jakub Andrzejewski</dc:creator>
      <pubDate>Mon, 18 May 2026 09:21:34 +0000</pubDate>
      <link>https://dev.to/jacobandrewsky/avoid-unnecessary-re-renders-in-vue-with-v-memo-49bo</link>
      <guid>https://dev.to/jacobandrewsky/avoid-unnecessary-re-renders-in-vue-with-v-memo-49bo</guid>
      <description>&lt;p&gt;When building Vue applications, performance usually feels great by default - Vue’s reactivity system is incredibly efficient.&lt;/p&gt;

&lt;p&gt;But as applications grow larger, you may eventually run into situations where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;components re-render too often&lt;/li&gt;
&lt;li&gt;large lists become expensive&lt;/li&gt;
&lt;li&gt;UI updates feel sluggish&lt;/li&gt;
&lt;li&gt;unnecessary computations happen repeatedly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where &lt;strong&gt;memoization&lt;/strong&gt; becomes useful. And in Vue, one of the easiest ways to optimize rendering is with &lt;code&gt;v-memo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What memoization is&lt;/li&gt;
&lt;li&gt;What problem it solves&lt;/li&gt;
&lt;li&gt;How &lt;code&gt;v-memo&lt;/code&gt; works in Vue&lt;/li&gt;
&lt;li&gt;Real-world examples&lt;/li&gt;
&lt;li&gt;Best practices and common mistakes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 What Is Memoization?
&lt;/h2&gt;

&lt;p&gt;Memoization is an optimization technique where results are &lt;strong&gt;cached&lt;/strong&gt; and reused instead of recalculating them again.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;recomputing&lt;/li&gt;
&lt;li&gt;re-rendering&lt;/li&gt;
&lt;li&gt;recalculating&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You simply use the cached version.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 What Problem Does Memoization Solve?
&lt;/h2&gt;

&lt;p&gt;In reactive applications, updates can trigger many re-renders even when most data has not changed for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Parent component updates&lt;/li&gt;
&lt;li&gt;Entire list re-renders&lt;/li&gt;
&lt;li&gt;Hundreds of child components update unnecessarily&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This can hurt performance, responsiveness, and even battery usage on mobile devices.&lt;/p&gt;

&lt;p&gt;Without memoization every update causes new rendering work - even for unchanged content.&lt;/p&gt;

&lt;p&gt;With memoization Vue can skip rendering when dependencies stay the same which reduces DOM operations, Virtual DOM diffing, and in general component work.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 What Is &lt;code&gt;v-memo&lt;/code&gt; in Vue?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;v-memo&lt;/code&gt; is a Vue directive that memoizes part of a template.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-memo=&lt;/span&gt;&lt;span class="s"&gt;"[value]"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  {{ expensiveContent }}
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vue will only re-render this block when &lt;code&gt;value&lt;/code&gt; changes. Otherwise Vue reuses the previous rendered result.&lt;/p&gt;

&lt;p&gt;Let’s imagine a large user list.&lt;/p&gt;

&lt;p&gt;Without &lt;code&gt;v-memo&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&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;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John&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;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Alice&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;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&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="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"counter++"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;
    &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"user in users"&lt;/span&gt;
    &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"user.id"&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&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;name&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every counter update re-renders the whole list even though users never changed.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;v-memo&lt;/code&gt; we can:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&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;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John&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;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Alice&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;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&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="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"counter++"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;
    &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"user in users"&lt;/span&gt;
    &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"user.id"&lt;/span&gt;
    &lt;span class="na"&gt;v-memo=&lt;/span&gt;&lt;span class="s"&gt;"[user.id]"&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&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;name&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now counter updates still happen but unchanged list items are skipped. This becomes extremely valuable for large lists, dashboards, or tables.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 When NOT to Use It
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;v-memo&lt;/code&gt; is not needed everywhere as Vue is already highly optimized.&lt;/p&gt;

&lt;p&gt;Avoid using it for tiny components, static content, or premature optimization as overusing memoization can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reduce readability&lt;/li&gt;
&lt;li&gt;make debugging harder&lt;/li&gt;
&lt;li&gt;introduce stale UI bugs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🧪 Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;v-memo&lt;/code&gt; only for measurable bottlenecks&lt;/li&gt;
&lt;li&gt;Great for large dynamic lists&lt;/li&gt;
&lt;li&gt;Keep dependency arrays minimal&lt;/li&gt;
&lt;li&gt;Avoid premature optimization&lt;/li&gt;
&lt;li&gt;Profile performance before optimizing&lt;/li&gt;
&lt;li&gt;Combine with virtual scrolling for huge datasets&lt;/li&gt;
&lt;li&gt;Prefer stable keys and predictable state updates&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📖 Learn more
&lt;/h2&gt;

&lt;p&gt;If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this &lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2Fj7hlfz848ut2d9ly8i8q.png" alt="Vue School Link" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Advance skills
&lt;/h2&gt;

&lt;p&gt;A certification boosts your skills, builds credibility, and opens doors to new opportunities. Whether you're advancing your career or switching paths, it's a smart step toward success.&lt;/p&gt;

&lt;p&gt;Check out Certificates.dev by clicking this &lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2F9iledpqv69huancwg283.png" alt="Certificates.dev Link" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Invest in yourself—get certified in Vue.js, JavaScript, Nuxt, Angular, React, and more!&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Summary
&lt;/h2&gt;

&lt;p&gt;Memoization is a powerful optimization technique that helps avoid unnecessary work.&lt;/p&gt;

&lt;p&gt;In this article, you learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What memoization is&lt;/li&gt;
&lt;li&gt;What problem it solves&lt;/li&gt;
&lt;li&gt;How Vue’s &lt;code&gt;v-memo&lt;/code&gt; works&lt;/li&gt;
&lt;li&gt;Practical examples for lists and components&lt;/li&gt;
&lt;li&gt;When to use it — and when not to&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Take care!&lt;br&gt;
And happy coding as always 🖥️&lt;/p&gt;

</description>
      <category>performance</category>
      <category>vue</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Why Loaders Matter for Performance</title>
      <dc:creator>Jakub Andrzejewski</dc:creator>
      <pubDate>Mon, 11 May 2026 09:29:43 +0000</pubDate>
      <link>https://dev.to/jacobandrewsky/why-loaders-matter-for-performance-4b8a</link>
      <guid>https://dev.to/jacobandrewsky/why-loaders-matter-for-performance-4b8a</guid>
      <description>&lt;p&gt;When developers think about performance optimization, they usually focus on things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lazy loading&lt;/li&gt;
&lt;li&gt;caching&lt;/li&gt;
&lt;li&gt;image optimization&lt;/li&gt;
&lt;li&gt;bundle size&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And while those things absolutely matter there’s another area that heavily impacts user experience -&amp;gt; Loading states and layout stability.&lt;/p&gt;

&lt;p&gt;A badly implemented loading experience can make an app feel slow, jumpy, or frustrating to use. This is strongly connected to an important Core Web Vital metric Cumulative Layout Shift (CLS).&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What CLS is&lt;/li&gt;
&lt;li&gt;Why loaders are critical for perceived performance&lt;/li&gt;
&lt;li&gt;How poor loading states hurt UX&lt;/li&gt;
&lt;li&gt;Practical examples in Vue&lt;/li&gt;
&lt;li&gt;Best practices for stable layouts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 What Is Cumulative Layout Shift (CLS)?
&lt;/h2&gt;

&lt;p&gt;CLS measures how much elements unexpectedly move during page loading.&lt;/p&gt;

&lt;p&gt;Example of bad CLS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Text suddenly jumps down&lt;/li&gt;
&lt;li&gt;Buttons move while you try to click&lt;/li&gt;
&lt;li&gt;Images appear late and push content around&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’ve all experienced websites like this:&lt;/p&gt;

&lt;p&gt;👉 You try to click something… and suddenly the layout shifts. Extremely annoying.&lt;/p&gt;

&lt;p&gt;Why does this happen? Usually because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;content loads asynchronously&lt;/li&gt;
&lt;li&gt;elements have no reserved space&lt;/li&gt;
&lt;li&gt;loaders are missing&lt;/li&gt;
&lt;li&gt;images don’t define dimensions&lt;/li&gt;
&lt;li&gt;components suddenly appear&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why does CLS matter? Because it affects user experience, accessibility, or mobile usability (and obviously Google Core Web Vitals). Even if your app is technically fast poor layout stability can make it feel slow.&lt;/p&gt;

&lt;p&gt;👉 Users care more about &lt;strong&gt;perceived performance&lt;/strong&gt; than actual milliseconds.&lt;/p&gt;

&lt;p&gt;A good loader communicates progress, prevents layout jumping, and makes apps feel responsive&lt;/p&gt;

&lt;p&gt;A bad or missing loader creates uncertainty. Users start thinking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Did the app freeze?”&lt;/li&gt;
&lt;li&gt;“Is something broken?”&lt;/li&gt;
&lt;li&gt;“Why is everything moving?”&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🟢 Implementing proper loaders in Vue
&lt;/h2&gt;

&lt;p&gt;Let's take a look at the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&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;loading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&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="nf"&gt;onMounted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &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;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchUsers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&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;v-if=&lt;/span&gt;&lt;span class="s"&gt;"loading"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"skeleton-list"&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;v-for=&lt;/span&gt;&lt;span class="s"&gt;"n in 5"&lt;/span&gt;
      &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"n"&lt;/span&gt;
      &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"skeleton-card"&lt;/span&gt;
    &lt;span class="nt"&gt;/&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;UserCard&lt;/span&gt;
    &lt;span class="na"&gt;v-else&lt;/span&gt;
    &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"user in users"&lt;/span&gt;
    &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"user.id"&lt;/span&gt;
    &lt;span class="na"&gt;:user=&lt;/span&gt;&lt;span class="s"&gt;"user"&lt;/span&gt;
  &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt; &lt;span class="na"&gt;scoped&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nc"&gt;.skeleton-card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;120px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We fetch users, but when the fetch is in progress we display the same hard coded number of loaders/skeletons. When the users are loaded there is no layout shift as it occupies the same space improving perceived performance and User Experience.&lt;/p&gt;

&lt;p&gt;If we don't know how many results there will be, we have to assume some number but it is still better than not having skeletons at all :)&lt;/p&gt;

&lt;p&gt;Many apps still use simple spinners or text/icon loaders like:&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;div&amp;gt;&lt;/span&gt;Loading...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But modern UX usually prefers Skeleton loaders because they mimic final layout, reduce layout shift, and improve perceived speed.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Prefer skeleton loaders over tiny spinners&lt;/li&gt;
&lt;li&gt;Reserve space before content loads&lt;/li&gt;
&lt;li&gt;Keep loading and final layouts similar&lt;/li&gt;
&lt;li&gt;Always define image dimensions&lt;/li&gt;
&lt;li&gt;Avoid injecting large content suddenly&lt;/li&gt;
&lt;li&gt;Test CLS using Lighthouse or Core Web Vitals tools&lt;/li&gt;
&lt;li&gt;Think about perceived performance — not just raw speed&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📖 Learn more
&lt;/h2&gt;

&lt;p&gt;If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this &lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2Fj7hlfz848ut2d9ly8i8q.png" alt="Vue School Link" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Advance skills
&lt;/h2&gt;

&lt;p&gt;A certification boosts your skills, builds credibility, and opens doors to new opportunities. Whether you're advancing your career or switching paths, it's a smart step toward success.&lt;/p&gt;

&lt;p&gt;Check out Certificates.dev by clicking this &lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2F9iledpqv69huancwg283.png" alt="Certificates.dev Link" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Invest in yourself—get certified in Vue.js, JavaScript, Nuxt, Angular, React, and more!&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Summary
&lt;/h2&gt;

&lt;p&gt;Loaders are much more important than most developers realize.&lt;/p&gt;

&lt;p&gt;In this article, you learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What Cumulative Layout Shift (CLS) is&lt;/li&gt;
&lt;li&gt;Why poor loading states hurt UX&lt;/li&gt;
&lt;li&gt;How skeleton loaders improve perceived performance&lt;/li&gt;
&lt;li&gt;How to avoid layout jumping in Vue and other frameworks&lt;/li&gt;
&lt;li&gt;Best practices for stable, responsive interfaces&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fast apps are great.&lt;/p&gt;

&lt;p&gt;But apps that &lt;strong&gt;feel smooth and stable&lt;/strong&gt; are what users truly remember.&lt;/p&gt;

&lt;p&gt;Take care!&lt;br&gt;
And happy coding as always 🖥️&lt;/p&gt;

</description>
      <category>vue</category>
      <category>performance</category>
      <category>tutorial</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to Safely Allow Inline Scripts Without Breaking Security with CSP Nonce</title>
      <dc:creator>Jakub Andrzejewski</dc:creator>
      <pubDate>Mon, 27 Apr 2026 06:46:57 +0000</pubDate>
      <link>https://dev.to/jacobandrewsky/how-to-safely-allow-inline-scripts-without-breaking-security-with-csp-nonce-3a2j</link>
      <guid>https://dev.to/jacobandrewsky/how-to-safely-allow-inline-scripts-without-breaking-security-with-csp-nonce-3a2j</guid>
      <description>&lt;p&gt;When building modern web applications, security is not optional. One of the most important protections you can add is a &lt;strong&gt;Content Security Policy (CSP)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But here’s the catch:&lt;/p&gt;

&lt;p&gt;👉 CSP often &lt;strong&gt;blocks inline scripts and styles&lt;/strong&gt; — which can break your app.&lt;/p&gt;

&lt;p&gt;So how do you keep your app secure &lt;strong&gt;without disabling useful features&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;That’s where &lt;strong&gt;CSP nonce&lt;/strong&gt; comes in - it allows you to safely execute inline code &lt;strong&gt;without opening security holes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What CSP nonce is&lt;/li&gt;
&lt;li&gt;What problem it solves&lt;/li&gt;
&lt;li&gt;How to implement it&lt;/li&gt;
&lt;li&gt;How it works automatically in Nuxt with &lt;code&gt;nuxt-security&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Best practices and common pitfalls&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 What Is CSP Nonce?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;nonce&lt;/strong&gt; (short for &lt;em&gt;number used once&lt;/em&gt;) is a &lt;strong&gt;unique, random value generated for each request&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is used in CSP to explicitly allow trusted inline scripts or styles.&lt;/p&gt;

&lt;p&gt;Example:&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 &lt;/span&gt;&lt;span class="na"&gt;nonce=&lt;/span&gt;&lt;span class="s"&gt;"abc123"&lt;/span&gt;&lt;span class="nt"&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;Secure inline script&lt;/span&gt;&lt;span class="dl"&gt;'&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in your HTTP headers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Content-Security-Policy: script-src 'nonce-abc123'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser will only execute scripts that have a matching nonce.&lt;/p&gt;

&lt;p&gt;CSP nonce is a &lt;strong&gt;whitelist mechanism&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only scripts with the correct nonce are allowed&lt;/li&gt;
&lt;li&gt;Everything else is blocked&lt;/li&gt;
&lt;li&gt;The nonce changes on every request&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes it extremely effective against &lt;strong&gt;XSS (Cross-Site Scripting)&lt;/strong&gt; attacks.&lt;/p&gt;

&lt;p&gt;CSP nonce is commonly used for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;SSR frameworks - Injecting initial state, Hydration scripts&lt;/li&gt;
&lt;li&gt;Analytics / tracking snippets - Inline scripts required by providers&lt;/li&gt;
&lt;li&gt;Critical inline scripts - Small scripts needed before app bootstraps&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🟢 What Problem Does CSP Nonce Solve?
&lt;/h2&gt;

&lt;p&gt;Without nonce, you usually face a trade-off:&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Allow inline scripts (unsafe)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Content-Security-Policy: script-src 'unsafe-inline'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Problem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Opens the door to XSS attacks&lt;/li&gt;
&lt;li&gt;Any injected script can run&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ❌ Block inline scripts completely
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Content-Security-Policy: script-src 'self'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Problem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;breaks inline event handlers&lt;/li&gt;
&lt;li&gt;breaks injected scripts (SSR hydration, state)&lt;/li&gt;
&lt;li&gt;breaks some frameworks&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🟢 How to Implement CSP Nonce
&lt;/h2&gt;

&lt;p&gt;The process is relatively simple but let's break it down and explain each step individually.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Generate a nonce per request
&lt;/h3&gt;

&lt;p&gt;Example (Node.js):&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;crypto&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;crypto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;generateNonce&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;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randomBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;base64&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;h3&gt;
  
  
  Step 2: Add it to response headers
&lt;/h3&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;nonce&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generateNonce&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Security-Policy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;`script-src 'nonce-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;nonce&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Inject it into your HTML
&lt;/h3&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 &lt;/span&gt;&lt;span class="na"&gt;nonce=&lt;/span&gt;&lt;span class="s"&gt;"{{nonce}}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__INITIAL_STATE__&lt;/span&gt; &lt;span class="o"&gt;=&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ⚠️ Critical rule
&lt;/h3&gt;

&lt;p&gt;The nonce in the header and HTML &lt;strong&gt;must match exactly&lt;/strong&gt;. Otherwise, script will be blocked and app may break silently.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 CSP Nonce in Nuxt (with nuxt-security)
&lt;/h2&gt;

&lt;p&gt;If you’re using Nuxt, things get much easier thanks to &lt;strong&gt;nuxt-security&lt;/strong&gt; module that can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatically generate nonce per request&lt;/li&gt;
&lt;li&gt;Inject it into CSP headers&lt;/li&gt;
&lt;li&gt;Attach it to scripts/styles&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It makes it much easier to work with CSP nonces in Nuxt. Let's take a look at the following configuration:&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="nf"&gt;defineNuxtConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;modules&lt;/span&gt;&lt;span class="p"&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;nuxt-security&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;security&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;contentSecurityPolicy&lt;/span&gt;&lt;span class="p"&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;script-src&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;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;'self'&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="s2"&gt;'nonce-{{nonce}}'&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;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;p&gt;What happens automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nuxt generates a nonce per request&lt;/li&gt;
&lt;li&gt;Replaces &lt;code&gt;{{nonce}}&lt;/code&gt; in headers&lt;/li&gt;
&lt;li&gt;Applies nonce to inline scripts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don’t need to manually wire everything&lt;/p&gt;

&lt;p&gt;You can read more here:&lt;br&gt;
&lt;a href="https://nuxt-security.vercel.app/" rel="noopener noreferrer"&gt;https://nuxt-security.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Common Mistakes
&lt;/h2&gt;

&lt;p&gt;Let's take a look at the list of common mistakes to understand what to look for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;❌ Reusing the same nonce - Nonce must be unique per request and cryptographically random&lt;/li&gt;
&lt;li&gt;❌ Forgetting to apply nonce in HTML - if you only set CSP header the scripts will still be blocked&lt;/li&gt;
&lt;li&gt;❌ Mixing nonce with unsafe-inline - &lt;code&gt;script-src 'unsafe-inline' 'nonce-abc'&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;❌ Caching issues - if HTML is cached nonce may not match header&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🧪 Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Generate nonce &lt;strong&gt;per request&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Use secure randomness (&lt;code&gt;crypto&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Never reuse nonce&lt;/li&gt;
&lt;li&gt;Avoid &lt;code&gt;unsafe-inline&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Use frameworks/tools (like nuxt-security)&lt;/li&gt;
&lt;li&gt;Test CSP in &lt;strong&gt;report-only mode&lt;/strong&gt; first&lt;/li&gt;
&lt;li&gt;Monitor browser console for CSP violations&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📖 Learn more
&lt;/h2&gt;

&lt;p&gt;If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this &lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2Fj7hlfz848ut2d9ly8i8q.png" alt="Vue School Link" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Advance skills
&lt;/h2&gt;

&lt;p&gt;A certification boosts your skills, builds credibility, and opens doors to new opportunities. Whether you're advancing your career or switching paths, it's a smart step toward success.&lt;/p&gt;

&lt;p&gt;Check out Certificates.dev by clicking this &lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2F9iledpqv69huancwg283.png" alt="Certificates.dev Link" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Invest in yourself—get certified in Vue.js, JavaScript, Nuxt, Angular, React, and more!&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Summary
&lt;/h2&gt;

&lt;p&gt;CSP nonce is a powerful mechanism that allows you to safely use inline scripts while maintaining strong security.&lt;/p&gt;

&lt;p&gt;In this article, you learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What CSP nonce is and how it works&lt;/li&gt;
&lt;li&gt;What problem it solves (security vs flexibility)&lt;/li&gt;
&lt;li&gt;How to implement it step by step&lt;/li&gt;
&lt;li&gt;How Nuxt + nuxt-security handle it automatically&lt;/li&gt;
&lt;li&gt;Common mistakes and best practices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Take care!&lt;br&gt;
And happy coding as always 🖥️&lt;/p&gt;

</description>
      <category>security</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Flexible Code Without Losing Type Safety with TS Generics</title>
      <dc:creator>Jakub Andrzejewski</dc:creator>
      <pubDate>Mon, 30 Mar 2026 09:03:13 +0000</pubDate>
      <link>https://dev.to/jacobandrewsky/flexible-code-without-losing-type-safety-with-ts-generics-1pem</link>
      <guid>https://dev.to/jacobandrewsky/flexible-code-without-losing-type-safety-with-ts-generics-1pem</guid>
      <description>&lt;p&gt;When working with TypeScript, you quickly run into a common problem:&lt;/p&gt;

&lt;p&gt;👉 You want your code to be &lt;strong&gt;reusable&lt;/strong&gt;, but also &lt;strong&gt;type-safe&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;At first, it’s tempting to use &lt;code&gt;any&lt;/code&gt; to make things flexible… but that comes at a cost:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You lose type safety&lt;/li&gt;
&lt;li&gt;You lose autocomplete&lt;/li&gt;
&lt;li&gt;You introduce hidden bugs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is exactly the problem that &lt;strong&gt;TypeScript Generics&lt;/strong&gt; solve.&lt;/p&gt;

&lt;p&gt;They let you write reusable code &lt;strong&gt;without sacrificing type safety&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What Generics are&lt;/li&gt;
&lt;li&gt;What problem they solve&lt;/li&gt;
&lt;li&gt;Practical examples you’ll actually use&lt;/li&gt;
&lt;li&gt;Best practices to avoid common mistakes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 Problem with type reusability
&lt;/h2&gt;

&lt;p&gt;When you want your function to be reusable, you usually end up with this &lt;code&gt;any&lt;/code&gt; approach:&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;function&lt;/span&gt; &lt;span class="nf"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;any&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;value&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works but it also comes with problems such as no type safety, no IntelliSense, and can easily lead to break things.&lt;/p&gt;

&lt;p&gt;The second problem is code duplication:&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;function&lt;/span&gt; &lt;span class="nf"&gt;identityString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&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="kr"&gt;string&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;value&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;identityNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&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;value&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this approach, we are breaking the Don't Repeat Yourself (DRY) rule which also makes the code harder to maintain and less scalable.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 Solution: TypeScript Generics
&lt;/h2&gt;

&lt;p&gt;Generics allow you to create components, functions, or classes that work with &lt;strong&gt;multiple types&lt;/strong&gt;, while still preserving full type information.&lt;/p&gt;

&lt;p&gt;Think of them as:&lt;/p&gt;

&lt;p&gt;👉 “Type placeholders” that get filled in later&lt;/p&gt;

&lt;p&gt;Basic 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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;identity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&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;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;T&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;value&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;T&lt;/code&gt; is a generic type&lt;/li&gt;
&lt;li&gt;It represents &lt;strong&gt;whatever type you pass in&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Usage:&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;identity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// string&lt;/span&gt;
&lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;// number&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;TypeScript automatically knows what comes out based on what goes in.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Practical Examples
&lt;/h2&gt;

&lt;p&gt;Let’s look at real-world scenarios where generics shine.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Example 1: Reusable API Response Type
&lt;/h3&gt;

&lt;p&gt;Very common pattern in frontend apps:&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;type&lt;/span&gt; &lt;span class="nx"&gt;ApiResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;
  &lt;span class="na"&gt;error&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;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usage:&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;type&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="na"&gt;name&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ApiResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&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;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your API types are consistent, reusable, and fully typed.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Example 2: Generic Array Helper
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getFirstItem&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&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;arr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="nx"&gt;T&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;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&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;Usage:&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="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getFirstItem&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;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;// number&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getFirstItem&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a&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="s2"&gt;b&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;// string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;TypeScript knows exactly what type is returned.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Example 3: Generic Props in Vue
&lt;/h3&gt;

&lt;p&gt;Check out my other article where I have explained this topic in more details &lt;a href="https://dev.to/jacobandrewsky/using-generics-in-vue-components-1lnn"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Example 4: Constraining Generics
&lt;/h3&gt;

&lt;p&gt;Sometimes you want flexibility — but with rules.&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;function&lt;/span&gt; &lt;span class="nf"&gt;getLength&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&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;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usage:&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="nf"&gt;getLength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// ✅&lt;/span&gt;
&lt;span class="nf"&gt;getLength&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;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;// ✅&lt;/span&gt;
&lt;span class="nf"&gt;getLength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// ❌ error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this approach, you ensure flexibility but also controlled structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Example 5: Keyof + Generics
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getProperty&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;K&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&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;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;K&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;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&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;Usage:&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;id&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;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;getProperty&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// ✅&lt;/span&gt;
&lt;span class="nf"&gt;getProperty&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;age&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// ❌ error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is extremely powerful for forms, dynamic access, or utilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  📖 Learn more
&lt;/h2&gt;

&lt;p&gt;If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this &lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2Fj7hlfz848ut2d9ly8i8q.png" alt="Vue School Link" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Advance skills
&lt;/h2&gt;

&lt;p&gt;A certification boosts your skills, builds credibility, and opens doors to new opportunities. Whether you're advancing your career or switching paths, it's a smart step toward success.&lt;/p&gt;

&lt;p&gt;Check out Certificates.dev by clicking this &lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2F9iledpqv69huancwg283.png" alt="Certificates.dev Link" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Invest in yourself—get certified in Vue.js, JavaScript, Nuxt, Angular, React, and more!&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Summary
&lt;/h2&gt;

&lt;p&gt;TypeScript Generics are one of the most powerful features in the language. They let you write code that is both &lt;strong&gt;flexible and safe&lt;/strong&gt; — which is exactly what you want in modern applications.&lt;/p&gt;

&lt;p&gt;Once you start using them properly, it’s hard to go back.&lt;/p&gt;

&lt;p&gt;Take care!&lt;br&gt;
And happy coding as always 🖥️&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>tutorial</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>When You Should Use Vue Teleport</title>
      <dc:creator>Jakub Andrzejewski</dc:creator>
      <pubDate>Mon, 23 Mar 2026 09:36:56 +0000</pubDate>
      <link>https://dev.to/jacobandrewsky/when-you-should-use-vue-teleport-4k6i</link>
      <guid>https://dev.to/jacobandrewsky/when-you-should-use-vue-teleport-4k6i</guid>
      <description>&lt;p&gt;When building modern Vue applications, not everything fits neatly inside your component tree. Some UI elements — like modals, tooltips, dropdowns, or overlays — often need to &lt;strong&gt;escape their parent container&lt;/strong&gt; due to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;z-index issues&lt;/li&gt;
&lt;li&gt;overflow constraints&lt;/li&gt;
&lt;li&gt;stacking context problems&lt;/li&gt;
&lt;li&gt;layout limitations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where &lt;strong&gt;Vue Teleport&lt;/strong&gt; becomes incredibly useful as it allows you to render part of your component &lt;strong&gt;outside of its DOM hierarchy&lt;/strong&gt;, while still keeping it logically connected to the component.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What Vue Teleport is&lt;/li&gt;
&lt;li&gt;When you should use it&lt;/li&gt;
&lt;li&gt;Real-world use cases (like dialogs and overlays)&lt;/li&gt;
&lt;li&gt;What &lt;code&gt;defer&lt;/code&gt; Teleport does and when to use it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 What Is Vue Teleport?
&lt;/h2&gt;

&lt;p&gt;Vue Teleport is a built-in component that allows you to &lt;strong&gt;render content in a different part of the DOM&lt;/strong&gt; than where it is declared.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Teleport&lt;/span&gt; &lt;span class="na"&gt;to=&lt;/span&gt;&lt;span class="s"&gt;"body"&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;"modal"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    I am rendered in body!
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Teleport&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even though this code exists inside a component, the rendered HTML is moved to &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt;. Teleport changes &lt;strong&gt;where elements are rendered&lt;/strong&gt;, not how they behave. This means that reactivity still works, events still work, and component logic stays intact.&lt;/p&gt;

&lt;p&gt;Teleport is purely about &lt;strong&gt;DOM placement&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 When Should You Use Vue Teleport?
&lt;/h2&gt;

&lt;p&gt;Teleport is ideal when UI elements need to visually break out of their parent container.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Modals / Dialogs
&lt;/h3&gt;

&lt;p&gt;Modals are the most common use case.&lt;/p&gt;

&lt;p&gt;Without Teleport, modals can break due to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;overflow: hidden&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;nested containers&lt;/li&gt;
&lt;li&gt;stacking issues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Teleport&lt;/span&gt; &lt;span class="na"&gt;to=&lt;/span&gt;&lt;span class="s"&gt;"body"&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;"modal-backdrop"&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;"modal"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      Modal content
    &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;/Teleport&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ✅ Tooltips &amp;amp; Dropdowns
&lt;/h3&gt;

&lt;p&gt;Dropdowns and tooltips often need to appear above everything else.&lt;/p&gt;

&lt;p&gt;Teleport helps avoid:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;clipping inside parent containers&lt;/li&gt;
&lt;li&gt;z-index conflicts&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ✅ Notifications / Toasts
&lt;/h3&gt;

&lt;p&gt;Global UI elements like notifications should not depend on local layout.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Teleport&lt;/span&gt; &lt;span class="na"&gt;to=&lt;/span&gt;&lt;span class="s"&gt;"#notifications"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;Toast&lt;/span&gt; &lt;span class="na"&gt;message=&lt;/span&gt;&lt;span class="s"&gt;"Saved!"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Teleport&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ✅ Third-party UI Libraries (Real Example)
&lt;/h3&gt;

&lt;p&gt;Libraries like &lt;strong&gt;Reka UI&lt;/strong&gt; use Teleport internally for components such as dialogs.&lt;/p&gt;

&lt;p&gt;Example usage pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;DialogRoot&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;DialogTrigger&amp;gt;&lt;/span&gt;Open&lt;span class="nt"&gt;&amp;lt;/DialogTrigger&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;DialogPortal&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;DialogOverlay&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;DialogContent&amp;gt;&lt;/span&gt;
      Dialog content
    &lt;span class="nt"&gt;&amp;lt;/DialogContent&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/DialogPortal&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/DialogRoot&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Under the hood, &lt;code&gt;DialogPortal&lt;/code&gt; uses Teleport to render content outside the component tree — usually into &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This ensures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Proper layering&lt;/li&gt;
&lt;li&gt;Accessibility compliance&lt;/li&gt;
&lt;li&gt;Correct focus management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This pattern is standard for &lt;strong&gt;headless UI libraries&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Deferred Teleport (&lt;code&gt;defer&lt;/code&gt;)
&lt;/h2&gt;

&lt;p&gt;Vue also provides an advanced feature: &lt;strong&gt;deferred teleport&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Teleport&lt;/span&gt; &lt;span class="na"&gt;to=&lt;/span&gt;&lt;span class="s"&gt;"#target"&lt;/span&gt; &lt;span class="na"&gt;defer&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Deferred content&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Teleport&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Normally, Teleport tries to move content immediately but sometimes the target element does not exist yet or it is rendered later (e.g., in SSR or layouts)&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;defer&lt;/code&gt;, Vue waits until the target exists before teleporting.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Common Mistakes When Using Teleport
&lt;/h2&gt;

&lt;p&gt;There are few things we should take care when using Teleport:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Overusing Teleport - avoid using Teleport for regular layout, simple components, or static UI.&lt;/li&gt;
&lt;li&gt;Forgetting Accessibility - teleport does not solve focus trapping, keyboard navigation, or ARIA roles.&lt;/li&gt;
&lt;li&gt;Styling issues - Teleported content is no longer inside the same DOM tree which means scoped styles may not apply and parent CSS may not affect the component.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🧪 Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use Teleport primarily for &lt;strong&gt;overlays and global UI&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Combine with proper &lt;strong&gt;focus management&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;defer&lt;/code&gt; when working with dynamic targets&lt;/li&gt;
&lt;li&gt;Prefer UI libraries (like Reka UI) for complex patterns&lt;/li&gt;
&lt;li&gt;Keep Teleport usage minimal and intentional&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📖 Learn more
&lt;/h2&gt;

&lt;p&gt;If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this &lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2Fj7hlfz848ut2d9ly8i8q.png" alt="Vue School Link" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Advance skills
&lt;/h2&gt;

&lt;p&gt;A certification boosts your skills, builds credibility, and opens doors to new opportunities. Whether you're advancing your career or switching paths, it's a smart step toward success.&lt;/p&gt;

&lt;p&gt;Check out Certificates.dev by clicking this &lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2F9iledpqv69huancwg283.png" alt="Certificates.dev Link" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Invest in yourself—get certified in Vue.js, JavaScript, Nuxt, Angular, React, and more!&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Summary
&lt;/h2&gt;

&lt;p&gt;Vue Teleport is a powerful tool for handling UI elements that need to exist outside normal DOM hierarchy.&lt;/p&gt;

&lt;p&gt;Teleport helps you solve layout problems cleanly while keeping your component logic simple and maintainable.&lt;/p&gt;

&lt;p&gt;Use it wisely — and your UI architecture will become much more flexible.&lt;/p&gt;

&lt;p&gt;Take care!&lt;br&gt;
And happy coding as always 🖥️&lt;/p&gt;

</description>
      <category>vue</category>
      <category>tutorial</category>
      <category>javascript</category>
      <category>css</category>
    </item>
    <item>
      <title>Reusable Architecture for Large Applications with Nuxt Layers</title>
      <dc:creator>Jakub Andrzejewski</dc:creator>
      <pubDate>Mon, 16 Mar 2026 09:51:13 +0000</pubDate>
      <link>https://dev.to/jacobandrewsky/reusable-architecture-for-large-applications-with-nuxt-layers-1a46</link>
      <guid>https://dev.to/jacobandrewsky/reusable-architecture-for-large-applications-with-nuxt-layers-1a46</guid>
      <description>&lt;p&gt;As applications grow, managing shared code across projects becomes increasingly difficult. Teams often face problems like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Duplicated logic across repositories&lt;/li&gt;
&lt;li&gt;Inconsistent project structure&lt;/li&gt;
&lt;li&gt;Hard-to-maintain design systems&lt;/li&gt;
&lt;li&gt;Repeated configuration setup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where &lt;strong&gt;Nuxt Layers&lt;/strong&gt; become extremely useful.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What Nuxt Layers are&lt;/li&gt;
&lt;li&gt;How they work&lt;/li&gt;
&lt;li&gt;How to use them to reuse code across projects&lt;/li&gt;
&lt;li&gt;How they help build scalable architecture&lt;/li&gt;
&lt;li&gt;Potential tradeoffs and when to avoid them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 What Are Nuxt Layers?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Nuxt Layers&lt;/strong&gt; allow one Nuxt project to extend another using the &lt;code&gt;extends&lt;/code&gt; feature.&lt;/p&gt;

&lt;p&gt;In practice, this means you can create a &lt;strong&gt;base layer&lt;/strong&gt; containing shared logic, and multiple applications can build on top of it.&lt;/p&gt;

&lt;p&gt;A layer can include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Components&lt;/li&gt;
&lt;li&gt;Composables&lt;/li&gt;
&lt;li&gt;Pages&lt;/li&gt;
&lt;li&gt;Layouts&lt;/li&gt;
&lt;li&gt;Middleware&lt;/li&gt;
&lt;li&gt;Configuration&lt;/li&gt;
&lt;li&gt;Modules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of layers as &lt;strong&gt;reusable Nuxt building blocks&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;base-layer/
  components/
  composables/
  layouts/
  nuxt.config.ts

app/
  pages/
  nuxt.config.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application extends the base layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Creating a Nuxt Layer
&lt;/h2&gt;

&lt;p&gt;A layer is essentially a Nuxt project that other projects can extend.&lt;/p&gt;

&lt;p&gt;Example layer structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ui-layer/
  components/
    AppButton.vue
  composables/
    useTheme.ts
  nuxt.config.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then in your application:&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="nf"&gt;defineNuxtConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;extends&lt;/span&gt;&lt;span class="p"&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;../ui-layer&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;Now everything inside the layer becomes available inside your app.&lt;/p&gt;

&lt;p&gt;For example, the &lt;code&gt;AppButton&lt;/code&gt; component can be used directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;AppButton&amp;gt;&lt;/span&gt;
  Click me
&lt;span class="nt"&gt;&amp;lt;/AppButton&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No additional imports required. This makes sharing UI systems across multiple apps much easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Reusing Code Across Multiple Projects
&lt;/h2&gt;

&lt;p&gt;One of the biggest benefits of Nuxt Layers is &lt;strong&gt;code reuse across multiple repositories&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, you may create layers for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UI components&lt;/li&gt;
&lt;li&gt;Authentication logic&lt;/li&gt;
&lt;li&gt;Analytics integrations&lt;/li&gt;
&lt;li&gt;Design systems&lt;/li&gt;
&lt;li&gt;API composables&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example layered architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;core-layer
  composables/
  utils/

ui-layer
  components/
  layouts/

marketing-app
admin-app
dashboard-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each application extends the shared layers.&lt;/p&gt;

&lt;p&gt;Example configuration:&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="nf"&gt;defineNuxtConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;extends&lt;/span&gt;&lt;span class="p"&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;../core-layer&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;../ui-layer&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;This ensures that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shared code lives in one place&lt;/li&gt;
&lt;li&gt;Updates propagate across projects&lt;/li&gt;
&lt;li&gt;Teams maintain consistent patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s particularly useful for &lt;strong&gt;large organizations managing multiple applications&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Using Layers for Scalable Architecture
&lt;/h2&gt;

&lt;p&gt;Nuxt Layers also help structure &lt;strong&gt;large applications&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of a single large codebase, you can divide your system into logical layers.&lt;/p&gt;

&lt;p&gt;Example architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;design-system-layer
business-logic-layer
feature-layer
app-layer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each layer builds on top of the previous one.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;design-system-layer
  components/
  styles/

business-layer
  composables/

feature-layer
  pages/
  components/

app-layer
  pages/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then your main application config:&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="nf"&gt;defineNuxtConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;extends&lt;/span&gt;&lt;span class="p"&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;../design-system-layer&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;../business-layer&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;../feature-layer&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;This approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Improves maintainability&lt;/li&gt;
&lt;li&gt;Encourages separation of concerns&lt;/li&gt;
&lt;li&gt;Helps teams scale development&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It becomes easier to reason about the architecture of large Nuxt projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Layer Overrides and Merging
&lt;/h2&gt;

&lt;p&gt;One powerful aspect of Nuxt Layers is that &lt;strong&gt;later layers override earlier ones&lt;/strong&gt;.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;base-layer/components/Header.vue
app/components/Header.vue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application version overrides the base layer component.&lt;/p&gt;

&lt;p&gt;This allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provide defaults in layers&lt;/li&gt;
&lt;li&gt;Customize behavior in applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Configuration is also merged automatically.&lt;/p&gt;

&lt;p&gt;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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineNuxtConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;runtimeConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;apiBase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api&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;If multiple layers define &lt;code&gt;runtimeConfig&lt;/code&gt;, Nuxt merges them.&lt;/p&gt;

&lt;p&gt;This merging behavior makes layers flexible and customizable.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚠️ Tradeoffs of Nuxt Layers
&lt;/h2&gt;

&lt;p&gt;While layers are powerful, they introduce some complexity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Increased Architectural Complexity
&lt;/h3&gt;

&lt;p&gt;When many layers are involved, it can become harder to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where components come from&lt;/li&gt;
&lt;li&gt;Which layer overrides which&lt;/li&gt;
&lt;li&gt;How configuration is merged&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This can slow onboarding for new developers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Debugging Can Be Harder
&lt;/h3&gt;

&lt;p&gt;If a component behaves unexpectedly, you may need to check multiple layers.&lt;/p&gt;

&lt;p&gt;Example problem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Component defined in:
- layer A
- layer B
- application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Understanding which one is active requires careful inspection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tooling and IDE Navigation
&lt;/h3&gt;

&lt;p&gt;Depending on your editor setup, navigating across layers may be less straightforward than working within a single project.&lt;/p&gt;

&lt;p&gt;Although modern Nuxt tooling is improving, it still requires good project organization.&lt;/p&gt;

&lt;h3&gt;
  
  
  Overengineering Risk
&lt;/h3&gt;

&lt;p&gt;For small projects, layers may be unnecessary.&lt;/p&gt;

&lt;p&gt;If you only have one application, layers may introduce &lt;strong&gt;more complexity than value&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;They shine most when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Managing multiple applications&lt;/li&gt;
&lt;li&gt;Building reusable systems&lt;/li&gt;
&lt;li&gt;Maintaining design systems&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📖 Learn more
&lt;/h2&gt;

&lt;p&gt;If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this &lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2Fj7hlfz848ut2d9ly8i8q.png" alt="Vue School Link" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Advance skills
&lt;/h2&gt;

&lt;p&gt;A certification boosts your skills, builds credibility, and opens doors to new opportunities. Whether you're advancing your career or switching paths, it's a smart step toward success.&lt;/p&gt;

&lt;p&gt;Check out Certificates.dev by clicking this &lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2F9iledpqv69huancwg283.png" alt="Certificates.dev Link" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Invest in yourself—get certified in Vue.js, JavaScript, Nuxt, Angular, React, and more!&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Summary
&lt;/h2&gt;

&lt;p&gt;Nuxt Layers introduce a powerful way to structure and reuse code across applications. When used correctly, layers can transform a collection of applications into a &lt;strong&gt;well-organized ecosystem of reusable building blocks&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But like any architectural tool, they should be applied thoughtfully and only when they truly provide value.&lt;/p&gt;

&lt;p&gt;Take care!&lt;br&gt;
And happy coding as always 🖥️&lt;/p&gt;

</description>
      <category>vue</category>
      <category>nuxt</category>
      <category>architecture</category>
      <category>performance</category>
    </item>
    <item>
      <title>How Vue Protects Your App Against Injections</title>
      <dc:creator>Jakub Andrzejewski</dc:creator>
      <pubDate>Mon, 09 Mar 2026 07:52:51 +0000</pubDate>
      <link>https://dev.to/jacobandrewsky/how-vue-protects-your-app-against-injections-cpa</link>
      <guid>https://dev.to/jacobandrewsky/how-vue-protects-your-app-against-injections-cpa</guid>
      <description>&lt;p&gt;Security is one of the most important aspects of modern web development. Applications that process user input must protect themselves against various forms of attacks — especially &lt;strong&gt;injection attacks&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Luckily, Vue provides several built-in mechanisms that help protect your application from common vulnerabilities like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cross-Site Scripting (XSS)&lt;/li&gt;
&lt;li&gt;HTML injection&lt;/li&gt;
&lt;li&gt;Attribute injection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These protections are built into the framework, meaning that in many cases &lt;strong&gt;Vue secures your app by default&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How Vue escapes interpolated content&lt;/li&gt;
&lt;li&gt;Why &lt;code&gt;v-html&lt;/code&gt; can be dangerous&lt;/li&gt;
&lt;li&gt;How Vue protects against attribute injection&lt;/li&gt;
&lt;li&gt;Best practices for keeping your Vue apps secure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 What Are Injection Attacks?
&lt;/h2&gt;

&lt;p&gt;Injection attacks occur when an attacker manages to insert malicious code into an application that is later executed in the browser.&lt;/p&gt;

&lt;p&gt;A common example is &lt;strong&gt;Cross-Site Scripting (XSS)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example of malicious input:&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="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hacked&lt;/span&gt;&lt;span class="dl"&gt;'&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your application renders this directly into the DOM, the script executes in the user’s browser.&lt;/p&gt;

&lt;p&gt;That could allow attackers to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Steal authentication tokens&lt;/li&gt;
&lt;li&gt;Hijack user sessions&lt;/li&gt;
&lt;li&gt;Inject malicious UI&lt;/li&gt;
&lt;li&gt;Redirect users to phishing pages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why modern frameworks must protect developers against unsafe rendering.&lt;/p&gt;

&lt;p&gt;Vue does exactly that.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Vue Automatic HTML Escaping
&lt;/h2&gt;

&lt;p&gt;By default, Vue &lt;strong&gt;escapes all interpolated content&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{{ userInput }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;userInput&lt;/code&gt; contains:&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="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hacked&lt;/span&gt;&lt;span class="dl"&gt;'&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vue will render it as text:&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;p&amp;gt;&lt;/span&gt;&lt;span class="ni"&gt;&amp;amp;lt;&lt;/span&gt;script&lt;span class="ni"&gt;&amp;amp;gt;&lt;/span&gt;alert('Hacked')&lt;span class="ni"&gt;&amp;amp;lt;&lt;/span&gt;/script&lt;span class="ni"&gt;&amp;amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of executing the script.&lt;/p&gt;

&lt;p&gt;This simple rule protects against most XSS attacks is that Interpolation (&lt;code&gt;{{ }}&lt;/code&gt;) is always safe.&lt;/p&gt;

&lt;p&gt;The browser sees escaped text rather than executable HTML.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Template Compilation Safety
&lt;/h2&gt;

&lt;p&gt;Vue templates are compiled into JavaScript functions.&lt;/p&gt;

&lt;p&gt;However, Vue only compiles &lt;strong&gt;trusted templates&lt;/strong&gt; — the ones written by developers.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;{{ message }}&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This template becomes optimized render functions internally.&lt;/p&gt;

&lt;p&gt;But Vue &lt;strong&gt;does not compile user-provided templates dynamically&lt;/strong&gt;. Doing so would be extremely dangerous.&lt;/p&gt;

&lt;p&gt;Bad example (never do this):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UnsafeComponent&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;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userInput&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;userInput&lt;/code&gt; contains malicious JavaScript, it could execute inside your app.&lt;/p&gt;

&lt;p&gt;The rule of thumb here is to never use user input as a Vue template.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Attribute Injection Protection
&lt;/h2&gt;

&lt;p&gt;Vue also escapes values used inside HTML attributes.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;:title=&lt;/span&gt;&lt;span class="s"&gt;"userInput"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;userInput&lt;/code&gt; contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;" onmouseover="alert('Hacked')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vue safely escapes it before inserting it into the DOM.&lt;/p&gt;

&lt;p&gt;Instead of executing malicious JavaScript, the browser treats it as a simple string value.&lt;/p&gt;

&lt;p&gt;This protects against:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Event handler injection&lt;/li&gt;
&lt;li&gt;Attribute-based XSS attacks&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🟢 URL Injection Protection
&lt;/h2&gt;

&lt;p&gt;Another attack vector involves injecting dangerous URLs like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;javascript:alert('Hacked')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;:href=&lt;/span&gt;&lt;span class="s"&gt;"userLink"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Click me&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vue &lt;strong&gt;does not automatically sanitize URLs&lt;/strong&gt;, because valid URLs may include many protocols.&lt;/p&gt;

&lt;p&gt;This means developers must validate URLs themselves.&lt;/p&gt;

&lt;p&gt;Safe practice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sanitizeUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&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;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://&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;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&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="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;:href=&lt;/span&gt;&lt;span class="s"&gt;"sanitizeUrl(userLink)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Open link&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents dangerous protocols like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;javascript:&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;data:&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vbscript:&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔴 The Danger of &lt;code&gt;v-html&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;While Vue escapes interpolation by default, &lt;code&gt;v-html&lt;/code&gt; bypasses that protection.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-html=&lt;/span&gt;&lt;span class="s"&gt;"userContent"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;userContent&lt;/code&gt; contains:&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="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;XSS&lt;/span&gt;&lt;span class="dl"&gt;'&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The script &lt;strong&gt;will execute&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That makes &lt;code&gt;v-html&lt;/code&gt; the most common source of XSS vulnerabilities in Vue apps.&lt;/p&gt;

&lt;p&gt;Only use it when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rendering trusted HTML&lt;/li&gt;
&lt;li&gt;Rendering sanitized content&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example with sanitization library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;DOMPurify&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;dompurify&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;safeHtml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;DOMPurify&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sanitize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userContent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-html=&lt;/span&gt;&lt;span class="s"&gt;"safeHtml"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧪 Best Security Practices for Vue Apps
&lt;/h2&gt;

&lt;p&gt;Even though Vue protects your application by default, developers should still follow security best practices.&lt;/p&gt;

&lt;p&gt;1.Prefer interpolation&lt;/p&gt;

&lt;p&gt;Safe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;{{ content }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Avoid:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;v-html="content"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2.Sanitize external HTML&lt;/p&gt;

&lt;p&gt;If you must render HTML, use sanitization tools like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DOMPurify&lt;/li&gt;
&lt;li&gt;sanitize-html&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3.Validate URLs&lt;/p&gt;

&lt;p&gt;Never blindly render user-provided links.&lt;/p&gt;

&lt;p&gt;Always validate allowed protocols.&lt;/p&gt;

&lt;p&gt;4.Avoid dynamic template compilation&lt;/p&gt;

&lt;p&gt;Never use user input inside Vue templates.&lt;/p&gt;

&lt;p&gt;5.Use CSP (Content Security Policy)&lt;/p&gt;

&lt;p&gt;A strong CSP header can mitigate many injection attacks.&lt;/p&gt;

&lt;p&gt;Example policy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Content-Security-Policy: script-src 'self'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents execution of inline malicious scripts.&lt;/p&gt;

&lt;h2&gt;
  
  
  📖 Learn more
&lt;/h2&gt;

&lt;p&gt;If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this &lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2Fj7hlfz848ut2d9ly8i8q.png" alt="Vue School Link" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Advance skills
&lt;/h2&gt;

&lt;p&gt;A certification boosts your skills, builds credibility, and opens doors to new opportunities. Whether you're advancing your career or switching paths, it's a smart step toward success.&lt;/p&gt;

&lt;p&gt;Check out Certificates.dev by clicking this &lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2F9iledpqv69huancwg283.png" alt="Certificates.dev Link" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Invest in yourself—get certified in Vue.js, JavaScript, Nuxt, Angular, React, and more!&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Summary
&lt;/h2&gt;

&lt;p&gt;Vue includes several built-in protections against injection attacks.&lt;/p&gt;

&lt;p&gt;These mechanisms make Vue a &lt;strong&gt;secure-by-default framework&lt;/strong&gt;, but security still depends on responsible developer practices.&lt;/p&gt;

&lt;p&gt;When used correctly, Vue helps ensure your application stays safe from common injection vulnerabilities.&lt;/p&gt;

&lt;p&gt;Take care!&lt;br&gt;
And happy coding as always 🖥️&lt;/p&gt;

</description>
      <category>vue</category>
      <category>security</category>
      <category>typescript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Lesser-Known but Powerful Vue Features</title>
      <dc:creator>Jakub Andrzejewski</dc:creator>
      <pubDate>Mon, 02 Mar 2026 08:51:59 +0000</pubDate>
      <link>https://dev.to/jacobandrewsky/lesser-known-but-powerful-vue-features-1pp0</link>
      <guid>https://dev.to/jacobandrewsky/lesser-known-but-powerful-vue-features-1pp0</guid>
      <description>&lt;p&gt;Vue is often praised for its simplicity and clean API. Most developers are familiar with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ref()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;reactive()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;computed()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;watch()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;v-if&lt;/code&gt; / &lt;code&gt;v-for&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But Vue also includes several lesser-known features that can significantly improve Performance, Code clarity, Architecture, and Developer experience.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore some powerful yet underused Vue features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nextTick()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;watchEffect()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;provide()&lt;/code&gt; / &lt;code&gt;inject()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;useId()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;shallowRef()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;v-memo&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;v-once&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;CSS &lt;code&gt;v-bind()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 Why These Features Matter
&lt;/h2&gt;

&lt;p&gt;As applications grow component trees get deeper, state becomes more complex, performance becomes critical, and reusability becomes harder.&lt;/p&gt;

&lt;p&gt;Knowing these features helps you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write cleaner logic&lt;/li&gt;
&lt;li&gt;Avoid unnecessary re-renders&lt;/li&gt;
&lt;li&gt;Improve performance&lt;/li&gt;
&lt;li&gt;Build better abstractions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They’re not always needed — but when they are, they’re incredibly useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 nextTick()
&lt;/h2&gt;

&lt;p&gt;Vue updates the DOM asynchronously. That means when you change state, the DOM is not updated immediately.&lt;/p&gt;

&lt;p&gt;Sometimes you need to wait for the DOM to update before running code.&lt;/p&gt;

&lt;p&gt;That’s where &lt;code&gt;nextTick()&lt;/code&gt; comes in.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&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;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nextTick&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;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;nextTick&lt;/span&gt;&lt;span class="p"&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;DOM updated&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;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accessing updated DOM elements&lt;/li&gt;
&lt;li&gt;Measuring element size&lt;/li&gt;
&lt;li&gt;Managing focus after state change&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without &lt;code&gt;nextTick()&lt;/code&gt;, you may interact with outdated DOM.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 watchEffect()
&lt;/h2&gt;

&lt;p&gt;Most developers use &lt;code&gt;watch()&lt;/code&gt;, but &lt;code&gt;watchEffect()&lt;/code&gt; is often simpler.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;watchEffect()&lt;/code&gt; automatically tracks reactive dependencies.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&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;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;watchEffect&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;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;watchEffect&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;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;Count is:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No need to specify dependencies manually.&lt;/p&gt;

&lt;p&gt;Difference:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;watch()&lt;/code&gt; → explicit dependency&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;watchEffect()&lt;/code&gt; → automatic dependency tracking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Best used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Side effects&lt;/li&gt;
&lt;li&gt;Logging&lt;/li&gt;
&lt;li&gt;Reactive debugging&lt;/li&gt;
&lt;li&gt;Simple reactive reactions&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🟢 provide() / inject()
&lt;/h2&gt;

&lt;p&gt;Prop drilling becomes painful in large component trees.&lt;/p&gt;

&lt;p&gt;Instead of passing props multiple levels down, you can use dependency injection.&lt;/p&gt;

&lt;p&gt;Parent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&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;provide&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;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nf"&gt;provide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;theme&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;dark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Child (deeply nested):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&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;inject&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;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;theme&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Theming&lt;/li&gt;
&lt;li&gt;Plugin systems&lt;/li&gt;
&lt;li&gt;Form context&lt;/li&gt;
&lt;li&gt;Shared services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s lightweight and avoids unnecessary prop chains.&lt;/p&gt;

&lt;p&gt;But remember:&lt;/p&gt;

&lt;p&gt;👉 It’s not a state management replacement. Use it intentionally.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 useId()
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;useId()&lt;/code&gt; generates unique, SSR-safe IDs.&lt;/p&gt;

&lt;p&gt;Very useful for accessibility and form labeling.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&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;useId&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;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useId&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;:for=&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Email&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;:id=&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No ID collisions&lt;/li&gt;
&lt;li&gt;SSR compatibility&lt;/li&gt;
&lt;li&gt;Cleaner form components&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Especially helpful in reusable UI libraries.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 shallowRef()
&lt;/h2&gt;

&lt;p&gt;Normally, &lt;code&gt;ref()&lt;/code&gt; makes nested objects reactive.&lt;/p&gt;

&lt;p&gt;But sometimes you don’t want deep reactivity.&lt;/p&gt;

&lt;p&gt;That’s where &lt;code&gt;shallowRef()&lt;/code&gt; helps.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&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;shallowRef&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;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chartInstance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;shallowRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Best used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Third-party libraries&lt;/li&gt;
&lt;li&gt;Large objects&lt;/li&gt;
&lt;li&gt;Non-reactive instances&lt;/li&gt;
&lt;li&gt;Performance optimization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;shallowRef()&lt;/code&gt; tracks only &lt;code&gt;.value&lt;/code&gt; changes — not nested properties.&lt;/p&gt;

&lt;p&gt;This avoids unnecessary reactive overhead.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 v-once
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;v-once&lt;/code&gt; renders an element only once.&lt;/p&gt;

&lt;p&gt;After that, it never updates again.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;v-once&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Static Title
&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Static content&lt;/li&gt;
&lt;li&gt;Large lists of immutable data&lt;/li&gt;
&lt;li&gt;Performance optimization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Be careful:&lt;/p&gt;

&lt;p&gt;👉 It will never update — even if data changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 v-memo
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;v-memo&lt;/code&gt; is lesser-known but powerful.&lt;/p&gt;

&lt;p&gt;It memoizes part of a template based on dependencies.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-memo=&lt;/span&gt;&lt;span class="s"&gt;"[user.id]"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  {{ user.name }}
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The block only re-renders when &lt;code&gt;user.id&lt;/code&gt; changes.&lt;/p&gt;

&lt;p&gt;Useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large lists&lt;/li&gt;
&lt;li&gt;Performance-critical UI&lt;/li&gt;
&lt;li&gt;Preventing unnecessary updates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It gives you fine-grained control over rendering behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 CSS v-bind()
&lt;/h2&gt;

&lt;p&gt;Vue allows binding reactive values directly inside &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&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;ref&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;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&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;"box"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Hello&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt; &lt;span class="na"&gt;scoped&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nc"&gt;.box&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;v-bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This enables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dynamic styling without inline styles&lt;/li&gt;
&lt;li&gt;Cleaner separation of logic and presentation&lt;/li&gt;
&lt;li&gt;Reactive CSS variables&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Great for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Theming&lt;/li&gt;
&lt;li&gt;Dynamic layouts&lt;/li&gt;
&lt;li&gt;Design systems&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📖 Learn more
&lt;/h2&gt;

&lt;p&gt;If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this &lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2Fj7hlfz848ut2d9ly8i8q.png" alt="Vue School Link" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 Advance skills
&lt;/h2&gt;

&lt;p&gt;A certification boosts your skills, builds credibility, and opens doors to new opportunities. Whether you're advancing your career or switching paths, it's a smart step toward success.&lt;/p&gt;

&lt;p&gt;Check out Certificates.dev by clicking this &lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2F9iledpqv69huancwg283.png" alt="Certificates.dev Link" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Invest in yourself—get certified in Vue.js, JavaScript, Nuxt, Angular, React, and more!&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Summary
&lt;/h2&gt;

&lt;p&gt;Vue has many powerful features beyond the basics.&lt;/p&gt;

&lt;p&gt;In this article, you discovered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How &lt;code&gt;nextTick()&lt;/code&gt; helps with DOM timing&lt;/li&gt;
&lt;li&gt;Why &lt;code&gt;watchEffect()&lt;/code&gt; simplifies reactive side effects&lt;/li&gt;
&lt;li&gt;How &lt;code&gt;provide()&lt;/code&gt; / &lt;code&gt;inject()&lt;/code&gt; reduces prop drilling&lt;/li&gt;
&lt;li&gt;When to use &lt;code&gt;useId()&lt;/code&gt; for accessibility&lt;/li&gt;
&lt;li&gt;How &lt;code&gt;shallowRef()&lt;/code&gt; optimizes performance&lt;/li&gt;
&lt;li&gt;How &lt;code&gt;v-once&lt;/code&gt; and &lt;code&gt;v-memo&lt;/code&gt; improve rendering control&lt;/li&gt;
&lt;li&gt;How CSS &lt;code&gt;v-bind()&lt;/code&gt; enables reactive styling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These features can elevate your Vue code from good to great — when used intentionally.&lt;/p&gt;

&lt;p&gt;Take care!&lt;br&gt;
And happy coding as always 🖥️&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>vue</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Accessibility in Vue: Quick Tips for Building Inclusive Apps</title>
      <dc:creator>Jakub Andrzejewski</dc:creator>
      <pubDate>Mon, 23 Feb 2026 08:29:06 +0000</pubDate>
      <link>https://dev.to/jacobandrewsky/accessibility-in-vue-quick-tips-for-building-inclusive-apps-2ne0</link>
      <guid>https://dev.to/jacobandrewsky/accessibility-in-vue-quick-tips-for-building-inclusive-apps-2ne0</guid>
      <description>&lt;p&gt;Accessibility is not a “nice to have” — it is a fundamental part of building modern web applications.&lt;/p&gt;

&lt;p&gt;An accessible application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reaches more users&lt;/li&gt;
&lt;li&gt;Improves usability for everyone&lt;/li&gt;
&lt;li&gt;Reduces legal risks&lt;/li&gt;
&lt;li&gt;Strengthens brand reputation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When working with Vue, accessibility is largely in your hands. Vue does not limit accessibility — but it also does not automatically solve it for you.&lt;/p&gt;

&lt;p&gt;In this article, we’ll go through practical and quick tips for improving accessibility in Vue apps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keyboard shortcuts &amp;amp; navigation&lt;/li&gt;
&lt;li&gt;ARIA labels &amp;amp; roles&lt;/li&gt;
&lt;li&gt;Focus management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 Why Accessibility Matters in Vue Apps
&lt;/h2&gt;

&lt;p&gt;Modern SPAs introduce challenges that traditional multi-page websites did not have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dynamic content updates&lt;/li&gt;
&lt;li&gt;Client-side routing&lt;/li&gt;
&lt;li&gt;Modal dialogs&lt;/li&gt;
&lt;li&gt;Complex component trees&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without proper accessibility handling, users relying on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Screen readers&lt;/li&gt;
&lt;li&gt;Keyboard navigation&lt;/li&gt;
&lt;li&gt;Assistive technologies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;may struggle to use your app.&lt;/p&gt;

&lt;p&gt;The good news? Most accessibility improvements require small, intentional changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Keyboard Navigation &amp;amp; Shortcuts
&lt;/h2&gt;

&lt;p&gt;Many users do not use a mouse. They rely entirely on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Tab&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Shift + Tab&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Enter&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Space&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Arrow keys&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Make Elements Focusable
&lt;/h3&gt;

&lt;p&gt;Use semantic HTML whenever possible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Submit
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Avoid:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Submit
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you must use a non-semantic element, make it keyboard-accessible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;
  &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;
  &lt;span class="na"&gt;tabindex=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
  &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;
  &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;keydown.enter=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Submit
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Logical Tab Order
&lt;/h3&gt;

&lt;p&gt;Ensure that your DOM structure follows a logical navigation flow.&lt;/p&gt;

&lt;p&gt;Avoid:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Random &lt;code&gt;tabindex&lt;/code&gt; values&lt;/li&gt;
&lt;li&gt;Skipping interactive elements&lt;/li&gt;
&lt;li&gt;Hidden focus traps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use &lt;code&gt;tabindex="0"&lt;/code&gt; only when necessary.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keyboard Shortcuts
&lt;/h3&gt;

&lt;p&gt;Vue makes it easy to listen for keyboard events:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&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;onMounted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onBeforeUnmount&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;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&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;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;k&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ctrlKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;openSearch&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="nf"&gt;onMounted&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="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nf"&gt;onBeforeUnmount&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="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Best practices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Always document shortcuts&lt;/li&gt;
&lt;li&gt;Avoid overriding browser defaults&lt;/li&gt;
&lt;li&gt;Provide alternative UI access&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keyboard shortcuts should enhance usability — not replace accessibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 ARIA Labels &amp;amp; Roles
&lt;/h2&gt;

&lt;p&gt;ARIA (Accessible Rich Internet Applications) attributes help screen readers understand UI meaning when semantic HTML is not enough.&lt;/p&gt;

&lt;h3&gt;
  
  
  aria-label
&lt;/h3&gt;

&lt;p&gt;Useful when visual text is not descriptive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;aria-label=&lt;/span&gt;&lt;span class="s"&gt;"Close modal"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"close"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without &lt;code&gt;aria-label&lt;/code&gt;, a screen reader might only read “button”.&lt;/p&gt;

&lt;h3&gt;
  
  
  aria-hidden
&lt;/h3&gt;

&lt;p&gt;Hide decorative elements from assistive technologies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;aria-hidden=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;🎉&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  aria-live
&lt;/h3&gt;

&lt;p&gt;For dynamic updates (like notifications):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;aria-live=&lt;/span&gt;&lt;span class="s"&gt;"polite"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  {{ message }}
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This informs screen readers that content has changed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Proper Roles
&lt;/h3&gt;

&lt;p&gt;If you create custom components (dropdowns, tabs, modals), use appropriate roles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"dialog"&lt;/span&gt; &lt;span class="na"&gt;aria-modal=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Settings&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, remember:&lt;/p&gt;

&lt;p&gt;👉 Native HTML elements are always preferred over ARIA when possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Focus Management
&lt;/h2&gt;

&lt;p&gt;Focus management is one of the most overlooked accessibility issues in Vue apps.&lt;/p&gt;

&lt;p&gt;Especially when dealing with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modals&lt;/li&gt;
&lt;li&gt;Route changes&lt;/li&gt;
&lt;li&gt;Dynamic content&lt;/li&gt;
&lt;li&gt;Dropdowns&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Managing Focus in Modals
&lt;/h3&gt;

&lt;p&gt;When opening a modal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Move focus into the modal&lt;/li&gt;
&lt;li&gt;Trap focus inside&lt;/li&gt;
&lt;li&gt;Return focus when closing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&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;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nextTick&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;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;modalRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;openModal&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;isOpen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

  &lt;span class="nf"&gt;nextTick&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;modalRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;focus&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="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&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;v-if=&lt;/span&gt;&lt;span class="s"&gt;"isOpen"&lt;/span&gt;
    &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"modalRef"&lt;/span&gt;
    &lt;span class="na"&gt;tabindex=&lt;/span&gt;&lt;span class="s"&gt;"-1"&lt;/span&gt;
    &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"dialog"&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Modal content
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Focus After Route Changes
&lt;/h3&gt;

&lt;p&gt;In SPAs, screen readers do not automatically detect route changes.&lt;/p&gt;

&lt;p&gt;You should move focus to the main heading after navigation.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&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;useRoute&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;vue-router&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;watch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nextTick&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;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRoute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;watch&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;route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &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="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;nextTick&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nb"&gt;document&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;h1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="nf"&gt;focus&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And ensure the heading is focusable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;tabindex=&lt;/span&gt;&lt;span class="s"&gt;"-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Page Title
&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Avoid Focus Traps
&lt;/h3&gt;

&lt;p&gt;Common mistakes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Removing elements without restoring focus&lt;/li&gt;
&lt;li&gt;Dynamically hiding focused elements&lt;/li&gt;
&lt;li&gt;Infinite focus loops&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Always test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tab navigation&lt;/li&gt;
&lt;li&gt;Shift + Tab navigation&lt;/li&gt;
&lt;li&gt;Screen reader behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🧪 Quick Accessibility Checklist for Vue
&lt;/h2&gt;

&lt;p&gt;Before shipping your feature:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Can I navigate everything using only keyboard?&lt;/li&gt;
&lt;li&gt;✅ Are all buttons real &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; elements?&lt;/li&gt;
&lt;li&gt;✅ Do interactive icons have &lt;code&gt;aria-label&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;✅ Does focus move correctly after modals and navigation?&lt;/li&gt;
&lt;li&gt;✅ Are dynamic updates announced properly?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These small checks dramatically improve usability.&lt;/p&gt;

&lt;h2&gt;
  
  
  📖 Learn more
&lt;/h2&gt;

&lt;p&gt;If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this &lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2Fj7hlfz848ut2d9ly8i8q.png" alt="Vue School Link" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Advance skills
&lt;/h2&gt;

&lt;p&gt;A certification boosts your skills, builds credibility, and opens doors to new opportunities. Whether you're advancing your career or switching paths, it's a smart step toward success.&lt;/p&gt;

&lt;p&gt;Check out Certificates.dev by clicking this &lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2F9iledpqv69huancwg283.png" alt="Certificates.dev Link" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Invest in yourself—get certified in Vue.js, JavaScript, Nuxt, Angular, React, and more!&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Summary
&lt;/h2&gt;

&lt;p&gt;Accessibility in Vue does not require massive architectural changes — it requires &lt;strong&gt;intentional implementation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Small improvements make your app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More inclusive&lt;/li&gt;
&lt;li&gt;More professional&lt;/li&gt;
&lt;li&gt;More compliant&lt;/li&gt;
&lt;li&gt;More usable for everyone&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Take care!&lt;br&gt;
And happy coding as always 🖥️&lt;/p&gt;

</description>
      <category>vue</category>
      <category>a11y</category>
      <category>html</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Business Advantages of Using Nuxt</title>
      <dc:creator>Jakub Andrzejewski</dc:creator>
      <pubDate>Mon, 16 Feb 2026 10:10:53 +0000</pubDate>
      <link>https://dev.to/jacobandrewsky/business-advantages-of-using-nuxt-51j2</link>
      <guid>https://dev.to/jacobandrewsky/business-advantages-of-using-nuxt-51j2</guid>
      <description>&lt;p&gt;Choosing the right framework is not just a technical decision — it’s a &lt;strong&gt;business decision&lt;/strong&gt;. When building modern web applications, companies care about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scalability&lt;/li&gt;
&lt;li&gt;Performance&lt;/li&gt;
&lt;li&gt;SEO&lt;/li&gt;
&lt;li&gt;Accessibility&lt;/li&gt;
&lt;li&gt;Hosting flexibility&lt;/li&gt;
&lt;li&gt;Enterprise integrations&lt;/li&gt;
&lt;li&gt;Long-term maintainability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where &lt;strong&gt;Nuxt&lt;/strong&gt; becomes more than just a Vue meta-framework — it becomes a strategic advantage.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why Nuxt is hosting-agnostic&lt;/li&gt;
&lt;li&gt;How its module ecosystem benefits enterprise projects&lt;/li&gt;
&lt;li&gt;Built-in SEO advantages (including &lt;code&gt;@nuxtjs/seo&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Accessibility support with &lt;code&gt;@nuxt/a11y&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Performance optimization with Hints&lt;/li&gt;
&lt;li&gt;Script and font optimization modules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 Why Framework Choice Matters for Business
&lt;/h2&gt;

&lt;p&gt;From a business perspective, poor architectural decisions can lead to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ Expensive rewrites&lt;/li&gt;
&lt;li&gt;❌ SEO problems and lost traffic&lt;/li&gt;
&lt;li&gt;❌ Performance issues affecting conversion rates&lt;/li&gt;
&lt;li&gt;❌ Vendor lock-in&lt;/li&gt;
&lt;li&gt;❌ Slower time-to-market&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nuxt reduces these risks by providing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SSR / SSG / Hybrid rendering&lt;/li&gt;
&lt;li&gt;A powerful module ecosystem&lt;/li&gt;
&lt;li&gt;Enterprise-ready integrations&lt;/li&gt;
&lt;li&gt;Deployment flexibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes it attractive not only to developers — but to CTOs and product teams as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Hosting Agnostic Architecture
&lt;/h2&gt;

&lt;p&gt;One of Nuxt’s strongest business advantages is that it is &lt;strong&gt;hosting agnostic&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can deploy Nuxt to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node servers&lt;/li&gt;
&lt;li&gt;Serverless platforms&lt;/li&gt;
&lt;li&gt;Edge runtimes&lt;/li&gt;
&lt;li&gt;Static hosting&lt;/li&gt;
&lt;li&gt;Docker environments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You are not locked into a specific cloud provider.&lt;/p&gt;

&lt;p&gt;Nuxt supports adapters and deployment to platforms like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vercel&lt;/li&gt;
&lt;li&gt;Netlify&lt;/li&gt;
&lt;li&gt;AWS&lt;/li&gt;
&lt;li&gt;Azure&lt;/li&gt;
&lt;li&gt;Google Cloud&lt;/li&gt;
&lt;li&gt;Traditional VPS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ No vendor lock-in&lt;/li&gt;
&lt;li&gt;✅ Easier migration between providers&lt;/li&gt;
&lt;li&gt;✅ Cost optimization flexibility&lt;/li&gt;
&lt;li&gt;✅ Infrastructure freedom&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For businesses, this reduces long-term risk significantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Enterprise Module Ecosystem
&lt;/h2&gt;

&lt;p&gt;Nuxt’s module ecosystem is one of its biggest strengths.&lt;/p&gt;

&lt;p&gt;Instead of building integrations from scratch, you can rely on production-ready modules for enterprise services such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Storyblok&lt;/li&gt;
&lt;li&gt;Sanity&lt;/li&gt;
&lt;li&gt;Cloudinary&lt;/li&gt;
&lt;li&gt;Stripe&lt;/li&gt;
&lt;li&gt;Supabase&lt;/li&gt;
&lt;li&gt;Auth providers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example: using Storyblok module&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx nuxi module add storyblok
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example configuration:&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="nf"&gt;defineNuxtConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;modules&lt;/span&gt;&lt;span class="p"&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;@storyblok/nuxt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;storyblok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;STORYBLOK_TOKEN&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 gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CMS integration&lt;/li&gt;
&lt;li&gt;Live preview support&lt;/li&gt;
&lt;li&gt;SSR compatibility&lt;/li&gt;
&lt;li&gt;Production-ready setup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The same applies to Sanity or Cloudinary — reducing development time and integration costs.&lt;/p&gt;

&lt;p&gt;For businesses, this means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🚀 Faster time-to-market&lt;/li&gt;
&lt;li&gt;🧩 Reliable integrations&lt;/li&gt;
&lt;li&gt;💰 Lower development cost&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🟢 Built-in SEO Capabilities
&lt;/h2&gt;

&lt;p&gt;SEO is critical for organic traffic and revenue.&lt;/p&gt;

&lt;p&gt;Nuxt provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server-side rendering (SSR)&lt;/li&gt;
&lt;li&gt;Static generation (SSG)&lt;/li&gt;
&lt;li&gt;Meta management&lt;/li&gt;
&lt;li&gt;Sitemap support&lt;/li&gt;
&lt;li&gt;Robots.txt support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Additionally, you can use the official &lt;code&gt;@nuxtjs/seo&lt;/code&gt; module to centralize and standardize SEO configuration across your application.&lt;/p&gt;

&lt;p&gt;Install it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx nuxi module add @nuxtjs/seo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basic configuration:&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="nf"&gt;defineNuxtConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;modules&lt;/span&gt;&lt;span class="p"&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;@nuxtjs/seo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;seo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;redirectToCanonicalSiteUrl&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And dynamic metadata with composables:&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="nf"&gt;useSeoMeta&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nuxt Business Advantages&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Learn why Nuxt is a strategic framework choice.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;ogTitle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nuxt for Business&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;ogDescription&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Enterprise-ready Vue framework&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nuxt ensures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Better indexing&lt;/li&gt;
&lt;li&gt;✅ Improved Core Web Vitals&lt;/li&gt;
&lt;li&gt;✅ Stronger search visibility&lt;/li&gt;
&lt;li&gt;✅ Consistent SEO configuration at scale&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For e-commerce and marketing-driven platforms, this directly impacts revenue.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Accessibility Support with @nuxt/a11y
&lt;/h2&gt;

&lt;p&gt;Accessibility is no longer optional — it is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A legal requirement in many regions&lt;/li&gt;
&lt;li&gt;A brand reputation factor&lt;/li&gt;
&lt;li&gt;A usability advantage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nuxt provides an official accessibility module: &lt;code&gt;@nuxt/a11y&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Install it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx nuxi module add @nuxt/a11y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basic configuration:&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="nf"&gt;defineNuxtConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;modules&lt;/span&gt;&lt;span class="p"&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;@nuxt/a11y&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;a11y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;enabled&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The module helps with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automated accessibility checks&lt;/li&gt;
&lt;li&gt;WCAG compliance improvements&lt;/li&gt;
&lt;li&gt;Accessibility devtools integration&lt;/li&gt;
&lt;li&gt;Route announcements for screen readers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For enterprises, this reduces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⚖️ Legal risks&lt;/li&gt;
&lt;li&gt;🧪 Manual QA costs&lt;/li&gt;
&lt;li&gt;♿ Accessibility regressions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Accessibility becomes part of the development workflow — not an afterthought.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Performance Optimization with Nuxt Hints
&lt;/h2&gt;

&lt;p&gt;Performance directly affects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Conversion rates&lt;/li&gt;
&lt;li&gt;SEO rankings&lt;/li&gt;
&lt;li&gt;User engagement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nuxt provides performance optimization tools like &lt;strong&gt;Nuxt Hints&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Nuxt Hints helps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identify render bottlenecks&lt;/li&gt;
&lt;li&gt;Detect unnecessary payload size&lt;/li&gt;
&lt;li&gt;Suggest performance improvements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This gives teams visibility into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hydration issues&lt;/li&gt;
&lt;li&gt;Bundle size problems&lt;/li&gt;
&lt;li&gt;Runtime inefficiencies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of guessing, teams can measure and optimize systematically.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Script Optimization with Nuxt Scripts
&lt;/h2&gt;

&lt;p&gt;Third-party scripts are often a major performance and security problem.&lt;/p&gt;

&lt;p&gt;Nuxt provides &lt;code&gt;@nuxt/scripts&lt;/code&gt; to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Control when scripts load&lt;/li&gt;
&lt;li&gt;Define triggers&lt;/li&gt;
&lt;li&gt;Add warmup strategies&lt;/li&gt;
&lt;li&gt;Improve security&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineNuxtConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;modules&lt;/span&gt;&lt;span class="p"&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;@nuxt/scripts&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;Google Analytics example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nf"&gt;useScript&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://www.googletagmanager.com/gtag/js?id=GA_ID&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;onInteraction&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🚀 Improved performance&lt;/li&gt;
&lt;li&gt;🔐 Safer script execution&lt;/li&gt;
&lt;li&gt;🎯 Controlled loading strategies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For business-critical apps, this means fewer third-party performance issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Font Optimization
&lt;/h2&gt;

&lt;p&gt;Fonts can significantly slow down rendering.&lt;/p&gt;

&lt;p&gt;Nuxt offers modules to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Self-host fonts&lt;/li&gt;
&lt;li&gt;Optimize font loading&lt;/li&gt;
&lt;li&gt;Avoid layout shifts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example configuration:&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="nf"&gt;defineNuxtConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;modules&lt;/span&gt;&lt;span class="p"&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;@nuxt/fonts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;fonts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="na"&gt;defaults&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;weights&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;styles&lt;/span&gt;&lt;span class="p"&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;normal&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;italic&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;subsets&lt;/span&gt;&lt;span class="p"&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;cyrillic-ext&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;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;p&gt;This reduces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CLS (Cumulative Layout Shift)&lt;/li&gt;
&lt;li&gt;Render-blocking resources&lt;/li&gt;
&lt;li&gt;External dependency risk&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Performance improvements directly impact user retention and conversion.&lt;/p&gt;

&lt;h2&gt;
  
  
  📖 Learn more
&lt;/h2&gt;

&lt;p&gt;If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this &lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2Fj7hlfz848ut2d9ly8i8q.png" alt="Vue School Link" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Advance skills
&lt;/h2&gt;

&lt;p&gt;A certification boosts your skills, builds credibility, and opens doors to new opportunities. Whether you're advancing your career or switching paths, it's a smart step toward success.&lt;/p&gt;

&lt;p&gt;Check out Certificates.dev by clicking this &lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;link&lt;/a&gt; or by clicking the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;&lt;img src="https://media2.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%2F9iledpqv69huancwg283.png" alt="Certificates.dev Link" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Invest in yourself—get certified in Vue.js, JavaScript, Nuxt, Angular, React, and more!&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Summary
&lt;/h2&gt;

&lt;p&gt;Nuxt is not just a developer-friendly framework — it is a &lt;strong&gt;business-ready platform&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hosting agnostic deployment&lt;/li&gt;
&lt;li&gt;Enterprise module ecosystem&lt;/li&gt;
&lt;li&gt;Built-in SEO support with &lt;code&gt;@nuxtjs/seo&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Accessibility tooling with &lt;code&gt;@nuxt/a11y&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Performance optimization (Hints)&lt;/li&gt;
&lt;li&gt;Script and font management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For companies, this means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lower long-term risk&lt;/li&gt;
&lt;li&gt;Faster development cycles&lt;/li&gt;
&lt;li&gt;Better performance and SEO&lt;/li&gt;
&lt;li&gt;Improved scalability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Choosing Nuxt is not just about Vue — it’s about making a strategic technical decision that supports business growth.&lt;/p&gt;

&lt;p&gt;Take care!&lt;br&gt;
And happy coding as always 🖥️&lt;/p&gt;

</description>
      <category>nuxt</category>
      <category>vue</category>
      <category>seo</category>
      <category>a11y</category>
    </item>
  </channel>
</rss>
