<?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>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>
    <item>
      <title>Responsive Images for Better Web Performance</title>
      <dc:creator>Jakub Andrzejewski</dc:creator>
      <pubDate>Mon, 09 Feb 2026 07:50:32 +0000</pubDate>
      <link>https://dev.to/jacobandrewsky/responsive-images-for-better-web-performance-55hn</link>
      <guid>https://dev.to/jacobandrewsky/responsive-images-for-better-web-performance-55hn</guid>
      <description>&lt;p&gt;Images are often the &lt;strong&gt;largest assets&lt;/strong&gt; on a website—and one of the most common performance bottlenecks. Serving the same large image to every device, regardless of screen size or resolution, leads to wasted bandwidth, slower load times, and poor user experience.&lt;/p&gt;

&lt;p&gt;This problem becomes even more visible in modern frameworks like Vue and Nuxt, where performance, SEO, and Core Web Vitals matter more than ever.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Why non-responsive images are a performance problem&lt;/li&gt;
&lt;li&gt;How responsive images work on the web&lt;/li&gt;
&lt;li&gt;How to implement responsive images in plain HTML&lt;/li&gt;
&lt;li&gt;How to optimize images in Nuxt using &lt;strong&gt;unpic-vue&lt;/strong&gt; and &lt;strong&gt;Nuxt Image&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  🤔 What’s the Problem With Non-Responsive Images?
&lt;/h2&gt;

&lt;p&gt;When you serve a single static image like this:&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;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/hero.jpg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Hero image"&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 user downloads the &lt;strong&gt;same file&lt;/strong&gt;, whether they are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;on a mobile phone&lt;/li&gt;
&lt;li&gt;on a tablet&lt;/li&gt;
&lt;li&gt;on a high-resolution desktop display&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This leads to several issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ Mobile users download unnecessarily large images&lt;/li&gt;
&lt;li&gt;❌ Slower page load and Time to Interactive&lt;/li&gt;
&lt;li&gt;❌ Worse Core Web Vitals (especially LCP)&lt;/li&gt;
&lt;li&gt;❌ Higher data usage and costs for users&lt;/li&gt;
&lt;li&gt;❌ Poor SEO performance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Modern websites need images that &lt;strong&gt;adapt to the device&lt;/strong&gt;, not the other way around.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 How Responsive Images Work on the Web
&lt;/h2&gt;

&lt;p&gt;Responsive images allow the browser to decide &lt;strong&gt;which image variant&lt;/strong&gt; to download based on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;viewport size&lt;/li&gt;
&lt;li&gt;device pixel ratio&lt;/li&gt;
&lt;li&gt;layout constraints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is achieved using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;srcset&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sizes&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; element&lt;/li&gt;
&lt;li&gt;modern image formats (WebP, AVIF)&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 html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
  &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"image-800.jpg"&lt;/span&gt;
  &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"
    image-400.jpg 400w,
    image-800.jpg 800w,
    image-1600.jpg 1600w
  "&lt;/span&gt;
  &lt;span class="na"&gt;sizes=&lt;/span&gt;&lt;span class="s"&gt;"(max-width: 600px) 90vw, 800px"&lt;/span&gt;
  &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Responsive example"&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;The browser automatically selects the &lt;strong&gt;best possible image&lt;/strong&gt; for the current device.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Using unpic-vue for Responsive Images in Vue
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;unpic-vue&lt;/strong&gt; provides a framework-agnostic way to generate optimized, responsive images with a clean API.&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;Image&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;@unpic/vue&lt;/span&gt;&lt;span class="dl"&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;Image&lt;/span&gt;
    &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://your-website.com/image.jpeg"&lt;/span&gt;
    &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Amazing Product Image"&lt;/span&gt;
    &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"800"&lt;/span&gt;
    &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"600"&lt;/span&gt;
    &lt;span class="na"&gt;layout=&lt;/span&gt;&lt;span class="s"&gt;"constrained"&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;What you get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;automatic &lt;code&gt;srcset&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;responsive sizing&lt;/li&gt;
&lt;li&gt;modern image formats&lt;/li&gt;
&lt;li&gt;lazy loading by default&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a great choice when you want provider-agnostic image optimization in Vue but also other frameworks like React, Angular, Svelte and more.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Optimizing Images in Nuxt with Nuxt Image
&lt;/h2&gt;

&lt;p&gt;Nuxt offers a first-class solution via &lt;strong&gt;Nuxt Image&lt;/strong&gt;, designed specifically for SSR and performance.&lt;/p&gt;

&lt;p&gt;Example using &lt;code&gt;&amp;lt;NuxtImg&amp;gt;&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;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;NuxtImg&lt;/span&gt;
    &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/hero.jpg"&lt;/span&gt;
    &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"1200"&lt;/span&gt;
    &lt;span class="na"&gt;sizes=&lt;/span&gt;&lt;span class="s"&gt;"(max-width: 768px) 100vw, 1200px"&lt;/span&gt;
    &lt;span class="na"&gt;format=&lt;/span&gt;&lt;span class="s"&gt;"webp"&lt;/span&gt;
    &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Hero image"&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;Nuxt Image automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generates responsive variants&lt;/li&gt;
&lt;li&gt;serves modern formats&lt;/li&gt;
&lt;li&gt;integrates with CDNs&lt;/li&gt;
&lt;li&gt;optimizes for SSR and hydration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It supports providers like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;static&lt;/li&gt;
&lt;li&gt;IPX&lt;/li&gt;
&lt;li&gt;Cloudinary&lt;/li&gt;
&lt;li&gt;ImageKit&lt;/li&gt;
&lt;li&gt;and more&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For Nuxt applications, this is usually the &lt;strong&gt;best default choice&lt;/strong&gt;.&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;Responsive images are one of the &lt;strong&gt;highest-impact performance optimizations&lt;/strong&gt; you can make.&lt;/p&gt;

&lt;p&gt;Serving the right image to the right device improves load times, SEO, Core Web Vitals, and user satisfaction—all with relatively little effort.&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>performance</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Using effectScope to Control Vue Reactivity Lifecycles</title>
      <dc:creator>Jakub Andrzejewski</dc:creator>
      <pubDate>Mon, 02 Feb 2026 13:06:58 +0000</pubDate>
      <link>https://dev.to/jacobandrewsky/using-effectscope-to-control-vue-reactivity-lifecycles-2mml</link>
      <guid>https://dev.to/jacobandrewsky/using-effectscope-to-control-vue-reactivity-lifecycles-2mml</guid>
      <description>&lt;p&gt;Vue’s reactivity system is powerful, but that power comes with responsibility. As applications grow, uncontrolled reactive effects can easily outlive the components that created them, leading to memory leaks, unnecessary recomputation, and hard-to-debug behavior.&lt;/p&gt;

&lt;p&gt;This is especially common when working with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;composables reused across multiple components&lt;/li&gt;
&lt;li&gt;manual watchers and effects&lt;/li&gt;
&lt;li&gt;integrations with external systems&lt;/li&gt;
&lt;li&gt;long-lived reactive processes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vue 3 introduced &lt;strong&gt;&lt;code&gt;effectScope&lt;/code&gt;&lt;/strong&gt; to give developers explicit control over the &lt;strong&gt;lifecycle of reactive effects&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 &lt;code&gt;effectScope&lt;/code&gt; is and why it exists&lt;/li&gt;
&lt;li&gt;How it helps manage reactivity lifecycles&lt;/li&gt;
&lt;li&gt;Practical examples with composables and watchers&lt;/li&gt;
&lt;li&gt;When you should (and shouldn’t) use it&lt;/li&gt;
&lt;li&gt;How it prevents subtle performance and memory issues&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  🤔 What Is &lt;code&gt;effectScope&lt;/code&gt; in Vue?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;effectScope&lt;/code&gt; is a low-level Vue API that allows you to &lt;strong&gt;group reactive effects&lt;/strong&gt; (like &lt;code&gt;watch&lt;/code&gt;, &lt;code&gt;watchEffect&lt;/code&gt;, and computed dependencies) into a single scope that can be &lt;strong&gt;stopped all at once&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In simple terms:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It lets you control &lt;em&gt;when reactivity starts and when it ends&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Without &lt;code&gt;effectScope&lt;/code&gt;, reactive effects are tied implicitly to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the current component instance, or&lt;/li&gt;
&lt;li&gt;global execution context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This works most of the time — until it doesn’t.&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;effectScope&lt;/code&gt; when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;building complex composables&lt;/li&gt;
&lt;li&gt;managing reactivity outside components&lt;/li&gt;
&lt;li&gt;working with plugins or services&lt;/li&gt;
&lt;li&gt;creating start/stop reactive behavior&lt;/li&gt;
&lt;li&gt;debugging memory or performance issues&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🟢 The Problem: Reactivity That Lives Too Long
&lt;/h2&gt;

&lt;p&gt;Consider a composable that sets up a watcher:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&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="nx"&gt;source&lt;/span&gt;&lt;span class="p"&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="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="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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this composable is used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;outside of a component&lt;/li&gt;
&lt;li&gt;inside a plugin&lt;/li&gt;
&lt;li&gt;conditionally&lt;/li&gt;
&lt;li&gt;or repeatedly without cleanup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That watcher may:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;never be disposed&lt;/li&gt;
&lt;li&gt;keep reacting forever&lt;/li&gt;
&lt;li&gt;leak memory&lt;/li&gt;
&lt;li&gt;react to stale state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where &lt;code&gt;effectScope&lt;/code&gt; becomes essential.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Basic Usage of &lt;code&gt;effectScope&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Here’s the simplest 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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;effectScope&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;watch&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;scope&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;effectScope&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;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;watch&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="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="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="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="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stop&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 here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All reactive effects created inside &lt;code&gt;run()&lt;/code&gt; are tracked&lt;/li&gt;
&lt;li&gt;Calling &lt;code&gt;stop()&lt;/code&gt; disposes &lt;strong&gt;everything at once&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;No lingering watchers, no surprises&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This explicit lifecycle control is the key benefit.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Using &lt;code&gt;effectScope&lt;/code&gt; Inside Composables
&lt;/h2&gt;

&lt;p&gt;One of the best use cases for &lt;code&gt;effectScope&lt;/code&gt; is &lt;strong&gt;advanced composables&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 typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;effectScope&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;watch&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;usePolling&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;interval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1000&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;scope&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;effectScope&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;data&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="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;timer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&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;data&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="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;interval&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="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;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;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="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onStop&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timer&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="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stop&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:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The composable owns its reactivity&lt;/li&gt;
&lt;li&gt;Consumers can explicitly stop it&lt;/li&gt;
&lt;li&gt;Side effects are cleaned up correctly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This pattern is invaluable for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;polling&lt;/li&gt;
&lt;li&gt;subscriptions&lt;/li&gt;
&lt;li&gt;event listeners&lt;/li&gt;
&lt;li&gt;external integrations&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;&lt;code&gt;effectScope&lt;/code&gt; gives Vue developers &lt;strong&gt;explicit control over reactivity lifecycles&lt;/strong&gt;.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;What &lt;code&gt;effectScope&lt;/code&gt; is and why it exists&lt;/li&gt;
&lt;li&gt;How it prevents runaway reactive effects&lt;/li&gt;
&lt;li&gt;How to use it in composables and services&lt;/li&gt;
&lt;li&gt;How to manage start/stop reactivity patterns&lt;/li&gt;
&lt;li&gt;When it’s worth the added complexity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Used thoughtfully, &lt;code&gt;effectScope&lt;/code&gt; helps keep Vue apps predictable, performant, and leak-free — especially as they grow in complexity.&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>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Config-driven Vue Interfaces with Dynamic Components</title>
      <dc:creator>Jakub Andrzejewski</dc:creator>
      <pubDate>Mon, 26 Jan 2026 07:37:42 +0000</pubDate>
      <link>https://dev.to/jacobandrewsky/config-driven-vue-interfaces-with-dynamic-components-28eo</link>
      <guid>https://dev.to/jacobandrewsky/config-driven-vue-interfaces-with-dynamic-components-28eo</guid>
      <description>&lt;p&gt;Modern Vue applications are no longer built from hardcoded layouts alone. As products scale, UIs increasingly need to adapt to configuration, CMS content, feature flags, experiments, or backend-driven schemas.&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;config-driven interfaces&lt;/strong&gt; and Vue’s dynamic components (&lt;code&gt;&amp;lt;component :is&amp;gt;&lt;/code&gt;) truly shine.&lt;/p&gt;

&lt;p&gt;Instead of baking layout decisions into templates, you let configuration decide &lt;em&gt;what&lt;/em&gt; gets rendered — and Vue handles &lt;em&gt;how&lt;/em&gt; it’s rendered.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;What config-driven UI means in Vue&lt;/li&gt;
&lt;li&gt;How &lt;code&gt;&amp;lt;component :is&amp;gt;&lt;/code&gt; enables truly dynamic rendering&lt;/li&gt;
&lt;li&gt;Patterns for CMS-driven and backend-driven interfaces&lt;/li&gt;
&lt;li&gt;Common pitfalls and how to avoid them&lt;/li&gt;
&lt;li&gt;When dynamic components are powerful — and when they’re not&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  🤔 What Are Config-driven Interfaces in Vue?
&lt;/h2&gt;

&lt;p&gt;A config-driven interface is one where &lt;strong&gt;structure, composition, or behavior is controlled by data&lt;/strong&gt;, not hardcoded templates.&lt;/p&gt;

&lt;p&gt;Instead of writing:&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;Hero&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;Features&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;Testimonials&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;You render UI based on configuration:&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="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hero&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&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;Hello&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="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;features&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;items&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;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;testimonials&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;quotes&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 approach is common in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CMS-driven websites&lt;/li&gt;
&lt;li&gt;Page builders&lt;/li&gt;
&lt;li&gt;Design systems&lt;/li&gt;
&lt;li&gt;A/B testing&lt;/li&gt;
&lt;li&gt;White-label products&lt;/li&gt;
&lt;li&gt;Dashboard builders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vue’s &lt;code&gt;&amp;lt;component :is&amp;gt;&lt;/code&gt; is the core primitive that makes this possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Dynamic Components with &lt;code&gt;&amp;lt;component :is&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;At its core, Vue allows you to dynamically choose which component to render:&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;component&lt;/span&gt; &lt;span class="na"&gt;:is=&lt;/span&gt;&lt;span class="s"&gt;"currentComponent"&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;Where &lt;code&gt;currentComponent&lt;/code&gt; can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A component reference&lt;/li&gt;
&lt;li&gt;A registered component name&lt;/li&gt;
&lt;li&gt;A function that resolves a component&lt;/li&gt;
&lt;li&gt;A value from configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes Vue ideal for config-driven rendering — &lt;em&gt;as long as you structure it correctly&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mapping Config to Components (Recommended Pattern)
&lt;/h3&gt;

&lt;p&gt;Avoid rendering arbitrary strings directly. Instead, define an explicit mapping:&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;HeroBlock&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/components/HeroBlock.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;FeaturesBlock&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/components/FeaturesBlock.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;componentMap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;hero&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HeroBlock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;features&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FeaturesBlock&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then render safely:&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;component&lt;/span&gt;
  &lt;span class="na"&gt;:is=&lt;/span&gt;&lt;span class="s"&gt;"componentMap[block.type]"&lt;/span&gt;
  &lt;span class="na"&gt;v-bind=&lt;/span&gt;&lt;span class="s"&gt;"block.props"&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;Strong boundaries&lt;/li&gt;
&lt;li&gt;Better type safety&lt;/li&gt;
&lt;li&gt;Easier refactoring&lt;/li&gt;
&lt;li&gt;Clear ownership of what can be rendered&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This pattern scales well with CMS-driven systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rendering Lists of Dynamic Blocks
&lt;/h3&gt;

&lt;p&gt;Most config-driven UIs involve iteration:&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;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;component&lt;/span&gt;
    &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"block in blocks"&lt;/span&gt;
    &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"block.id"&lt;/span&gt;
    &lt;span class="na"&gt;:is=&lt;/span&gt;&lt;span class="s"&gt;"componentMap[block.type]"&lt;/span&gt;
    &lt;span class="na"&gt;v-bind=&lt;/span&gt;&lt;span class="s"&gt;"block.props"&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;This allows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reordering content without code changes&lt;/li&gt;
&lt;li&gt;Enabling/disabling blocks via config&lt;/li&gt;
&lt;li&gt;Experimenting with layouts safely&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The UI becomes data-driven, not template-driven.&lt;/p&gt;

&lt;h3&gt;
  
  
  CMS-driven Interfaces in Practice
&lt;/h3&gt;

&lt;p&gt;A typical CMS payload might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"blocks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hero"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"props"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Welcome"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"features"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"props"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"items"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vue consumes this naturally using dynamic components — no conditionals, no giant &lt;code&gt;v-if&lt;/code&gt; chains.&lt;/p&gt;

&lt;p&gt;This is significantly more maintainable than:&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;Hero&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"type === 'hero'"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;Features&lt;/span&gt; &lt;span class="na"&gt;v-else-if=&lt;/span&gt;&lt;span class="s"&gt;"type === 'features'"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🟢 Common Pitfalls of Dynamic Components
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overusing Dynamic Rendering
&lt;/h3&gt;

&lt;p&gt;Not every UI should be config-driven.&lt;/p&gt;

&lt;p&gt;Avoid dynamic components when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The layout is static&lt;/li&gt;
&lt;li&gt;The structure rarely changes&lt;/li&gt;
&lt;li&gt;The complexity outweighs flexibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dynamic components introduce indirection — use them intentionally.&lt;/p&gt;

&lt;h3&gt;
  
  
  Leaking Logic into Configuration
&lt;/h3&gt;

&lt;p&gt;Configuration should describe &lt;strong&gt;what&lt;/strong&gt;, not &lt;strong&gt;how&lt;/strong&gt;.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hero"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"showIf"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user.isAdmin &amp;amp;&amp;amp; env === 'prod'"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep logic in code&lt;/li&gt;
&lt;li&gt;Keep config declarative&lt;/li&gt;
&lt;li&gt;Validate inputs before rendering&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Performance Considerations
&lt;/h3&gt;

&lt;p&gt;Dynamic components are still Vue components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They mount&lt;/li&gt;
&lt;li&gt;They update&lt;/li&gt;
&lt;li&gt;They re-render&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Optimize with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;markRaw&lt;/code&gt; for component maps&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;KeepAlive&lt;/code&gt; for frequently toggled blocks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;defineAsyncComponent&lt;/code&gt; for heavy CMS sections&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dynamic doesn’t mean free — measure when needed.&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;Config-driven interfaces are one of Vue’s quiet superpowers.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;What config-driven UI means in Vue&lt;/li&gt;
&lt;li&gt;How &lt;code&gt;&amp;lt;component :is&amp;gt;&lt;/code&gt; enables dynamic rendering&lt;/li&gt;
&lt;li&gt;Patterns for CMS-driven and backend-driven layouts&lt;/li&gt;
&lt;li&gt;Common pitfalls to avoid&lt;/li&gt;
&lt;li&gt;When dynamic components are worth the complexity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Used intentionally, dynamic components turn Vue into a flexible UI runtime — not just a templating system.&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>typescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>What to Unit Test in a Vue App (And What Not to Touch)</title>
      <dc:creator>Jakub Andrzejewski</dc:creator>
      <pubDate>Mon, 19 Jan 2026 07:51:38 +0000</pubDate>
      <link>https://dev.to/jacobandrewsky/what-to-unit-test-in-a-vue-app-and-what-not-to-touch-2mm3</link>
      <guid>https://dev.to/jacobandrewsky/what-to-unit-test-in-a-vue-app-and-what-not-to-touch-2mm3</guid>
      <description>&lt;p&gt;Unit testing is often treated as a checkbox on a project’s checklist. Teams either try to test &lt;em&gt;everything&lt;/em&gt; or avoid tests altogether because they feel slow, brittle, or hard to maintain.&lt;/p&gt;

&lt;p&gt;In Vue applications, the real challenge isn’t &lt;strong&gt;how&lt;/strong&gt; to write unit tests — it’s &lt;strong&gt;what is actually worth testing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Testing the wrong things leads to fragile tests, constant refactoring pain, and a false sense of confidence. Testing the right things creates a safety net that enables refactoring, faster development, and long-term maintainability.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;What unit tests are truly good at in Vue apps&lt;/li&gt;
&lt;li&gt;Which parts of your codebase deserve unit tests&lt;/li&gt;
&lt;li&gt;What &lt;em&gt;not&lt;/em&gt; to unit test (and why)&lt;/li&gt;
&lt;li&gt;How to define pragmatic testing boundaries&lt;/li&gt;
&lt;li&gt;How to keep tests valuable instead of burdensome&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  🤔 What Is the Purpose of Unit Tests in Vue?
&lt;/h2&gt;

&lt;p&gt;Unit tests are not meant to prove that Vue works. Vue itself is already heavily tested.&lt;/p&gt;

&lt;p&gt;The real purpose of unit tests in a Vue application is to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Protect &lt;strong&gt;business logic&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Validate &lt;strong&gt;critical decision paths&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;safe refactoring&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Catch regressions early&lt;/li&gt;
&lt;li&gt;Document expected behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A good unit test answers this question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“If this logic breaks, would it meaningfully affect the user or the business?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the answer is no, that code probably doesn’t need a unit test.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 What You &lt;em&gt;Should&lt;/em&gt; Unit Test in a Vue App
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Business Logic and Pure Functions
&lt;/h3&gt;

&lt;p&gt;Anything that contains &lt;strong&gt;decision-making logic&lt;/strong&gt; is a prime candidate for unit testing.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Price calculations&lt;/li&gt;
&lt;li&gt;Validation rules&lt;/li&gt;
&lt;li&gt;Permission checks&lt;/li&gt;
&lt;li&gt;Data transformations&lt;/li&gt;
&lt;li&gt;Formatting logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If it’s a pure function with inputs and outputs, it should almost always be tested.&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;calculateDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;price&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="nx"&gt;isPremium&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&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;isPremium&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This logic is easy to test, stable over time, and critical to correctness.&lt;/p&gt;

&lt;h3&gt;
  
  
  Composables with Logic (Not Just Glue)
&lt;/h3&gt;

&lt;p&gt;Composables that encapsulate logic — not just re-export state — are excellent testing targets.&lt;/p&gt;

&lt;p&gt;Good candidates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data fetching composables&lt;/li&gt;
&lt;li&gt;State machines&lt;/li&gt;
&lt;li&gt;Feature-flag logic&lt;/li&gt;
&lt;li&gt;Complex reactive flows
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useUserAccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;computed&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;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="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 a composable makes decisions, unit tests add real value.&lt;/p&gt;

&lt;h3&gt;
  
  
  Store Logic (Actions, Getters, Rules)
&lt;/h3&gt;

&lt;p&gt;Stores are not just state containers — they often encode business rules.&lt;/p&gt;

&lt;p&gt;You should test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Actions that modify state&lt;/li&gt;
&lt;li&gt;Getters with logic&lt;/li&gt;
&lt;li&gt;Error handling paths&lt;/li&gt;
&lt;li&gt;Side-effect orchestration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What you usually &lt;em&gt;don’t&lt;/em&gt; need to test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple state assignments&lt;/li&gt;
&lt;li&gt;Trivial getters that just return a value&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Test &lt;strong&gt;behavior&lt;/strong&gt;, not implementation details.&lt;/p&gt;

&lt;h3&gt;
  
  
  Edge Cases and Failure Paths
&lt;/h3&gt;

&lt;p&gt;Unit tests shine when validating:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Error states&lt;/li&gt;
&lt;li&gt;Empty data&lt;/li&gt;
&lt;li&gt;Invalid input&lt;/li&gt;
&lt;li&gt;Boundary conditions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the scenarios that often break silently in production and are hardest to reason about without tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 What You Should &lt;em&gt;Not&lt;/em&gt; Unit Test
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Vue Internals and Framework Behavior
&lt;/h3&gt;

&lt;p&gt;You don’t need to test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;That &lt;code&gt;v-if&lt;/code&gt; works&lt;/li&gt;
&lt;li&gt;That &lt;code&gt;v-model&lt;/code&gt; updates correctly&lt;/li&gt;
&lt;li&gt;That reactivity updates the DOM&lt;/li&gt;
&lt;li&gt;That lifecycle hooks are called&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vue already guarantees these behaviors. Testing them adds noise without value.&lt;/p&gt;

&lt;h3&gt;
  
  
  Markup and Styling Details
&lt;/h3&gt;

&lt;p&gt;Avoid unit tests that assert:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Exact HTML structure&lt;/li&gt;
&lt;li&gt;CSS classes unless they affect logic&lt;/li&gt;
&lt;li&gt;Pixel-perfect rendering&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These tests are brittle and break on harmless refactors.&lt;/p&gt;

&lt;p&gt;If appearance matters, use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visual testing&lt;/li&gt;
&lt;li&gt;Snapshot testing (sparingly)&lt;/li&gt;
&lt;li&gt;End-to-end tests&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Components That Are Pure Composition
&lt;/h3&gt;

&lt;p&gt;If a component:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only wires props to children&lt;/li&gt;
&lt;li&gt;Contains no logic&lt;/li&gt;
&lt;li&gt;Has no branching behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…it usually doesn’t need unit tests.&lt;/p&gt;

&lt;p&gt;Testing such components often duplicates what integration or E2E tests already cover better.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementation Details
&lt;/h3&gt;

&lt;p&gt;Avoid tests that depend on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Internal variable names&lt;/li&gt;
&lt;li&gt;Specific reactive structures&lt;/li&gt;
&lt;li&gt;Internal refs or watchers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good tests verify &lt;strong&gt;observable behavior&lt;/strong&gt;, not how that behavior is implemented.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 Defining Pragmatic Testing Boundaries
&lt;/h2&gt;

&lt;p&gt;A healthy Vue testing strategy looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unit tests protect &lt;strong&gt;logic&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Integration tests protect &lt;strong&gt;collaboration between components&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;E2E tests protect &lt;strong&gt;user flows&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ask yourself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Would this test fail if the behavior broke?&lt;/li&gt;
&lt;li&gt;Would this test survive a refactor?&lt;/li&gt;
&lt;li&gt;Does this test increase confidence or just coverage?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;High-value tests are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Focused&lt;/li&gt;
&lt;li&gt;Stable&lt;/li&gt;
&lt;li&gt;Intentional&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Low-value tests are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fragile&lt;/li&gt;
&lt;li&gt;Redundant&lt;/li&gt;
&lt;li&gt;Framework-dependent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not maximum coverage — it’s &lt;strong&gt;maximum confidence per test written&lt;/strong&gt;.&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;Unit testing in Vue is not about testing everything — it’s about testing &lt;strong&gt;the right things&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Well-chosen tests enable confidence and speed.&lt;br&gt;
Poorly chosen tests slow teams down and provide little value.&lt;/p&gt;

&lt;p&gt;Test intentionally — your future self will thank you.&lt;/p&gt;

&lt;p&gt;Take care!&lt;/p&gt;

&lt;p&gt;And happy coding as always 🖥️&lt;/p&gt;

</description>
      <category>testing</category>
      <category>vue</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Hidden Cost of Global Stores in Vue (and When They’re Still Worth It)</title>
      <dc:creator>Jakub Andrzejewski</dc:creator>
      <pubDate>Mon, 12 Jan 2026 06:53:33 +0000</pubDate>
      <link>https://dev.to/jacobandrewsky/the-hidden-cost-of-global-stores-in-vue-and-when-theyre-still-worth-it-4c2p</link>
      <guid>https://dev.to/jacobandrewsky/the-hidden-cost-of-global-stores-in-vue-and-when-theyre-still-worth-it-4c2p</guid>
      <description>&lt;p&gt;Global state management is often one of the first architectural decisions made in Vue applications. With tools like &lt;strong&gt;Pinia&lt;/strong&gt;, sharing state across components has never been easier.&lt;/p&gt;

&lt;p&gt;But while global stores feel convenient and powerful, they come with &lt;strong&gt;hidden costs&lt;/strong&gt; that often appear only as the application grows. Overusing global state can lead to tight coupling, unnecessary reactivity, performance regressions, and codebases that are harder to reason about.&lt;/p&gt;

&lt;p&gt;Global stores are not inherently bad — but they are frequently &lt;strong&gt;overused&lt;/strong&gt;.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Why global stores feel so attractive at first&lt;/li&gt;
&lt;li&gt;Common ways Pinia is misused in real-world Vue apps&lt;/li&gt;
&lt;li&gt;How dependency creep sneaks into your architecture&lt;/li&gt;
&lt;li&gt;Performance implications of global reactivity&lt;/li&gt;
&lt;li&gt;When global stores are still worth it&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  🤔 Why Global Stores Feel So Convenient
&lt;/h2&gt;

&lt;p&gt;Global stores solve a real problem: &lt;strong&gt;sharing state across distant parts of your application&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;With Pinia, you get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A centralized place for state&lt;/li&gt;
&lt;li&gt;Excellent DevTools integration&lt;/li&gt;
&lt;li&gt;Type safety&lt;/li&gt;
&lt;li&gt;Simple APIs for actions and getters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Typical &lt;em&gt;valid&lt;/em&gt; use cases include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication and user sessions&lt;/li&gt;
&lt;li&gt;Feature flags&lt;/li&gt;
&lt;li&gt;Global UI preferences (theme, locale)&lt;/li&gt;
&lt;li&gt;Shared cached API data&lt;/li&gt;
&lt;li&gt;Notifications and toasts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Problems start when a global store becomes the &lt;strong&gt;default place for all state&lt;/strong&gt;, instead of a deliberate architectural choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 The Hidden Costs of Overusing Global Stores
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pinia Misuse: When Everything Becomes Global
&lt;/h3&gt;

&lt;p&gt;A very common anti-pattern is placing &lt;strong&gt;local or temporary state&lt;/strong&gt; into Pinia just because it’s available.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modal open/close state&lt;/li&gt;
&lt;li&gt;Form input values&lt;/li&gt;
&lt;li&gt;Page-specific filters&lt;/li&gt;
&lt;li&gt;Temporary loading flags&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This leads to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bloated stores&lt;/li&gt;
&lt;li&gt;Unclear ownership of state&lt;/li&gt;
&lt;li&gt;More indirection than necessary&lt;/li&gt;
&lt;li&gt;Harder refactoring later on&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If a piece of state only belongs to a single component tree or route, keeping it &lt;strong&gt;local&lt;/strong&gt; is often simpler and healthier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dependency Creep and Tight Coupling
&lt;/h3&gt;

&lt;p&gt;Every time a component imports a store, it introduces an &lt;strong&gt;implicit dependency&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That component is now coupled to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The store’s structure&lt;/li&gt;
&lt;li&gt;Its internal logic&lt;/li&gt;
&lt;li&gt;Its side effects&lt;/li&gt;
&lt;li&gt;Its lifecycle&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Components become harder to reuse&lt;/li&gt;
&lt;li&gt;Tests require more mocking&lt;/li&gt;
&lt;li&gt;Changes in one store ripple across the app&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What starts as convenience slowly turns into &lt;strong&gt;architectural gravity&lt;/strong&gt;, pulling unrelated concerns into the same global layer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance Implications of Global Reactivity
&lt;/h3&gt;

&lt;p&gt;Global stores are reactive by default.&lt;/p&gt;

&lt;p&gt;That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Any reactive property can trigger updates&lt;/li&gt;
&lt;li&gt;Any component using the store participates in its dependency graph&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Issues arise when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large objects are stored globally&lt;/li&gt;
&lt;li&gt;Stores are deeply reactive without need&lt;/li&gt;
&lt;li&gt;Components subscribe to more state than they actually use&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Unnecessary re-renders&lt;/li&gt;
&lt;li&gt;Expensive computed recalculations&lt;/li&gt;
&lt;li&gt;Subtle performance regressions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While tools like &lt;code&gt;shallowRef&lt;/code&gt; or store splitting can help, the best optimization is often &lt;strong&gt;not globalizing state in the first place&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Losing Intent and Domain Boundaries
&lt;/h3&gt;

&lt;p&gt;When everything lives in a global store, &lt;strong&gt;nothing feels special anymore&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Stores should represent &lt;strong&gt;domain-level concepts&lt;/strong&gt;, not act as generic data buckets. Overusing them blurs the line between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UI state and business logic&lt;/li&gt;
&lt;li&gt;Temporary and persistent data&lt;/li&gt;
&lt;li&gt;Local concerns and application-wide concerns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Clear intent is usually the first thing lost in over-globalized architectures.&lt;/p&gt;

&lt;h2&gt;
  
  
  🟢 When Global Stores Are Still Worth It
&lt;/h2&gt;

&lt;p&gt;Despite all of this, global stores are absolutely the right tool in many cases.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;State must persist across routes&lt;/li&gt;
&lt;li&gt;Multiple distant components depend on the same data&lt;/li&gt;
&lt;li&gt;Centralized caching or synchronization is required&lt;/li&gt;
&lt;li&gt;Debugging via DevTools matters&lt;/li&gt;
&lt;li&gt;State truly represents an application-wide concern&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key is &lt;strong&gt;scope discipline&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep stores small and focused&lt;/li&gt;
&lt;li&gt;Avoid dumping UI-only state into them&lt;/li&gt;
&lt;li&gt;Expose minimal reactive surface&lt;/li&gt;
&lt;li&gt;Treat stores as part of your public API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Global stores are powerful — but power requires restraint.&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;Global stores are neither good nor bad by default — they’re &lt;strong&gt;contextual tools&lt;/strong&gt;. Used intentionally, they simplify your architecture. Used carelessly, they quietly erode it.&lt;/p&gt;

&lt;p&gt;Take care!&lt;/p&gt;

&lt;p&gt;And happy coding as always 🖥️&lt;/p&gt;

</description>
      <category>vue</category>
      <category>typescript</category>
      <category>performance</category>
      <category>webperf</category>
    </item>
  </channel>
</rss>
