<?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>Forem: Jakub Andrzejewski</title>
    <description>The latest articles on Forem by Jakub Andrzejewski (@jacobandrewsky).</description>
    <link>https://forem.com/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>Forem: Jakub Andrzejewski</title>
      <link>https://forem.com/jacobandrewsky</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jacobandrewsky"/>
    <language>en</language>
    <item>
      <title>Why Loaders Matter for Performance</title>
      <dc:creator>Jakub Andrzejewski</dc:creator>
      <pubDate>Mon, 11 May 2026 09:29:43 +0000</pubDate>
      <link>https://forem.com/jacobandrewsky/why-loaders-matter-for-performance-4b8a</link>
      <guid>https://forem.com/jacobandrewsky/why-loaders-matter-for-performance-4b8a</guid>
      <description>&lt;p&gt;When developers think about performance optimization, they usually focus on things like:&lt;/p&gt;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

&lt;span class="nf"&gt;onMounted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchUsers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"loading"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"skeleton-list"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;
      &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"n in 5"&lt;/span&gt;
      &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"n"&lt;/span&gt;
      &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"skeleton-card"&lt;/span&gt;
    &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;UserCard&lt;/span&gt;
    &lt;span class="na"&gt;v-else&lt;/span&gt;
    &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"user in users"&lt;/span&gt;
    &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"user.id"&lt;/span&gt;
    &lt;span class="na"&gt;:user=&lt;/span&gt;&lt;span class="s"&gt;"user"&lt;/span&gt;
  &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

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

&lt;/div&gt;



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

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

&lt;p&gt;Many apps still use simple spinners or text/icon loaders like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Loading...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

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

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

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

&lt;p&gt;&lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj7hlfz848ut2d9ly8i8q.png" alt="Vue School Link" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

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

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

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

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

&lt;p&gt;&lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9iledpqv69huancwg283.png" alt="Certificates.dev Link" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;nonce=&lt;/span&gt;&lt;span class="s"&gt;"abc123"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Secure inline script&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

&lt;/div&gt;



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

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

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

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

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

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

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

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

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



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

&lt;/div&gt;



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

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

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



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

&lt;/div&gt;



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

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

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

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

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

&lt;p&gt;Example (Node.js):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;crypto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;generateNonce&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randomBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;base64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Add it to response headers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nonce&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generateNonce&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Security-Policy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;`script-src 'nonce-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;nonce&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;'`&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Inject it into your HTML
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;nonce=&lt;/span&gt;&lt;span class="s"&gt;"{{nonce}}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__INITIAL_STATE__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

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

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

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

&lt;p&gt;It makes it much easier to work with CSP nonces in Nuxt. Let's take a look at the following configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineNuxtConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;modules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nuxt-security&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;security&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;contentSecurityPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;script-src&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;'self'&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;'nonce-{{nonce}}'&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What happens automatically:&lt;/p&gt;

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

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

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

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

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

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

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

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

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

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

&lt;p&gt;&lt;a href="https://vueschool.io/courses?friend=baroshem" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj7hlfz848ut2d9ly8i8q.png" alt="Vue School Link" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

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

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

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

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

&lt;p&gt;&lt;a href="https://certificates.dev/?friend=JAKUB" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9iledpqv69huancwg283.png" alt="Certificates.dev Link" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

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

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

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

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

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

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

</description>
      <category>security</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Flexible Code Without Losing Type Safety with TS Generics</title>
      <dc:creator>Jakub Andrzejewski</dc:creator>
      <pubDate>Mon, 30 Mar 2026 09:03:13 +0000</pubDate>
      <link>https://forem.com/jacobandrewsky/flexible-code-without-losing-type-safety-with-ts-generics-1pem</link>
      <guid>https://forem.com/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://forem.com/jacobandrewsky/when-you-should-use-vue-teleport-4k6i</link>
      <guid>https://forem.com/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://forem.com/jacobandrewsky/reusable-architecture-for-large-applications-with-nuxt-layers-1a46</link>
      <guid>https://forem.com/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://forem.com/jacobandrewsky/how-vue-protects-your-app-against-injections-cpa</link>
      <guid>https://forem.com/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://forem.com/jacobandrewsky/lesser-known-but-powerful-vue-features-1pp0</link>
      <guid>https://forem.com/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://forem.com/jacobandrewsky/accessibility-in-vue-quick-tips-for-building-inclusive-apps-2ne0</link>
      <guid>https://forem.com/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://forem.com/jacobandrewsky/business-advantages-of-using-nuxt-51j2</link>
      <guid>https://forem.com/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://forem.com/jacobandrewsky/responsive-images-for-better-web-performance-55hn</link>
      <guid>https://forem.com/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://forem.com/jacobandrewsky/using-effectscope-to-control-vue-reactivity-lifecycles-2mml</link>
      <guid>https://forem.com/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://forem.com/jacobandrewsky/config-driven-vue-interfaces-with-dynamic-components-28eo</link>
      <guid>https://forem.com/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>
  </channel>
</rss>
