<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mohsen Vaziri</title>
    <description>The latest articles on DEV Community by Mohsen Vaziri (@mohsen_vaziri).</description>
    <link>https://dev.to/mohsen_vaziri</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%2F865286%2Ff12b0248-b75a-4bc7-b1f9-2213d4cb33c0.jpeg</url>
      <title>DEV Community: Mohsen Vaziri</title>
      <link>https://dev.to/mohsen_vaziri</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mohsen_vaziri"/>
    <language>en</language>
    <item>
      <title>Updating My Mac Window Shortcuts Strategy for Optimal Workflow</title>
      <dc:creator>Mohsen Vaziri</dc:creator>
      <pubDate>Wed, 01 May 2024 12:55:22 +0000</pubDate>
      <link>https://dev.to/mohsen_vaziri/updating-my-mac-window-shortcuts-strategy-for-optimal-workflow-ke9</link>
      <guid>https://dev.to/mohsen_vaziri/updating-my-mac-window-shortcuts-strategy-for-optimal-workflow-ke9</guid>
      <description>&lt;p&gt;I previously wrote about &lt;a href="https://dev.to/mohsen_vaziri/mac-keyboard-shortcuts-for-arranging-app-windows-2l1l"&gt;using keyboard shortcuts to manage windows in macOS&lt;/a&gt;. With recent macOS updates and my discovery of the &lt;a href="https://rectangleapp.com/"&gt;Rectangle&lt;/a&gt; app, it’s time for a strategy refinement.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Challenge of macOS Shortcut Reliability
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4s1ycgxlgxotf50v5lll.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4s1ycgxlgxotf50v5lll.png" alt="Image description" width="800" height="639"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While I found the ⌃⌥⌘ keyboard combinations effective in the past, comments from others indicated that they’ve become less reliable on newer macOS versions. This inconsistency can disrupt productivity. After some investigation, switching to ⌃⌥⇧ shortcuts has restored the expected smooth functionality.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introducing &lt;strong&gt;Rectangle: Efficiency and Customization&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6uzhljhbhlwk0rztobtr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6uzhljhbhlwk0rztobtr.png" alt="Image description" width="792" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://rectangleapp.com/"&gt;Rectangle&lt;/a&gt; is a fantastic free app that streamlines window resizing and arrangement through keyboard shortcuts. It offers a high degree of customization, but its default shortcuts are intuitive and work perfectly for me without any adjustments.&lt;/p&gt;

&lt;p&gt;While the macOS native window animations are slightly smoother, Rectangle’s superior reliability makes it a clear winner in a professional workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Seamless Setup, Enhanced Productivity
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbr41erlv93tti91yb38v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbr41erlv93tti91yb38v.png" alt="Image description" width="800" height="704"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rectangle’s installation is incredibly straightforward. Its immediate out-of-the-box functionality was a pleasant surprise. For anyone seeking to reduce the friction of window management on their Mac, &lt;a href="https://rectangleapp.com/"&gt;Rectangle&lt;/a&gt; is a solution I wholeheartedly recommend.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Power of Optimized Window Management
&lt;/h3&gt;

&lt;p&gt;Don’t underestimate the impact streamlined window organization can have on your workflow. The ability to quickly position and resize windows minimizes distractions and helps maintain focus on the task at hand.&lt;/p&gt;

&lt;h3&gt;
  
  
  Share Your Productivity Tips!
&lt;/h3&gt;

&lt;p&gt;Do you have other Mac productivity tips or tricks involving window management? Please share them below!&lt;/p&gt;

</description>
      <category>macos</category>
      <category>productivity</category>
      <category>rectangle</category>
      <category>windowmanagement</category>
    </item>
    <item>
      <title>Developer experience with nuxt 3 — Vue Amsterdam Conference 2022 — Tenth Talk</title>
      <dc:creator>Mohsen Vaziri</dc:creator>
      <pubDate>Tue, 22 Aug 2023 09:25:48 +0000</pubDate>
      <link>https://dev.to/mohsen_vaziri/developer-experience-with-nuxt-3-vue-amsterdam-conference-2022-tenth-talk-2a98</link>
      <guid>https://dev.to/mohsen_vaziri/developer-experience-with-nuxt-3-vue-amsterdam-conference-2022-tenth-talk-2a98</guid>
      <description>&lt;p&gt;&lt;a href="https://twitter.com/danielcroe"&gt;Daniel Roe&lt;/a&gt; - Core team member at Nuxt.js&lt;/p&gt;

&lt;p&gt;Hello, dear readers! I'm back with another insightful piece, this time focusing on the developer experience in Nuxt 3, as presented by Daniel Roe, a core team member of Nuxt. Daniel also did a live coding session which covers all the following topics in action. If you want to watch that, or the entire talk, you can find it on &lt;a href="https://www.youtube.com/watch?v=Xv8EtQwPs8Q&amp;amp;list=PL02pdjMT4gWwpRIKWxWwuQFupMY6spv-i&amp;amp;index=21"&gt;YouTube&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Intro
&lt;/h1&gt;

&lt;p&gt;Daniel Roe, with his background as a CTO of a SaaS startup and experience with a creative agency, emphasizes the significance of the developer experience. Having been a user of Nuxt, he understands the challenges developers face and believes that enhancing this experience is beneficial for both developers and companies.&lt;br&gt;
He believes that improving the developer experience is beneficial for everyone. It aids the developer in implementing their ideas faster and more efficiently, and it's also advantageous for companies as it leads to quicker and better results.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The vision is to be as minimal as possible, as lightweight as possible, and to reduce context switching&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;
  
  
  Typescript in Nuxt 3
&lt;/h1&gt;

&lt;p&gt;One of the significant changes in Nuxt 3 is the full integration of Typescript. This doesn't mean developers have to use Typescript, but it offers full control of the IDE, generating a &lt;code&gt;tsconfig.json&lt;/code&gt; file that sets paths and provides type hinting.&lt;/p&gt;

&lt;p&gt;Nuxt 3 takes full control of the developer's IDE. This is achieved by generating a &lt;code&gt;tsconfig.json&lt;/code&gt; file. This configuration file is the heart of any Typescript project, and by controlling it, Nuxt 3 can introduce a plethora of features. For instance, it sets paths for every alias defined in the Nuxt project, whether it's by Nuxt itself, some other module, or an additional library. This ensures that developers have a smooth experience with imports, type hinting, and other IDE features.&lt;/p&gt;
&lt;h1&gt;
  
  
  Documentation at Fingertips
&lt;/h1&gt;

&lt;p&gt;One of the significant advantages of using Typescript is the ability to provide inline documentation. Nuxt 3 leverages this by moving as much documentation as possible into the editor. This includes detailed descriptions of functions, their parameters, expected return types, code examples, and even links to further reading. This approach ensures that developers have immediate access to crucial information without having to switch contexts or browse external documentation.&lt;/p&gt;
&lt;h1&gt;
  
  
  Reducing Boilerplate in Nuxt 3
&lt;/h1&gt;

&lt;p&gt;One of the standout features of Nuxt 3 is its commitment to reducing boilerplate code, making the developer experience smoother and more intuitive. Here's a deeper dive into how Nuxt 3 achieves this:&lt;/p&gt;
&lt;h2&gt;
  
  
  Auto-imported Functions
&lt;/h2&gt;

&lt;p&gt;In Nuxt 3, developers no longer need to manually import commonly used functions. For instance, when using Vue 3, functions like &lt;code&gt;ref&lt;/code&gt;, &lt;code&gt;onMounted&lt;/code&gt;, and &lt;code&gt;reactive&lt;/code&gt; are frequently utilized. In Nuxt 3, these are auto-imported, eliminating the need for repetitive import statements. This not only reduces the noise in the code but also streamlines the coding process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
const props = defineProps (&lt;span class="si"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt;)
const greeting = computed(() =&amp;gt; 'Hi $&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;)
&amp;lt;/script&amp;gt;

&amp;lt;template&amp;gt;
    {{ greeting }}
&amp;lt;/template&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Minimal Initial Setup
&lt;/h2&gt;

&lt;p&gt;A fresh Nuxt 3 project comes with a minimal set of files. This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;app.vue&lt;/code&gt;: The starting point of the application.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nuxt.config&lt;/code&gt;: While this configuration file is present, it's initially empty and can often remain so, thanks to Nuxt's convention-over-configuration approach.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;package.json&lt;/code&gt;: Contains just one dependency - Nuxt.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tsconfig.json&lt;/code&gt;: A configuration file generated by Nuxt to take full control of the IDE, enabling features like path aliases and type hinting.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Smart Data Fetching
&lt;/h2&gt;

&lt;p&gt;Nuxt 3 introduces an isomorphic fetch function, &lt;code&gt;$fetch&lt;/code&gt;, which smartly handles response headers. This function can determine whether the response is text, JSON, an array buffer, or another type, and processes it accordingly. This eliminates the need for developers to manually parse responses, making data fetching more intuitive.&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="nx"&gt;defineEventHandler&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// /api/user?id-1 =&amp;gt; 1&lt;/span&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;$fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="na"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;//api.dev/users/${id}*)&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;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Server Functions
&lt;/h2&gt;

&lt;p&gt;In Nuxt 3, server functions can directly return objects, such as JSON. This means developers no longer need to set headers or stringify responses manually. This approach not only simplifies server-side code but also powers type inference, providing developers with accurate type hints when fetching from these endpoints.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;I hope you enjoyed this part and that it was as valuable to you as it was to me.&lt;br&gt;
Over the next few days, I’ll share the rest of the talks with you. Stay tuned…&lt;/p&gt;

&lt;p&gt;Shout out to my friend &lt;a href="https://twitter.com/shazokhof"&gt;Shahrokh&lt;/a&gt;, who made me excited to write the next part.&lt;/p&gt;

</description>
      <category>nuxt</category>
      <category>vue</category>
      <category>typescript</category>
      <category>vueamsterdam</category>
    </item>
    <item>
      <title>Full Stack Development With Nuxt 3 and Nitro — Vue Amsterdam Conference 2022 — Ninth Talk</title>
      <dc:creator>Mohsen Vaziri</dc:creator>
      <pubDate>Thu, 02 Feb 2023 22:06:24 +0000</pubDate>
      <link>https://dev.to/mohsen_vaziri/full-stack-development-with-nuxt-3-and-nitro-vue-amsterdam-conference-2022-ninth-talk-2djk</link>
      <guid>https://dev.to/mohsen_vaziri/full-stack-development-with-nuxt-3-and-nitro-vue-amsterdam-conference-2022-ninth-talk-2djk</guid>
      <description>&lt;p&gt;&lt;a href="https://twitter.com/_pi0_" rel="noopener noreferrer"&gt;&lt;strong&gt;Pooya Parsa&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;- Head of Framework at Nuxt.js&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Welcome! It's been a while since my last article, but I'm excited to return with the ninth part of my series on the Vuejs Amsterdam conference 2022. In this part, we will delve into the exciting world of full-stack development using Nuxt 3 and Nitro. You can watch the talk on &lt;a href="https://www.youtube.com/watch?v=eYOifvwsFG0&amp;amp;list=PL02pdjMT4gWxL8oGwiZ-ZhJ9ChnRsHSTc&amp;amp;index=17" rel="noopener noreferrer"&gt;JSWorld's YouTube channel&lt;/a&gt; as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;I remember last time [two years ago] I was on the stage here, we had a really big dream of Nuxt to extending from an SSR application to something that we can use everywhere and beyond it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To make this happen, they had to rewrite everything, which took more than 2 years. But before talking about Nuxt 3, Pooya talks about Nuxt 2, its strengths and limitations, and the reason behind starting with a project called &lt;em&gt;Nitro&lt;/em&gt; which is a part of Nuxt 3.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nuxt 2 Server Middleware
&lt;/h2&gt;

&lt;p&gt;Nuxt 2 is a framework mainly focused on Server Side Rendering due to its benefits. Now that we already have a server, why not take this opportunity to extend it and add our APIs? Here's how we do it in Nuxt 2 using Server Middleware:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// server-middleware/test.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&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="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;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To register this middleware:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// nuxt.config&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;serverMiddleware&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;/api/test&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;./server-middleware/test&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 if we call &lt;code&gt;http://localhost:3000/api/test&lt;/code&gt; we get the response:&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="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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;world&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;As you can see it's plain simple node.js middleware, supports typescript and it had a basic router system using prefixes. But it has some limitations. For example, lack of dynamic path support in the route, no alias and transform support, and files are not bundled and are loaded in the runtime and we have to deploy the entire source code to the production to make it work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Server Middleware HMR in Nuxt 2
&lt;/h2&gt;

&lt;p&gt;Nuxt 2 is using an older version of express.js called connect which is lighter. On top of that, it has an isolation for SSR, so every code that you write like plugins and components is bundled through webpack or vite and is loaded in this isolated environment with HMR support.&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2F2zcej1s9n9j3wmofzj36.png" class="article-body-image-wrapper"&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%2F2zcej1s9n9j3wmofzj36.png" width="800" height="554"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It supports TypeScript with &lt;code&gt;unjs/jiti&lt;/code&gt; and is fast at cache invalidation, but the server and node_modules were not isolated and the entire node_modules folder had to be deployed. Runtimes varied between production and development too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nuxt 2 with Express
&lt;/h2&gt;

&lt;p&gt;We Could use nuxt 2 not only as a standalone framework but also as a middleware for an existing application. That gives us lots of flexibility but it comes with its own downsides.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It needs &lt;code&gt;node_modules&lt;/code&gt; entirely to deploy to production, which limits us for some environments like serverless or makes it impossible in some other environments like edge rendering which are workers - Because we can not deploy node application with node_modules to edge.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It has a bad Developer Experience without server HMR and you have to reload the server every time you change something in the code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It has unpredictable behaviors because it was designed to be used in specific ways.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  API Calls in Nuxt 2
&lt;/h2&gt;

&lt;p&gt;When you try to fetch something from the server side in your nuxt 2 application some strange things happen.&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2F9vnklp21194vtyunr6mh.png" class="article-body-image-wrapper"&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%2F9vnklp21194vtyunr6mh.png" width="764" height="607"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example, we are loading a product page in a webshop. In order to Server side render this endpoint we have to fetch the product's data, from the same API that is living on the same server. Maybe the only upside is that we have a shared server and there is no need to set up another server for the APIs.&lt;/p&gt;

&lt;p&gt;But there are more downsides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The base URL has to be manually configured and is a nightmare.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SSR API calls roundtrip in real-world apps to bring huge latency, making nuxt 2 apps slower than expected.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There is no built-in HTTP client.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Static Generation in nuxt 2
&lt;/h2&gt;

&lt;p&gt;Nuxt 2 allows you to generate a static application that is not dependent on server files so you can deploy it everywhere.&lt;/p&gt;

&lt;p&gt;When you run the &lt;code&gt;nuxt generate&lt;/code&gt; command to generate the static app, nuxt will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Build and bundle the whole app.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Load the bundle using a programmatic API to emulate the server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using this server and an internal API, nuxt tries to render each page and write them to the file system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;dist/&lt;/code&gt; is ready to use!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is simple and fast in implementation, has full static support, and there is also a shared generation cache feature between pages. But there are also some issues with that.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You can either target server or static. There are many cases in that you can choose between one of them, but there are some use cases that need to have best of the both worlds.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generation on demand is not possible and we have to pre-generate all of the pages every time on deployment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The direct rendering method used in nuxt 2 makes also the internal code more complicated which was making some improvements harder.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Nuxt 2 server deployment
&lt;/h2&gt;

&lt;p&gt;Deploying a nuxt 2 SSR App to production seems to be easy, but it's not efficient.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The whole repo must be deployed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Only Node.js hosting is supported.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extra unused node_modules.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Nitro
&lt;/h2&gt;

&lt;p&gt;During an internal team meeting about cloud flare workers at the time that the team was actively working on nuxt 2, Pooya realized that nuxt was limited in some important aspects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nitro.unjs.io/" rel="noopener noreferrer"&gt;Nitro&lt;/a&gt; project started as an experiment on top of nuxt 2 thanks to the modularity and the hooks that it provides. They managed to create a proof of concept to deploy nuxt 2 apps to the edge and remove most of those limitations.&lt;/p&gt;

&lt;p&gt;Nitro's goal according to Pooya is to deploy any JavaScript server anywhere you want, including edge, and he even claims that we can even run a package like express in the browser service worker using nitro.&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Fbf2ii98xxke69lc7fais.png" class="article-body-image-wrapper"&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%2Fbf2ii98xxke69lc7fais.png" width="800" height="671"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Server Routes in Nuxt 3
&lt;/h2&gt;

&lt;p&gt;To create a server route in Nuxt 3:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// server/api/hello.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default &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="na"&gt;nuxt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;is easy!&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// http://localhost:3000/api/hello&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nuxt&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;is easy!&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;Also, it has a first-class integration with the runtime application and works out of the box:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app.vue&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&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;useFetch&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/hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some of the benefits are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Minimalist API using &lt;code&gt;unjs/h3&lt;/code&gt; created by themselves, which is one of the fastest libraries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Built using TypeScript&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fast router using &lt;code&gt;unjs/radix3&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Integrated HTTP client (fetch and $fetch)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It's platform agnostic, meaning you can write the code and expect it to run on every platform.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lots of new built-in helpers&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  API Calls in Nuxt 3
&lt;/h2&gt;

&lt;p&gt;In opposite to Nuxt 2 where we had to make a round-trip, here we have direct API calls with 0 latency, baseURL is automatically handled, and also fetch is improved with &lt;code&gt;unjs/ohmyfetch&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Fklccba9k21ym9i6xv4h6.png" class="article-body-image-wrapper"&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%2Fklccba9k21ym9i6xv4h6.png" width="799" height="622"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Server HMR in Nuxt 3
&lt;/h2&gt;

&lt;p&gt;In Nuxt 3, server Entry is also integrated into the same bundle compared to nuxt 2. Also, the entire server is isolated, and it's much faster in HMR. The new gotcha is that runtime isolation is more complex.&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Fq6xcymlbql2hep8pcd6f.png" class="article-body-image-wrapper"&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%2Fq6xcymlbql2hep8pcd6f.png" width="800" height="555"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pluggable KV Storage
&lt;/h2&gt;

&lt;p&gt;Nitro comes with something called Pluggable Key-Value storage, which is powered by &lt;code&gt;unjs/unstorage&lt;/code&gt; built by the nuxt team.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/unjs/unstorage" rel="noopener noreferrer"&gt;unstorage&lt;/a&gt; solution is a unified and powerful Key-Value (KV) interface that allows combining drivers that are either built-in or can be implemented via a super simple interface and adding conventional features like mounting, watching, and working with metadata.&lt;/p&gt;

&lt;p&gt;It works in all environments (Browser, NodeJS, and Workers) and offers multiple built-in drivers (Memory, FS, LocalStorage, HTTP, Redis).&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2F94pzu3fjfwls48r9fbyu.png" class="article-body-image-wrapper"&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%2F94pzu3fjfwls48r9fbyu.png" width="750" height="537"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here you can see a snippet of an example of a simple note-taking app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// server/api/notes/index.post.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineEventHandler &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="nx"&gt;event&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;id&lt;/span&gt; &lt;span class="o"&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;useStorage&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getKeys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data: notes&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;Iength&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&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;useBody&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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;note&lt;/span&gt; &lt;span class="o"&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;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`data:notes:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;note&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;id&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// server/api/notes/[id].ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineEventHandler &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="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt;›&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;note&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;useStorage&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`data:notes:$(id)`&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nf"&gt;createError &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;statusMessage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Note not found!&lt;/span&gt;&lt;span class="dl"&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;note&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Nuxt 3 server deployment
&lt;/h2&gt;

&lt;p&gt;Deployment in Nuxt 3 is easier. You will fire &lt;code&gt;nuxt build&lt;/code&gt; and the result will be a portable &lt;code&gt;.output&lt;/code&gt;directory with required public files and a tree-shaken version of the &lt;code&gt;node_modules&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Static generation in Nuxt 3
&lt;/h2&gt;

&lt;p&gt;Here are the steps from running the command to receiving the output:&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2F72qz0gd6qa3w16pfegp4.png" class="article-body-image-wrapper"&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%2F72qz0gd6qa3w16pfegp4.png" width="693" height="608"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In opposite to nuxt 2, here we have a hybrid solution to have the best of both worlds (server and static), and also generation on demand is now also possible.&lt;/p&gt;




&lt;h2&gt;
  
  
  End of the ninth Talk
&lt;/h2&gt;

&lt;p&gt;I hope you enjoyed this part and that it was as valuable to you as it was to me. Over the next few days, I’ll share the rest of the talks with you. Stay tuned…&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>discuss</category>
      <category>async</category>
    </item>
    <item>
      <title>The Nuxt Web — Vue Amsterdam Conference 2022 Summary series — Eighth Talk</title>
      <dc:creator>Mohsen Vaziri</dc:creator>
      <pubDate>Sun, 07 Aug 2022 19:15:03 +0000</pubDate>
      <link>https://dev.to/mohsen_vaziri/the-nuxt-web-vue-amsterdam-conference-2022-summary-series-eighth-talk-lg3</link>
      <guid>https://dev.to/mohsen_vaziri/the-nuxt-web-vue-amsterdam-conference-2022-summary-series-eighth-talk-lg3</guid>
      <description>&lt;p&gt;Welcome! Happy to see you in the seventh part of my Vuejs Amsterdam Conference 2022 summary series, in which I share a summary of all the talks with you.&lt;/p&gt;

&lt;p&gt;You can read my JSWorld Conference 2022 Summary series (in four parts) &lt;a href="https://dev.to/mohsen_vaziri/series/18427"&gt;here&lt;/a&gt;, where I summarized all the first day’s talks. You can also find the previous Talks of the Vue Amsterdam conference 2022 in my blog.&lt;/p&gt;

&lt;h2&gt;
  
  
  (Recurring) Introduction
&lt;/h2&gt;

&lt;p&gt;After two and a half years, JSWorld and Vue Amsterdam Conference were back in Theater Amsterdam between 1 and 3 June, and I had the chance to attend this conference for the first time. I learned many things, met many wonderful people, spoke with great developers, and had a great time. On the first day the JSWorld Conference was held, and on the second and third days, the Vue Amsterdam.&lt;/p&gt;

&lt;p&gt;The conference was full of information with great speakers, each of whom taught me something valuable. They all wanted to share their knowledge and information with other developers. So I thought it would be great if I could continue to share it and help others use it.&lt;/p&gt;

&lt;p&gt;At first, I tried to share a few notes or slides, but I felt it was not good enough, at least not as good as what the speaker shared with me. So I decided to re-watch each speech, dive deeper into them, search, take notes and combine them with their slides and even their exact words in their speech and then share it with you so that what I share with you is at least at the same level as what I learned from them.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;A very important point&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Everything you read during these few articles is the result of the effort and time of the speaker itself,&lt;/strong&gt; and I have only tried to learn them so that I can turn them into these articles. Even &lt;strong&gt;many of the sentences written in these articles are exactly what they said or what they wrote in Slides.&lt;/strong&gt; This means if you learn something new, it is because of their efforts.&lt;/p&gt;

&lt;p&gt;Last but not least, I may not dig into every technical detail or live codings in some of the speeches. But if you are interested and need more information, let me know and I’ll try to write a more detailed article separately. Also, don’t forget to check out their Twitter/Linkedin.&lt;/p&gt;

&lt;p&gt;Here you can find the program of the conference:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.jsworldconference.com/program"&gt;JSWORLD Conference&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Nuxt Web
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://twitter.com/atinux"&gt;Sebastien Chopin&lt;/a&gt; - Co-Founder of Nuxt&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Our mission at &lt;a href="https://twitter.com/nuxtlabs"&gt;@nuxtlabs&lt;/a&gt; is to provide the best Developer Experience to deliver the best User Experience for your end users. We are doing this with Nuxt for six Years now.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nuxt is a web framework for creating &lt;strong&gt;any kind&lt;/strong&gt; of Vue app. That means you can do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Servier Side Rendering (SSR)&lt;/li&gt;
&lt;li&gt;Static Site Generation (SSG)&lt;/li&gt;
&lt;li&gt;Client Side Rendering (CSR)&lt;/li&gt;
&lt;li&gt;Edge Side Rendering (ESR) thanks to Nuxt 3&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since the beginning of Nuxt in October 2016 it has been downloaded about 46M times on npm, has 300k live websites, and 18k GitHub contributors. &lt;/p&gt;

&lt;h3&gt;
  
  
  A comparison between Nuxt 2 and Nuxt 3
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Web server:&lt;/strong&gt; For the development and production web server, Nuxt 2 uses to connect, which is the core of Express.js, but for Nuxt 3 they created h3 and it works in any kind of JavaScript environment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bundler:&lt;/strong&gt; Webpack 4 is used in Nuxt 2, and for Nuxt 3 they started with Webpack 5, but after the release of Vite, it is officially supported as the default Bundler.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI framework:&lt;/strong&gt; Vue 2 in Nuxt 2 and Vue 3 in Nuxt 3&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Routing library:&lt;/strong&gt; Vue Router 3 in Nuxt 2 and Vue Router 4 in Nuxt 3, which will not be included if no &lt;code&gt;pages/&lt;/code&gt; directory is found.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Meta management:&lt;/strong&gt; Since Nuxt does SSR, it’s important to be able to manage meta tags. Vue Meta is used in Nuxt 2 and VueUse Head in Nuxt 3.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server(less) packager:&lt;/strong&gt; This is introduced in Nuxt 3, which compacts the nuxt application for production by removing the node_modules so your Nuxt application will be about 1 megabyte.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a hello world bundle size comparison between Nuxt 2 and Nuxt 3:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LCZku7bn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3g0dhw0ayq4nlkhqpceu.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LCZku7bn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3g0dhw0ayq4nlkhqpceu.jpeg" alt="Image description" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the reasons Nuxt 3 is so much smaller is that it's tree shakable, like Vue 3. So if you don't use a feature, it will not be included in the bundle.&lt;/p&gt;

&lt;p&gt;The Next equivalent bundle size is around 80kB.&lt;/p&gt;

&lt;p&gt;In that Nuxt 3 JS bundle, 25.3kB are from Vue, and the 8.7kB left includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;App entry with hydration&lt;/li&gt;
&lt;li&gt;Root component with &lt;code&gt;&amp;lt;Suspense&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Universal and lightweight router: &lt;code&gt;useRouter()&lt;/code&gt;, &lt;code&gt;middleware&lt;/code&gt; and &lt;code&gt;&amp;lt;NuxtLink&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Head composable &amp;amp; components: &lt;code&gt;useHead()&lt;/code&gt;, &lt;code&gt;&amp;lt;Title&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;Meta&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;Script&amp;gt;&lt;/code&gt;, …&lt;/li&gt;
&lt;li&gt;Universal data fetching: &lt;code&gt;$fetch()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Default error pages: &lt;code&gt;404&lt;/code&gt; and &lt;code&gt;500&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Plugins&lt;/code&gt; and &lt;code&gt;runtimeConfig&lt;/code&gt; logic&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;useNuxtApp()&lt;/code&gt; composable and hooks: &lt;code&gt;app:created&lt;/code&gt;, &lt;code&gt;app:mounted&lt;/code&gt;, &lt;code&gt;page:start&lt;/code&gt;, …&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Edge Side Rendering
&lt;/h3&gt;

&lt;p&gt;Edge Side Rendering - also named JavaScript containers by Ryan Dahl - is the capability of running JavaScript at the CDN nodes somewhere around the world close to the end user.&lt;/p&gt;

&lt;p&gt;The advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Runs milliseconds from end users&lt;/li&gt;
&lt;li&gt;0ms cold starts&lt;/li&gt;
&lt;li&gt;No servers to maintain&lt;/li&gt;
&lt;li&gt;Automatic scaling&lt;/li&gt;
&lt;li&gt;Affordable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some of the Edge computing providers right now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CloudFlare Workers&lt;/li&gt;
&lt;li&gt;Vercel Edge&lt;/li&gt;
&lt;li&gt;Netlify Edge&lt;/li&gt;
&lt;li&gt;Deno Deploy&lt;/li&gt;
&lt;li&gt;Lambda Edge&lt;/li&gt;
&lt;li&gt;StackPath&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Content V2
&lt;/h3&gt;

&lt;p&gt;Nuxt Content is a &lt;strong&gt;&lt;a href="https://v3.nuxtjs.org/guide/features/modules"&gt;Nuxt module&lt;/a&gt;&lt;/strong&gt; that reads Markdown, YAML, CSV, and JSON files in the &lt;code&gt;content/&lt;/code&gt; directory to create a powerful data layer for your application and &lt;a href="https://content.nuxtjs.org/blog/announcing-v2/"&gt;Content V2&lt;/a&gt; is out now with more features.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nuxt 2.X
&lt;/h3&gt;

&lt;p&gt;What’s coming for Nuxt 2.X:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vue 2.7&lt;/li&gt;
&lt;li&gt;Nuxt Bridge (beta)

&lt;ul&gt;
&lt;li&gt;Vite&lt;/li&gt;
&lt;li&gt;Nitro&lt;/li&gt;
&lt;li&gt;Composition API &amp;amp; Script setup&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;nuxi CLI&lt;/li&gt;
&lt;li&gt;PostCSS 8&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Nuxt 3.0
&lt;/h3&gt;

&lt;p&gt;What's coming for Nuxt 3.0:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nuxt Image&lt;/li&gt;
&lt;li&gt;Hybrid rendering: Server + SWR + Pre-rendering&lt;/li&gt;
&lt;li&gt;Full static generation&lt;/li&gt;
&lt;li&gt;Preview mode&lt;/li&gt;
&lt;li&gt;Server sessions and Auth&lt;/li&gt;
&lt;li&gt;Service Workers (PWA)&lt;/li&gt;
&lt;li&gt;SEO helpers and i18n support&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  End of the Eighth Talk
&lt;/h2&gt;

&lt;p&gt;I hope you enjoyed this part and it can be as valuable to you as it was to me.&lt;/p&gt;

&lt;p&gt;Over the next few days, I’ll share the rest of the talks with you. Stay tuned…&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>vue</category>
      <category>nuxt</category>
      <category>vueamsterdam</category>
    </item>
    <item>
      <title>Animating with Vue — Vue Amsterdam Conference 2022 Summary series — Seventh Talk</title>
      <dc:creator>Mohsen Vaziri</dc:creator>
      <pubDate>Tue, 19 Jul 2022 20:21:00 +0000</pubDate>
      <link>https://dev.to/mohsen_vaziri/animating-with-vue-vue-amsterdam-conference-2022-summary-series-seventh-talk-42c6</link>
      <guid>https://dev.to/mohsen_vaziri/animating-with-vue-vue-amsterdam-conference-2022-summary-series-seventh-talk-42c6</guid>
      <description>&lt;p&gt;Welcome! Happy to see you in the seventh part of my Vuejs Amsterdam Conference 2022 summary series, in which I share a summary of all the talks with you.&lt;/p&gt;

&lt;p&gt;You can read my JSWorld Conference 2022 Summary series (in four parts) &lt;a href="https://dev.to/mohsen_vaziri/series/18427"&gt;here&lt;/a&gt;, where I summarized all the first day’s talks. You can also find the previous Talks of the Vue Amsterdam conference 2022 in my blog.&lt;/p&gt;

&lt;h2&gt;
  
  
  (Recurring) Introduction
&lt;/h2&gt;

&lt;p&gt;After two and a half years, JSWorld and Vue Amsterdam Conference were back in Theater Amsterdam between 1 and 3 June, and I had the chance to attend this conference for the first time. I learned many things, met many wonderful people, spoke with great developers, and had a great time. On the first day the JSWorld Conference was held, and on the second and third days, the Vue Amsterdam.&lt;/p&gt;

&lt;p&gt;The conference was full of information with great speakers, each of whom taught me something valuable. They all wanted to share their knowledge and information with other developers. So I thought it would be great if I could continue to share it and help others use it.&lt;/p&gt;

&lt;p&gt;At first, I tried to share a few notes or slides, but I felt it was not good enough, at least not as good as what the speaker shared with me. So I decided to re-watch each speech, dive deeper into them, search, take notes and combine them with their slides and even their exact words in their speech and then share it with you so that what I share with you is at least at the same level as what I learned from them.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;A very important point&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Everything you read during these few articles is the result of the effort and time of the speaker itself,&lt;/strong&gt; and I have only tried to learn them so that I can turn them into these articles. Even &lt;strong&gt;many of the sentences written in these articles are exactly what they said or what they wrote in Slides.&lt;/strong&gt; This means if you learn something new, it is because of their efforts.&lt;/p&gt;

&lt;p&gt;Last but not least, I may not dig into every technical detail or live codings in some of the speeches. But if you are interested and need more information, let me know and I’ll try to write a more detailed article separately. Also, don’t forget to check out their Twitter/Linkedin.&lt;/p&gt;

&lt;p&gt;Here you can find the program of the conference:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.jsworldconference.com/program"&gt;JSWORLD Conference&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Animating with Vue
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://twitter.com/codesofra"&gt;Ramona Biscoveanu&lt;/a&gt; - Frontend Developer at SAP&lt;/p&gt;

&lt;p&gt;Sometimes our applications need a little bit of "wow" and we can do this with some "movement" just the perfect amount to make them more alive.&lt;/p&gt;

&lt;p&gt;We will be looking at how to use the Vue magic to create awesome animations, from simple ones to more complex ones, combining Vue with animation libraries.&lt;/p&gt;

&lt;h3&gt;
  
  
  90s Websites
&lt;/h3&gt;

&lt;p&gt;On 90s websites, there were sometimes a lot of motions and colors. But the only way we could have animations back then was with gifs. Just imagine the bandwidth those gifs consumed in the era of Dial-Up internet! So we end up with some tiny low-frame gifs to limit the bandwidth consumption, and this was the result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WWPybChS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qsn3zwddswgzhesjc8hg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WWPybChS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qsn3zwddswgzhesjc8hg.gif" alt="" width="680" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why animate?
&lt;/h3&gt;

&lt;p&gt;One of the reasons we use animations these days, even back then, is to capture users' attention and focus.&lt;/p&gt;

&lt;p&gt;Think of how many distractions we have, notifications on our phones, pop-ups on the websites, or the jumping icons on the dock on macOS.&lt;/p&gt;

&lt;p&gt;We can also trick users into thinking that our website is a lot faster. We give them this perception that our APIs are faster by putting loaders and progress bars. Studies are saying if you have a custom loader you have a chance of keeping the people on our website longer.&lt;/p&gt;

&lt;p&gt;Sometimes we try to inform our users efficiently. Maybe we have lots of things going on on our website and we want to tell the user what is the next step in the flow of the application with an animated button.&lt;/p&gt;

&lt;p&gt;Other times we need interactive content for marketing materials to keep users there.&lt;/p&gt;

&lt;p&gt;Animations are also powerful when you try to tell a story.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vue &lt;code&gt;&amp;lt;Transition /&amp;gt;&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;In Vanilla JavaScript or jQuery, you need to manually calculate the timings and delays, and decide when to add or remove classes. But in Vue, we wrap the target element into the &lt;code&gt;&amp;lt;Transition /&amp;gt;&lt;/code&gt; component and it does many of those hard things automatically. Here is a simple fade animation:&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;transition&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"fade"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"show"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;hello&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/transition&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.fade-enter-active&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.fade-leave-active&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;opacity&lt;/span&gt; &lt;span class="m"&gt;.5s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.fade-enter-from&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.fade-leave-to&lt;/span&gt; 
  &lt;span class="nt"&gt;opacity&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is how Vue handles that:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Rf8xjVKZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sbh3nxd6dumn57pmr36t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Rf8xjVKZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sbh3nxd6dumn57pmr36t.png" alt="" width="880" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Vue &lt;code&gt;&amp;lt;TransitionGroup /&amp;gt;&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;TransitionGroup&amp;gt;&lt;/code&gt; is a built-in component designed for animating the insertion, removal, and order change of elements or components that are rendered in a list.&lt;/p&gt;

&lt;p&gt;This is a simple example of some tiles sliding on the screen:&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;transition-group&lt;/span&gt; &lt;span class="na"&gt;tag=&lt;/span&gt;&lt;span class="s"&gt;"div"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tile-section"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"list"&lt;/span&gt; &lt;span class="na"&gt;appear&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;TileComp&lt;/span&gt;
    &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"(tile, i) in tiles"&lt;/span&gt;
    &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"i + 'tile'"&lt;/span&gt;
    &lt;span class="na"&gt;:header=&lt;/span&gt;&lt;span class="s"&gt;"tile.title"&lt;/span&gt;
    &lt;span class="na"&gt;:content=&lt;/span&gt;&lt;span class="s"&gt;"tile.content"&lt;/span&gt;
    &lt;span class="na"&gt;:footer=&lt;/span&gt;&lt;span class="s"&gt;"tile.footer"&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&amp;lt;/TileComp&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/transition-group&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.list-enter-active&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nc"&gt;.list-leave-active&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.list-enter-from&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nc"&gt;.list-leave-to&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;70px&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;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1xkoB97K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3rj9uu4jqig8qpiolnzg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1xkoB97K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3rj9uu4jqig8qpiolnzg.gif" alt="" width="880" height="710"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  JavaScript Hooks
&lt;/h3&gt;

&lt;p&gt;CSS is awesome and we can do a lot with it, but sometimes it’s not enough.&lt;/p&gt;

&lt;p&gt;Vue provides some hooks on the &lt;code&gt;&amp;lt;Transition /&amp;gt;&lt;/code&gt; component.&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;Transition&lt;/span&gt;
  &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;before-enter=&lt;/span&gt;&lt;span class="s"&gt;"onBeforeEnter"&lt;/span&gt;
  &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;enter=&lt;/span&gt;&lt;span class="s"&gt;"onEnter"&lt;/span&gt;
  &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;after-enter=&lt;/span&gt;&lt;span class="s"&gt;"onAfterEnter"&lt;/span&gt;
  &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;enter-cancelled=&lt;/span&gt;&lt;span class="s"&gt;"onEnterCancelled"&lt;/span&gt;
  &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;before-leave=&lt;/span&gt;&lt;span class="s"&gt;"onBeforeLeave"&lt;/span&gt;
  &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;leave=&lt;/span&gt;&lt;span class="s"&gt;"onLeave"&lt;/span&gt;
  &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;after-leave=&lt;/span&gt;&lt;span class="s"&gt;"onAfterLeave"&lt;/span&gt;
  &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;leave-cancelled=&lt;/span&gt;&lt;span class="s"&gt;"onLeaveCancelled"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- ... --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Transition&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  GreenSock GSAP
&lt;/h3&gt;

&lt;p&gt;The GreenSock Animation Platform (&lt;a href="https://greensock.com/gsap"&gt;GSAP&lt;/a&gt; for short) is a powerful JavaScript library that enables front-end developers and designers to create robust timeline-based animations.&lt;/p&gt;

&lt;p&gt;One of the most important things you will hear a lot in GSAP is Tween.&lt;/p&gt;

&lt;p&gt;A Tween is what does all the animation work — think of it like a high-performance property setter. You feed in targets (the objects you want to animate), a duration, and any properties you want to animate and when its playhead moves to a new position, it figures out what the property values should be at that point and applies them accordingly.&lt;/p&gt;

&lt;p&gt;Common methods for creating a Tween (all of these methods return a Tween instance):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://greensock.com/docs/v3/GSAP/gsap.to()"&gt;gsap.to()&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://greensock.com/docs/v3/GSAP/gsap.from()"&gt;gsap.from()&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://greensock.com/docs/v3/GSAP/gsap.fromTo()"&gt;gsap.fromTo()&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For simple animations (no fancy sequencing), the methods above are all you need!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.selector&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;toVars&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.selector&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;fromVars&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.selector&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;fromVars&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;toVars&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// special properties (duration, ease, etc.) go in toVar&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s add GSAP to our tiles 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;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tile-section"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;TileComp&lt;/span&gt;
    &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"(tile, i) in tiles"&lt;/span&gt;
    &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"i + 'tile'"&lt;/span&gt;
    &lt;span class="na"&gt;:header=&lt;/span&gt;&lt;span class="s"&gt;"tile.title"&lt;/span&gt;
    &lt;span class="na"&gt;:content=&lt;/span&gt;&lt;span class="s"&gt;"tile.content"&lt;/span&gt;
    &lt;span class="na"&gt;:footer=&lt;/span&gt;&lt;span class="s"&gt;"tile.footer"&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&amp;lt;/TileComp&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gsap&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;mounted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.tile&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;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;opacity&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="na"&gt;scale&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="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;power2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;stagger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZScbSY6J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hpsf7h39xvm55mc5r7ku.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZScbSY6J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hpsf7h39xvm55mc5r7ku.gif" alt="" width="880" height="710"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Vue animation counter
&lt;/h3&gt;

&lt;p&gt;Another simple example of using GSAP to make nice animations can be a celebrate counter animation. Here you can see what it will look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xhKVy5ku--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xyya9luquzg29mehiesf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xhKVy5ku--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xyya9luquzg29mehiesf.gif" alt="Image description" width="880" height="617"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All we have in the template is just an h1 element where we pass the formatted value and a reset button.&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;
  &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"celebrate"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"counter"&lt;/span&gt; &lt;span class="na"&gt;:class=&lt;/span&gt;&lt;span class="s"&gt;"{ celebrate: isCelebrate }"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    {{ this.numberWithCommas(value) }}
  &lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"restart"&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;"restart"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Restart&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to use &lt;code&gt;timeline&lt;/code&gt; function of GSAP. Think of it as a tool to sequence your animations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gsap&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;confetti&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;canvas-confetti&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timeline&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;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100000&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;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3240074&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="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;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&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="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="na"&gt;isCelebrate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;mounted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;tl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.counter&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;innerText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;innerText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;snap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;innerText&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;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;linear&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;onUpdate&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$refs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;celebrate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;numberWithCommas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$refs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;celebrate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt;
          &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;onComplete&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;celebrate&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;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;celebrate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isCelebrate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;confetti&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;particleCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;spread&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.6&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;colors&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;#647eff&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;#42d392&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;disableForReducedMotion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;numberWithCommas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&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;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\B(?=(\d{3})&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;(?!\d))&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;,&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;restart&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;tl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isCelebrate&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="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;h3&gt;
  
  
  Page Transition
&lt;/h3&gt;

&lt;p&gt;In Vue Router 4 the syntax for transitioning pages has changed a bit. We don’t wrap the router into the transition component anymore. instead, we use the &lt;code&gt;v-slot&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;router&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="na"&gt;view&lt;/span&gt; &lt;span class="na"&gt;v-slot&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"{ Component }"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;transition&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"fade"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;component&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;is&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Component"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;router&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="na"&gt;view&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is an example of a page transition:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7Oeb6jHb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wlfdz8imff9r7baqc5xt.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7Oeb6jHb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wlfdz8imff9r7baqc5xt.gif" alt="" width="880" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For building this page transition, we need the enter hook:&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;router-view&lt;/span&gt; &lt;span class="na"&gt;v-slot=&lt;/span&gt;&lt;span class="s"&gt;"{ Component }"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;transition&lt;/span&gt;
    &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"$route.path"&lt;/span&gt;
    &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;enter=&lt;/span&gt;&lt;span class="s"&gt;"onEnter"&lt;/span&gt;
    &lt;span class="na"&gt;:css=&lt;/span&gt;&lt;span class="s"&gt;"false"&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;:is=&lt;/span&gt;&lt;span class="s"&gt;"Component"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/transition&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/router-view&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we need to register the &lt;code&gt;SplitText&lt;/code&gt; plugin from GSAP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gsap&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;SplitText&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gsap/SplitText&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;registerPlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SplitText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;defaults&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;duration&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;ease&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;power3.inOut&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;And then using the plugin we split the text to be able to animate it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;mySplitText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;SplitText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="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="s2"&gt;words,chars,lines&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;Let’s take a look at &lt;code&gt;onEnter&lt;/code&gt; hook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;onEnter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;done&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;masterTL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timeline&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;onComplete&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;done&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;masterTL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;enterContentTextAnimation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;mySplitText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.content-text-header&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;chars&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;masterTL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;enterContentTextAnimation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.content-text-body&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;-=0.9&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;//overlap with previous by 0.9s&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;masterTL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;imgScaleOut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.content img&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;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;//The start of previous animation&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here you can see how you can nest GSAP timelines and what  &lt;code&gt;enterContentTextAnimation&lt;/code&gt; and &lt;code&gt;imgScaleOut&lt;/code&gt; functions do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;enterContentTextAnimation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timeline&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;tl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;yPercent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;opacity&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;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;yPercent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;opacity&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;stagger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.03&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="nx"&gt;imgScaleOut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timeline&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;tl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.5&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;tl&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;
  
  
  SVG
&lt;/h3&gt;

&lt;p&gt;Animated charts can be a good example of SVG animation:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JsL2TINj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l3ukmaey09yn46nxady6.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JsL2TINj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l3ukmaey09yn46nxady6.gif" alt="charts" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the part of the code that makes this chart animation possible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;watch&lt;/span&gt;&lt;span class="p"&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;newValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;oldValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&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;index&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;var&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#arc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calculateArc&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;index&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;oldValueD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calculateArc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;oldValue&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&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;tl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gsap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timeline&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="nx"&gt;tl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;oldValueD&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;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="na"&gt;yoyo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;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;It’s important to not abuse animations on your website. Sometimes they are useful, but sometimes they can kill your audience.&lt;/p&gt;




&lt;h2&gt;
  
  
  End of the seventh Talk
&lt;/h2&gt;

&lt;p&gt;I hope you enjoyed this part and it can be as valuable to you as it was to me.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/mohsen_vaziri/the-nuxt-web-vue-amsterdam-conference-2022-summary-series-eighth-talk-lg3"&gt;Here&lt;/a&gt; you can find the next talk about Nuxt 3.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>vue</category>
      <category>animaton</category>
      <category>vueamsterdam</category>
    </item>
    <item>
      <title>It’s a (Testing) trap! — Vue Amsterdam Conference 2022 Summary series — Sixth Talk</title>
      <dc:creator>Mohsen Vaziri</dc:creator>
      <pubDate>Sun, 10 Jul 2022 10:18:33 +0000</pubDate>
      <link>https://dev.to/mohsen_vaziri/its-a-testing-trap-vue-amsterdam-conference-2022-summary-series-sixth-talk-dkf</link>
      <guid>https://dev.to/mohsen_vaziri/its-a-testing-trap-vue-amsterdam-conference-2022-summary-series-sixth-talk-dkf</guid>
      <description>&lt;p&gt;Welcome! Happy to see you in the sixth part of my Vuejs Amsterdam Conference 2022 summary series, in which I share a summary of all the talks with you.&lt;/p&gt;

&lt;p&gt;You can read my JSWorld Conference 2022 Summary series (in four parts) &lt;a href="https://dev.to/mohsen_vaziri/series/18427"&gt;here&lt;/a&gt;, where I summarized all the first day’s talks. You can also find the previous Talks of the Vue Amsterdam conference 2022 in my blog.&lt;/p&gt;

&lt;h2&gt;
  
  
  (Recurring) Introduction
&lt;/h2&gt;

&lt;p&gt;After two and a half years, JSWorld and Vue Amsterdam Conference were back in Theater Amsterdam between 1 and 3 June, and I had the chance to attend this conference for the first time. I learned many things, met many wonderful people, spoke with great developers, and had a great time. On the first day the JSWorld Conference was held, and on the second and third days, the Vue Amsterdam.&lt;/p&gt;

&lt;p&gt;The conference was full of information with great speakers, each of whom taught me something valuable. They all wanted to share their knowledge and information with other developers. So I thought it would be great if I could continue to share it and help others use it.&lt;/p&gt;

&lt;p&gt;At first, I tried to share a few notes or slides, but I felt it was not good enough, at least not as good as what the speaker shared with me. So I decided to re-watch each speech, dive deeper into them, search, take notes and combine them with their slides and even their exact words in their speech and then share it with you so that what I share with you is at least at the same level as what I learned from them.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;A very important point&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Everything you read during these few articles is the result of the effort and time of the speaker itself,&lt;/strong&gt; and I have only tried to learn them so that I can turn them into these articles. Even &lt;strong&gt;many of the sentences written in these articles are exactly what they said or what they wrote in Slides.&lt;/strong&gt; This means if you learn something new, it is because of their efforts. (So if you see some misinformation blame them, not me, right? xD)&lt;/p&gt;

&lt;p&gt;Last but not least, I may not dig into every technical detail or live codings in some of the speeches. But if you are interested and need more information, let me know and I’ll try to write a more detailed article separately. Also, don’t forget to check out their Twitter/Linkedin.&lt;/p&gt;

&lt;p&gt;Here you can find the program of the conference:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.jsworldconference.com/program"&gt;JSWORLD Conference&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  It’s a (Testing) trap! Common testing pitfalls and how to solve them
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://twitter.com/leichteckig"&gt;Ramona Schwering&lt;/a&gt; - Software developer at shopware&lt;/p&gt;

&lt;p&gt;“It’s a trap” - a call or feeling we all might be familiar with, not only when it comes to Star Wars. It’s signalizing a sudden moment of noticing imminent danger.&lt;/p&gt;

&lt;p&gt;This situation is an excellent allegory for an unpleasant realization in testing. Imagine having the best intentions when it comes to testing, but still ending up with tests failing to deliver you any value at all?&lt;/p&gt;

&lt;p&gt;Tests who are feeling like a pain to deal with?&lt;/p&gt;

&lt;p&gt;When writing frontend tests, there are lots of pitfalls on the way.&lt;/p&gt;

&lt;p&gt;In sum, they can lead to lousy maintainability, slow execution time, and - in the worst-case - tests you cannot trust.&lt;/p&gt;

&lt;p&gt;But the worst pain point is those tests that give you new value and result because they are flaky. You have a build that sometimes passes and sometimes fails and you did nothing in between.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pain points
&lt;/h2&gt;

&lt;p&gt;You might be sure that testing has many perks and advantages, but all of those wonderful things can be out shadowed by pain points caused by various reasons. All the things you did with the best intentions but in the long run or even earlier they turned out painful or exhausting.&lt;/p&gt;

&lt;p&gt;For example, slow tests can kill the fun. Imagine you have your pull request and you want it to be merged, but you need to wait hours or maybe days for the pipeline to finally be completed.&lt;/p&gt;

&lt;p&gt;Even worse are tests that are painful to maintain. You think about your past self and you ask: What did you do with this test? What was the purpose?! What did you think about that one? Or other team members who are asking you questions about what you did in the past and you have no clue.&lt;/p&gt;

&lt;p&gt;But the worst pain point are test that give you new value and result because they are flaky. You have a build which some times passes and some times fails and you did nothing in between.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simple tests
&lt;/h2&gt;

&lt;p&gt;It doesn’t have to be this way. One of the most important mindsets and golden rules in JavaScript testing best practices is &lt;strong&gt;Simple.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tests should be designed plain and simple in every case. In unit tests, integration tests, and End to End tests, keep it stupid simple.&lt;/p&gt;

&lt;p&gt;Our goal should be that one is capable to understand your test and get its intent instantly without thinking about it. &lt;/p&gt;

&lt;p&gt;Try to aim for a flat test design, which means only testing as much as needed and using few to no abstractions at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Traps
&lt;/h2&gt;

&lt;p&gt;Let’s look at the first Trap.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;deprecated.plugin&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should throw error&lt;/span&gt;&lt;span class="dl"&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="err"&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;It should throw an error if the deprecated plugin is in use.&lt;/p&gt;

&lt;p&gt;When you look at the title — should throw an error — you don’t know what it wants to accomplish. But the Golden rule says you should know instantly what it’s doing.&lt;/p&gt;

&lt;p&gt;We can make it more comprehensible with the “Three-Part Rule”. The test title should contain three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What is being tested&lt;/li&gt;
&lt;li&gt;Under what circumstances should be tested&lt;/li&gt;
&lt;li&gt;What is the expected result&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With this rule in mind, this is what our test will look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;deprecated.plugin&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Property: Should throw an errorif the deprecated prop is used&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="err"&gt;…&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next Trap can be the test structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Context menu&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should open the context menu on click&lt;/span&gt;&lt;span class="dl"&gt;'&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createWrapper&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBeTruthy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.sw-context-menu&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;isVisible&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;toBeTruthy&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;In this case, declarations, actions, and assertions are written all over the place without any clear structure. Especially in bigger tests, this can be a huge pain. We can make it more structured with AAA Pattern. You divide your test into three parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Arrange: Everything concerning the setup to the scenario the test aims to simulate.&lt;/li&gt;
&lt;li&gt;Actions: Running your unit on the test and doing the steps to get to the results state.&lt;/li&gt;
&lt;li&gt;Assert: Where you can do the assertions and check your test scenario.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is what our test looks like with AAA Pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Context menu&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should open the context menu on click&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createWrapper&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;selector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.sw-context-menu&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="c1"&gt;// Act&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Assert&lt;/span&gt;
        &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBeTruthy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;isVisible&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;toBeTruthy&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 looks much better!&lt;/p&gt;

&lt;p&gt;But there is a problem. Think back to our test case. It is a context menu and it is hidden by default. So we need to open it to interact with it. But it means we need to do an assertion to make sure that it’s open before the act. Doesn’t it destroy the pattern?&lt;/p&gt;

&lt;p&gt;If we are testing the DOM, we sometimes need to check the before and after states. So Let’s take a look at this pattern from another perspective.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;…arrange my test == what I’m &lt;strong&gt;given&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;…act in my test == &lt;strong&gt;when&lt;/strong&gt; something happens.&lt;/li&gt;
&lt;li&gt;…assert the results == something happens &lt;strong&gt;then&lt;/strong&gt; this is what I expect as the outcome.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a pattern taken from behaviour driven development: Given - When - Then&lt;/p&gt;

&lt;p&gt;Our prior test with the usage of this pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Context menu&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should open the context menu on click&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Given&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contextButtonSelector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sw-context-button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contextMenuSelector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.sw-context-menu&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="c1"&gt;// When&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;contextMenu&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contextMenuSelector&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contextMenu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isVisible&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contextButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contextButtonSelector&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;contextButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Then&lt;/span&gt;
        &lt;span class="nx"&gt;contextMenu&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contextMenuSelector&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contextMenu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isVisible&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  E2E Testing
&lt;/h2&gt;

&lt;p&gt;Avoid using placeholders and use realistic naming as much as possible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should create and read product&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;…&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.sw-field—product-name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="kd"&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;T-Shirt Ackbar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.sw-select-product__select_manufacturer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;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;Space Company’);
    …
});
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don’t want to come up with thousands of names, maybe you can use faker or other tools to generate some dummy data, or if it’s okay with the laws and your project, import it from the production state. Just make sure that your test stays comprehensible and easy to read and that you know what it does.&lt;/p&gt;

&lt;p&gt;Let’s take a look at the same test for the next trap, which is selectors.&lt;/p&gt;

&lt;p&gt;If you refactor your application and change some classes — which is common — this could cause your test to fail, and in this case, the test failing without a bug present in your app — which is called a false negative giving no reliable report of your app because it’s not broken, just your implementation changed.&lt;/p&gt;

&lt;p&gt;Look at selectors you must! In other words, you shouldn’t test implementation details. Instead, think about using things a user would call attention to and navigating your application. For example some text inside your page. Even better, use selectors which are not that prone to change, like data attributes. You can even call it for example for cypress &lt;code&gt;data-cy=”submit”&lt;/code&gt; so one instantly know that it is meant for testing.&lt;/p&gt;

&lt;p&gt;Last but not least, don’t use fixed waiting times.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;Cypress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Commands&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;typeSingleSelect&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;prevSubject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;element&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="nx"&gt;subject&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;selector&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="err"&gt;…&lt;/span&gt;
        &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; input`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On one hand, that can slow down your test way too much if a test case will be executed so many times. It can be even worse when your application is being used on weaker hardware. In this case, you may need more than that fix 500ms.&lt;/p&gt;

&lt;p&gt;There are some solutions for that, for example waiting for the changes in the UI, like a for loading spinner to disappear or an animation to stop or something to appear.&lt;/p&gt;

&lt;p&gt;Or even better, wait for API Requests and Responses.&lt;/p&gt;

&lt;p&gt;Tests are there as an assistant to you, not a hindrance. They should feel like a routine not like solving a complex mathematical formula.&lt;/p&gt;




&lt;h2&gt;
  
  
  End of the sixth Talk
&lt;/h2&gt;

&lt;p&gt;I hope you enjoyed this part and it can be as valuable to you as it was to me.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/mohsen_vaziri/animating-with-vue-vue-amsterdam-conference-2022-summary-series-seventh-talk-42c6"&gt;Here&lt;/a&gt; you can find the next talk about animations.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>javascript</category>
      <category>vueamsterda</category>
      <category>jsworld</category>
    </item>
    <item>
      <title>Reusable Widgets that work! — Vue Amsterdam Conference 2022 Summary series — Fifth Talk</title>
      <dc:creator>Mohsen Vaziri</dc:creator>
      <pubDate>Fri, 01 Jul 2022 15:48:56 +0000</pubDate>
      <link>https://dev.to/mohsen_vaziri/reusable-widgets-that-work-vue-amsterdam-conference-2022-summary-series-fifth-talk-473f</link>
      <guid>https://dev.to/mohsen_vaziri/reusable-widgets-that-work-vue-amsterdam-conference-2022-summary-series-fifth-talk-473f</guid>
      <description>&lt;p&gt;Welcome! Happy to see you in the fifth part of my Vuejs Amsterdam Conference 2022 summary series, in which I share a summary of all the talks with you.&lt;/p&gt;

&lt;p&gt;You can read my JSWorld Conference 2022 Summary series (in four parts) &lt;a href="https://dev.to/mohsen_vaziri/series/18427"&gt;here&lt;/a&gt;, where I summarized all the first day's talks. You can also find the previous Talks of the Vue Amsterdam conference 2022 in my blog.&lt;/p&gt;

&lt;h2&gt;
  
  
  (Recurring) Introduction
&lt;/h2&gt;

&lt;p&gt;After two and a half years, JSWorld and Vue Amsterdam Conference were back in Theater Amsterdam between 1 and 3 June, and I had the chance to attend this conference for the first time. I learned many things, met many wonderful people, spoke with great developers, and had a great time. On the first day the JSWorld Conference was held, and on the second and third days, the Vue Amsterdam.&lt;/p&gt;

&lt;p&gt;The conference was full of information with great speakers, each of whom taught me something valuable. They all wanted to share their knowledge and information with other developers. So I thought it would be great if I could continue to share it and help others use it.&lt;/p&gt;

&lt;p&gt;At first, I tried to share a few notes or slides, but I felt it was not good enough, at least not as good as what the speaker shared with me. So I decided to re-watch each speech, dive deeper into them, search, take notes and combine them with their slides and even their exact words in their speech and then share it with you so that what I share with you is at least at the same level as what I learned from them.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;A very important point&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Everything you read during these few articles is the result of the effort and time of the speaker itself,&lt;/strong&gt; and I have only tried to learn them so that I can turn them into these articles. Even &lt;strong&gt;many of the sentences written in these articles are exactly what they said or what they wrote in Slides.&lt;/strong&gt; This means if you learn something new, it is because of their efforts. (So if you see some misinformation blame them, not me, right? xD)&lt;/p&gt;

&lt;p&gt;Last but not least, I may not dig into every technical detail or live codings in some of the speeches. But if you are interested and need more information, let me know and I’ll try to write a more detailed article separately. Also, don’t forget to check out their Twitter/Linkedin.&lt;/p&gt;

&lt;p&gt;Here you can find the program of the conference:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.jsworldconference.com/program"&gt;JSWORLD Conference&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Reusable Widgets that work!
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://twitter.com/MariaLamardo"&gt;Maria Lamardo&lt;/a&gt; - Head of Accessibility Training and Sr Manager of Accessibility Engineering at CVS Health&lt;/p&gt;

&lt;p&gt;Vue.js is an amazing framework that allows you to quickly build reusable components. We can leverage this to build accessible reusable widgets with the help of ARIA (Accessible Rich Internet Application). Using ARIA roles and attributes, we can improve the accessibility of certain elements by providing additional semantics. In this talk, we will go over how to follow the specifications and build accessible and reusable tabs, accordions, toggle buttons, and modal dialogs that work for everyone!&lt;/p&gt;

&lt;h2&gt;
  
  
  Modal
&lt;/h2&gt;

&lt;p&gt;All the things that you need to know about ARIA are well documented in &lt;a href="https://w3c.github.io/aria-practices/#dialog_modal"&gt;W3C&lt;/a&gt; and it is recommended to read, but here is an abstracted version of it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modals Design Considerations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;It must have a button that closes the dialog.&lt;/li&gt;
&lt;li&gt;The content outside of the dialog should be obscured with visual styling like a grey background.&lt;/li&gt;
&lt;li&gt;Make sure you prevent users from interacting with content outside of the dialog.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Modals Opening Focus Interaction
&lt;/h3&gt;

&lt;p&gt;When a dialog opens, focus can be set on either the first focusable element, or a static element at the top of the dialog to make content easier to read and ensure that all the content remains in view, or the most frequently used element if interactions are limited to providing information or continue processing.&lt;/p&gt;

&lt;p&gt;You don’t wanna set focus to something that is going to be destructive for the user, for example, let’s imagine you have an interaction where you open a modal to delete your account. You don’t want to set the first focus on “Yes, delete my account”.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modals Closing Focus Interaction
&lt;/h3&gt;

&lt;p&gt;When a dialog closes, the focus is set on the element that invoked the dialog, or when it doesn’t make sense you can set the focus on a different element, like an element that provides logical workflow if invoking element no longer exists, or on the next element if there is a subsequent step in the workflow following dialog task completion, especially if immediately reopening dialog is very unlikely.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modals Keyboard Interaction
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tab&lt;/th&gt;
&lt;th&gt;Moves focus to next tabbable element in modalLooping around to first element&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Shift + Tab&lt;/td&gt;
&lt;td&gt;Moves focus to previous tabbable element in modalLooping around to last element&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Escape&lt;/td&gt;
&lt;td&gt;Closes the dialog&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Modals Technical Considerations
&lt;/h3&gt;

&lt;p&gt;Dialog container should have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Role of &lt;a href="https://www.w3.org/TR/wai-aria-1.1/#dialog"&gt;dialog&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.w3.org/TR/wai-aria-1.1/#aria-modal"&gt;aria-modal&lt;/a&gt; set to true.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.w3.org/TR/wai-aria-1.1/#aria-label"&gt;aria-label&lt;/a&gt; or &lt;a href="https://www.w3.org/TR/wai-aria-1.1/#aria-labelledby"&gt;aria-labelledby&lt;/a&gt; referring to dialog title, this is going to help assistive technologies figure out what the naming of this element will be.&lt;/li&gt;
&lt;li&gt;Optionally you can set &lt;a href="https://www.w3.org/TR/wai-aria-1.1/#aria-describedby"&gt;aria-describedby&lt;/a&gt; to any description.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All elements required to operate the dialog should be descendants of the element that has a dialog role.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; 
    &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;=&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="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
    &lt;span class="na"&gt;aria-labelledby&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"title"&lt;/span&gt;
    &lt;span class="na"&gt;aria-describedby&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"description"&lt;/span&gt;
&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Title of the dialog&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Information provided by the dialog.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;aria-label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"close"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;×&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the mac, you can Activate Voice Over which is the default mac screen reader by clicking Command + F5, and then you can go through your page and test it.&lt;/p&gt;

&lt;p&gt;Also in chrome Dev-Tools, there is an accessibility tab that has some cool accessibility information.&lt;/p&gt;

&lt;p&gt;With that, you can open &lt;a href="https://cdpn.io/mlama007/debug/PobXVGW"&gt;this example&lt;/a&gt; and check it out, and &lt;a href="https://codepen.io/mlama007/pen/PobXVGW"&gt;here&lt;/a&gt; is the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Toggle Buttons
&lt;/h2&gt;

&lt;p&gt;If you want the full information you can find it on the &lt;a href="https://w3c.github.io/aria-practices/#button"&gt;W3C&lt;/a&gt; website.&lt;/p&gt;

&lt;h3&gt;
  
  
  Buttons
&lt;/h3&gt;

&lt;p&gt;A &lt;a href="https://www.w3.org/TR/wai-aria-1.1/#button"&gt;button&lt;/a&gt; is a widget that enables users to trigger an action or event, such as submitting a form, opening a dialog, canceling an action, or performing a delete operation.&lt;/p&gt;

&lt;p&gt;In addition to the ordinary button widget, WAI-ARIA supports 2 other types of buttons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Toggle buttons&lt;/li&gt;
&lt;li&gt;Menu buttons&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Toggle Buttons Design Considerations
&lt;/h3&gt;

&lt;p&gt;A two-state button that can be either off (not pressed) or on (pressed).&lt;/p&gt;

&lt;p&gt;To tell assistive technologies that a button is a toggle button, specify a value for the attribute &lt;a href="https://www.w3.org/TR/wai-aria-1.1/#aria-pressed"&gt;aria-pressed&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The label on a toggle mustn't change when its state changes; if the label changes in the design, there is no need for the aria-pressed attribute.&lt;/p&gt;

&lt;h3&gt;
  
  
  Toggle Buttons Focus Handling
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;If activating the button does not dismiss the current context, then focus remains on the button after activation.&lt;/li&gt;
&lt;li&gt;If activating the button opens or closes a dialog, then follow the dialog pattern.&lt;/li&gt;
&lt;li&gt;If the button action indicates a context change, you can move focus to the starting point for that action&lt;/li&gt;
&lt;li&gt;If the button is activated with a shortcut key, then focus usually remains in the context from which the shortcut key was activated&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Toggle Buttons Keyboard Interaction
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Enter&lt;/th&gt;
&lt;th&gt;Activates the button&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Space&lt;/td&gt;
&lt;td&gt;Activates the button&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Toggle Buttons Technical Considerations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The Toggle button must have the role of &lt;a href="https://www.w3.org/TR/wai-aria-1.1/#button"&gt;button&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Make sure that the button has an accessible name.&lt;/li&gt;
&lt;li&gt;You can set &lt;a href="https://www.w3.org/TR/wai-aria-1.1/#aria-describedby"&gt;aria-describedby&lt;/a&gt; to any description.&lt;/li&gt;
&lt;li&gt;You can add &lt;a href="https://www.w3.org/TR/wai-aria-1.1/#aria-disabled"&gt;aria-disabled&lt;/a&gt; set to true if action is unavailable.&lt;/li&gt;
&lt;li&gt;The toggle button has an &lt;a href="https://www.w3.org/TR/wai-aria-1.1/#aria-pressed"&gt;aria-pressed&lt;/a&gt; state.
&lt;/li&gt;
&lt;/ul&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;button&lt;/span&gt; &lt;span class="na"&gt;aria-pressed=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Mute
&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;Here is a good &lt;a href="https://cdpn.io/mlama007/debug/MWbZZLr"&gt;example&lt;/a&gt; that you can check out and &lt;a href="https://codepen.io/mlama007/pen/MWbZZLr"&gt;here&lt;/a&gt; is the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accordions
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://w3c.github.io/aria-practices/#accordion"&gt;Here&lt;/a&gt; is the complete documentation. Let’s take a look at its main points.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accordions Design Considerations
&lt;/h3&gt;

&lt;p&gt;Vertically stacked set of interactive headings that each contain a title, content snippet, or thumbnail representing a section of content&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accordion Header:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Label for or thumbnail representing a section of content that also serves as a control for showing, and in some implementations, hiding the section of content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accordion Panel:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Section of content associated with an accordion header.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accordions Keyboard Interaction
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Enter or Space&lt;/th&gt;
&lt;th&gt;Expands associated collapsed panel, optionally collapses other opened panelCollapses associated expanded panel; if the implementation allows.&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tab&lt;/td&gt;
&lt;td&gt;Moves focus to the next focusable element&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shift + Tab&lt;/td&gt;
&lt;td&gt;Moves focus to the previous focusable element&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Down Arrow (Optional)&lt;/td&gt;
&lt;td&gt;Moves focus from the accordion header to the next accordion header Optionally loops back to the first accordion header.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Up Arrow (Optional)&lt;/td&gt;
&lt;td&gt;Moves focus from accordion header to the previous accordion header Optionally loops back to last accordion header&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Home (Optional)&lt;/td&gt;
&lt;td&gt;Moves focus from an accordion header to the first accordion header&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;End (Optional)&lt;/td&gt;
&lt;td&gt;Moves focus from an accordion header to the last accordion header&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Accordions Technical Considerations
&lt;/h3&gt;

&lt;p&gt;Make sure that Each accordion header button has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;wrapped in a heading&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.w3.org/TR/wai-aria-1.1/#aria-controls"&gt;aria-controls&lt;/a&gt; set to the ID of the corresponding accordion panel content&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.w3.org/TR/wai-aria-1.1/#aria-expanded"&gt;aria-expanded&lt;/a&gt; set to true if corresponding panel content is visible&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.w3.org/TR/wai-aria-1.1/#aria-disabled"&gt;aria-disabled&lt;/a&gt; set to true if the collapsing accordion is not permitted&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Optional) Each panel content has &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/Region_role"&gt;role region&lt;/a&gt; and &lt;a href="https://www.w3.org/TR/wai-aria-1.1/#aria-labelledby"&gt;aria-labelledby&lt;/a&gt; to the corresponding header button&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Avoid using the region role in circumstances that create too many landmark region&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Accordions Code Example
&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;h3&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt;
     &lt;span class="na"&gt;aria-expanded=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
     &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"Accordion-trigger"&lt;/span&gt;
     &lt;span class="na"&gt;aria-controls=&lt;/span&gt;&lt;span class="s"&gt;"sect1"&lt;/span&gt;
     &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"accordion1id"&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        Accordion 1
   &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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&lt;/span&gt;
   &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"sect1"&lt;/span&gt;
   &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"region"&lt;/span&gt;
   &lt;span class="na"&gt;aria-labelledby=&lt;/span&gt;&lt;span class="s"&gt;"accordion1id"&lt;/span&gt;
   &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"Accordion-panel"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Content Placeholder
&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;Here is a good &lt;a href="https://cdpn.io/mlama007/debug/XWNooxq"&gt;example&lt;/a&gt; and its &lt;a href="https://codepen.io/mlama007/pen/XWNooxq"&gt;code&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tabs
&lt;/h2&gt;

&lt;p&gt;You can see Tabs’ full documentation on &lt;a href="https://w3c.github.io/aria-practices/#tabpanel"&gt;W3C&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tabs Design Considerations
&lt;/h3&gt;

&lt;p&gt;Tabs are a set of layered sections of content, known as tab panels, that display one panel of content at a time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tab List:&lt;/strong&gt; A set of tab elements contained in a &lt;a href="https://w3c.github.io/aria/#tablist"&gt;tablist&lt;/a&gt; element&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tab:&lt;/strong&gt; An element in the tab list that serves as a label for one of the tab panels and can be activated to display that panel&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tab panel:&lt;/strong&gt; The element that contains the content associated with a tab&lt;/p&gt;

&lt;p&gt;It is recommended that tabs activate automatically when they receive focus as long as their associated tab panels are displayed without noticeable latency.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tabs Keyboard Interaction
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tab&lt;/th&gt;
&lt;th&gt;Places focus on the active tab element when user moves into the tab list&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Left Arrow (Horizontal tabs)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Up Arrow (Vertical tabs)&lt;/td&gt;
&lt;td&gt;Moves focus to the previous tab; looping to the last tabOptionally, activates the newly focused tab&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Right Arrow (Horizontal tabs)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Down Arrow (Vertical tabs)&lt;/td&gt;
&lt;td&gt;Moves focus to the next tab; looping to the first tabOptionally, activates the newly focused tab&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Space or Enter&lt;/td&gt;
&lt;td&gt;Activates the tab if it was not activated automatically on focus&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shift + F10&lt;/td&gt;
&lt;td&gt;When focus is on a tab that has an associated popup menu, opens the menu&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Tabs Optional Keyboard Interaction
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Home (optional)&lt;/th&gt;
&lt;th&gt;Moves focus to the first tabOptionally, activates the newly focused tab&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;End(optional)&lt;/td&gt;
&lt;td&gt;Moves focus to the last tabOptionally, activates the newly focused tab&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete(optional)&lt;/td&gt;
&lt;td&gt;If deletion is allowed, deletes (closes) the current tab element and its associated tab panel, sets focus on the tab following the tab that was closed, and optionally activates the newly focused tab&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Tabs Technical Considerations
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Role of Tablist:&lt;/strong&gt; Element containing a set of tabs must have &lt;a href="https://www.w3.org/TR/wai-aria-1.1/#aria-labelledby"&gt;aria-labelledby&lt;/a&gt; or &lt;a href="https://www.w3.org/TR/wai-aria-1.1/#aria-label"&gt;aria-label&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Role of Tab:&lt;/strong&gt; The element that serves as a tab must have &lt;a href="https://www.w3.org/TR/wai-aria-1.1/#aria-controls"&gt;aria-controls&lt;/a&gt; paired to the associated tabpanel, the active tab should have the state aria-selected set to true; all other tabs are set to false.&lt;/p&gt;

&lt;p&gt;And it should have the property aria-haspopup set to either menu or true if a tab element has a pop-up menu.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Role of Tabpanel:&lt;/strong&gt;  Element containing content panel for a tab should have aria-labelledby paired to associated tab, and set aria-orientation to vertical or horizontal (default).&lt;/p&gt;

&lt;h3&gt;
  
  
  Tabs Code Example
&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;div&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"tablist"&lt;/span&gt; &lt;span class="na"&gt;aria-label=&lt;/span&gt;&lt;span class="s"&gt;"Tabs Example"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt;
    &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"tab"&lt;/span&gt;
    &lt;span class="na"&gt;aria-selected=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
    &lt;span class="na"&gt;aria-controls=&lt;/span&gt;&lt;span class="s"&gt;"tab1-content"&lt;/span&gt;
    &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"tab1"&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Tab 1 &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt;
    &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"tab"&lt;/span&gt;
    &lt;span class="na"&gt;aria-selected=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
    &lt;span class="na"&gt;aria-controls=&lt;/span&gt;&lt;span class="s"&gt;"tab2-content"&lt;/span&gt;
    &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"tab2"&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;Tab 2&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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&lt;/span&gt; 
  &lt;span class="na"&gt;tabindex=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; 
  &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"tabpanel"&lt;/span&gt;  
  &lt;span class="na"&gt;aria-labelledby=&lt;/span&gt;&lt;span class="s"&gt;"tab1"&lt;/span&gt;
  &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"tab1-content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Content 1&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;
  &lt;span class="na"&gt;tabindex=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
  &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"tabpanel"&lt;/span&gt;
  &lt;span class="na"&gt;aria-labelledby=&lt;/span&gt;&lt;span class="s"&gt;"tab2"&lt;/span&gt;
  &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"tab2-content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Content 2&lt;span class="nt"&gt;&amp;lt;/p&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;Here is a good &lt;a href="https://cdpn.io/mlama007/debug/dyOwwQE"&gt;example&lt;/a&gt; and its &lt;a href="https://codepen.io/mlama007/pen/dyOwwQE"&gt;code&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.w3.org/WAI/ARIA/apg/#intro"&gt;ARIA Authoring Practices Guide&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.w3.org/TR/WCAG21/#abstract"&gt;Web Content Accessibility Guidelines (WCAG) 2.1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can find a complete Vue code example with different components here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mlama007/Widgets"&gt;https://github.com/mlama007/Widgets&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  End of the &lt;strong&gt;fifth&lt;/strong&gt; Talk
&lt;/h2&gt;

&lt;p&gt;I hope you enjoyed this part and it can be as valuable to you as it was to me.&lt;/p&gt;

&lt;p&gt;You can find the next Talk &lt;a href="https://dev.to/mohsen_vaziri/its-a-testing-trap-vue-amsterdam-conference-2022-summary-series-sixth-talk-dkf"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>vue</category>
      <category>aria</category>
      <category>vueamsterdam</category>
    </item>
    <item>
      <title>The Unwanted Stack — Vue Amsterdam Conference 2022 Summary series — Forth Talk</title>
      <dc:creator>Mohsen Vaziri</dc:creator>
      <pubDate>Sun, 26 Jun 2022 11:44:52 +0000</pubDate>
      <link>https://dev.to/mohsen_vaziri/the-unwanted-stack-vue-amsterdam-conference-2022-summary-series-forth-talk-3n94</link>
      <guid>https://dev.to/mohsen_vaziri/the-unwanted-stack-vue-amsterdam-conference-2022-summary-series-forth-talk-3n94</guid>
      <description>&lt;p&gt;Welcome! Happy to see you in the fourth part of my Vuejs Amsterdam Conference 2022 summary series, in which I share a summary of all the talks with you.&lt;/p&gt;

&lt;p&gt;You can read my JSWorld Conference 2022 Summary series (in four parts) &lt;a href="https://dev.to/mohsen_vaziri/series/18427"&gt;here&lt;/a&gt;, where I summarized all the first day's talks. You can also find the previous parts of Vue Amsterdam in my blog.&lt;/p&gt;

&lt;h2&gt;
  
  
  (Recurring) Introduction
&lt;/h2&gt;

&lt;p&gt;After two and a half years, JSWorld and Vue Amsterdam Conference were back in Theater Amsterdam between 1 and 3 June, and I had the chance to attend this conference for the first time. I learned many things, met many wonderful people, spoke with great developers, and had a great time. On the first day the JSWorld Conference was held, and on the second and third days, the Vue Amsterdam.&lt;/p&gt;

&lt;p&gt;The conference was full of information with great speakers, each of whom taught me something valuable. They all wanted to share their knowledge and information with other developers. So I thought it would be great if I could continue to share it and help others use it.&lt;/p&gt;

&lt;p&gt;At first, I tried to share a few notes or slides, but I felt it was not good enough, at least not as good as what the speaker shared with me. so I decided to re-watch each speech, dive deeper into them, search, take notes and combine them with their slides and even their exact words in their speech and then share it with you so that what I share with you is at least at the same level as what I learned from them.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;A very important point&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Everything you read during these few articles is the result of the effort and time of the speaker itself,&lt;/strong&gt; and I have only tried to learn them so that I can turn them into these articles. Even &lt;strong&gt;many of the sentences written in these articles are exactly what they said or what they wrote in Slides.&lt;/strong&gt; This means if you learn something new, it is because of their efforts. (So if you see some misinformation blame them, not me, right? xD)&lt;/p&gt;

&lt;p&gt;Last but not least, I may not dig into every technical detail or live codings in some of the speeches. But if you are interested and need more information, let me know and I’ll try to write a more detailed article separately. Also, don’t forget to check out their Twitter/Linkedin.&lt;/p&gt;

&lt;p&gt;Here you can find the program of the conference:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.jsworldconference.com/program"&gt;JSWORLD Conference&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Unwanted Stack
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://twitter.com/MayaShavin"&gt;Maya Shavin&lt;/a&gt; - Senior Software Engineer at Microsoft&lt;/p&gt;

&lt;p&gt;Develop with Vue, build using Vite and deploy using Netlify or Vercel sounds to be the perfect stack, for every Web developer. But life is not always that perfect. And to be a good developer, we need to learn and to adapt ourselves in any situation. How do we make the most out of Vue in a less perfect, or even an unwanted tech stack? Let's join her talk and find out.&lt;/p&gt;

&lt;p&gt;She uses an example of the evolution of building a window as a window manufacturer to make it easier to understand.&lt;/p&gt;

&lt;h2&gt;
  
  
  The beginning
&lt;/h2&gt;

&lt;p&gt;When you start building a simple window, you can build it in any shape that you want and you have a lot of choices. You have the freedom of choice and you can choose any frame(work), any shape, any supporting tool, and any building technique.&lt;/p&gt;

&lt;h2&gt;
  
  
  After a while
&lt;/h2&gt;

&lt;p&gt;Assuming you finish with your windows, either you become the company who makes windows because you’ve released your window out there and it became successful, or it’s just a project that you do in your free time, so now that you know how to build a window you join a company to make windows.&lt;/p&gt;

&lt;p&gt;At this point, you start to realize that you can not choose everything on your own like before.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Delivery/Deploying:&lt;/strong&gt; How you’re going to Deliver the window to production or the store.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Team: H&lt;/strong&gt;ow you’re going to build a team around it; Each person in the team will be in charge of building a section of the window.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability:&lt;/strong&gt; How you’re going to add another lock or another frame or even another layer of protection over your window to protect it from sun or rain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintenance:&lt;/strong&gt; You always have to maintain your window because if it’s not maintainable anymore and people use it and then one day it’s broken and someone gets hurt from it, you have to take responsibility.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration:&lt;/strong&gt; Not all of the windows will fit what your customer needs. For example, it may need to be a little curvier to fit into the area where it supposes to be. So you have to do the integration and provide customization.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And suddenly, you don’t have a choice anymore and you have four factors that you need to consider to work on the window: Frameworks, Tools, Platforms, and Rules.&lt;/p&gt;

&lt;p&gt;The Platform is the base on which you build your windows on, now the question is:&lt;/p&gt;

&lt;p&gt;Can you build your Window on anything you want? → Can you build your application on any platform or server you want?&lt;/p&gt;

&lt;p&gt;Every Company has its favorite platform &amp;amp; stack. For example, Google has its own Google Cloud, Amazon has AWS, and Microsoft has Power app and Azure. So when you work with one of these companies you don’t decide on the platform, you work with the platform. But it’s not always your favorite one!&lt;/p&gt;

&lt;h2&gt;
  
  
  The New Guy Phenomenon
&lt;/h2&gt;

&lt;p&gt;“The one who thinks he’s cooler and knows better, and always asks: Why would you do that instead of this?!”&lt;/p&gt;

&lt;p&gt;When you join a new company, this is how you feel and how other people see you because you come fresh, so when you go into the system you think you know it better and ask questions like why do you use Webpack instead of Vite?!&lt;/p&gt;

&lt;p&gt;This is common and you start wanting to change things, which is good. But it leads to another debate:&lt;/p&gt;

&lt;p&gt;“My Approach, my framework, and my stack are better!”&lt;/p&gt;

&lt;p&gt;Or after some time you fail in convincing or feel that:&lt;/p&gt;

&lt;p&gt;“What am I doing here?! I don’t know and don’t like this stack!”&lt;/p&gt;

&lt;p&gt;So are you going to leave because that’s not the stack that you want?&lt;/p&gt;

&lt;h2&gt;
  
  
  It’s not about you
&lt;/h2&gt;

&lt;p&gt;The tech stack is been there for a long time. It can be changed, but&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It’s not about you, and It’s not about Evan You either! No one changes the stack just because of you or Evan You!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  It’s about the &lt;del&gt;Window&lt;/del&gt; Project
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Deployment - CI/CD, Architecture, Compliance, Platforms&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These represent the whole process of building a project. When you come into a new team or start a new project in a company, you need to consider these four cubes and not just go ahead and talk about a cool framework that comes with some nice tool that makes it a perfect stack. You need to consider the whole thing and find out why this is good for the project.&lt;/p&gt;

&lt;p&gt;For example in a project which Maya works on in Microsoft, There is not much control on the Platform and Deployment part.&lt;/p&gt;

&lt;p&gt;The Platform is already there and has all the connections to the database and all the authentication. So you can build everything up, but it also takes away some control. You don’t have control over the build process because the deployment is taken care of by the Power Apps. You don’t have control of building the server because the server is already there and you only need to config it to work with your application.&lt;/p&gt;

&lt;p&gt;So what we have right now is the control over the architecture and compliance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Project nature (size, type, etc)
&lt;/h3&gt;

&lt;p&gt;When you work on a project, you have to consider the nature of the project. Not every project is the same, and not every project needs the same stack.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code Maintenance
&lt;/h3&gt;

&lt;p&gt;How you are going to maintain and structure your code so that when the next new guy comes into your code base, he will not feel lost in the wood?&lt;/p&gt;

&lt;h3&gt;
  
  
  Scalability
&lt;/h3&gt;

&lt;p&gt;How much scalability you’re going to provide in your code? If you are going to write a normal website or a landing page, you probably don’t need scalability, but if you are going to write an application where every piece is a component going to be reused by some other team or be deployed to the customer as the component itself and they would take it and use it in their applications, you probably need to understand how to do scalability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Team performance (Skills, expertise)
&lt;/h3&gt;

&lt;p&gt;This is not about the performance of the application, it is about how fast a team can walk together and can help each other to achieve what you want to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compliance
&lt;/h2&gt;

&lt;p&gt;This is what you want to do to comply with a bunch of protocols that your projects are given.&lt;/p&gt;

&lt;p&gt;Startups or small companies may have fewer protocols, but in big companies like Microsoft and Google, there are many protocols to fulfill before you can release something.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accessibility Support
&lt;/h3&gt;

&lt;p&gt;Accessibility has to be a huge part because It is usability for everyone so you can not ignore it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing (E2E, Unit test)
&lt;/h3&gt;

&lt;p&gt;Are you going to manually run your test, check on your browser or have a whole team dedicated to doing manual testing? That’s not going to work. Nowadays finding people is hard and finding manual QAs is harder.&lt;/p&gt;

&lt;h3&gt;
  
  
  UI Consistency
&lt;/h3&gt;

&lt;p&gt;Every Company has its own product and brand in UI design. For example, the Flat UI in Microsoft. At Microsoft in every single product, no matter what tech stack developers use, they have to use the same standards and protocols for the UI components, and in everything they do, the UI has to match the company’s branding and look and feel.&lt;/p&gt;

&lt;p&gt;For example, if a user uses an Excel file and there is a Save button, your new application has to have the same color and look and feel for its save button.&lt;/p&gt;

&lt;h3&gt;
  
  
  Integration/Customization
&lt;/h3&gt;

&lt;p&gt;To what extent are we going to provide integration or customization? What is the level of workaround we want our customers to have?&lt;/p&gt;

&lt;p&gt;If you are going to build a store, that’s not much customization here except for the UI. But if you are going to build a dashboard that will be integrated into the customer database and pull data from the customer and it still needs to maintain the look and feel like Microsoft app, that would be the part where you trying to shape your application so that it will work with different customer needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Select(newCoolTool)
&lt;/h2&gt;

&lt;p&gt;Let’s say you are the new guy on the team and you want to propose to change a testing tool. How do you want to do that?&lt;/p&gt;

&lt;p&gt;For doing that, you have to understand what are the priorities, what are the alternatives and compare them, compatibility with the system, and only then, you propose the change to your managers or your team with Data. Here is an example:&lt;/p&gt;

&lt;h2&gt;
  
  
  Select(e2etesting)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is the goal?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Speed?&lt;/li&gt;
&lt;li&gt;Visual support?&lt;/li&gt;
&lt;li&gt;Cross-browser support?&lt;/li&gt;
&lt;li&gt;Flexibility in changing test runner?&lt;/li&gt;
&lt;li&gt;Parallel testing?&lt;/li&gt;
&lt;li&gt;Accessibility testing support?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How compatible is it?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Platform integration?&lt;/li&gt;
&lt;li&gt;CI/CD integration?&lt;/li&gt;
&lt;li&gt;Maintenance effort?&lt;/li&gt;
&lt;li&gt;Learning effort?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why would it be THE solution?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;What are the tradeoffs?&lt;/li&gt;
&lt;li&gt;Developer experience?&lt;/li&gt;
&lt;li&gt;Community support&lt;/li&gt;
&lt;li&gt;Comparisons&lt;/li&gt;
&lt;li&gt;Scalability&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Show me some data
&lt;/h3&gt;

&lt;p&gt;You will do a demo, and not just a simple demo on a small or simple case, but make the test on the hardest and most complex case of your application. That takes time but if you do that, you can see the difference in performance between the two frameworks. Because the most complex situation is what you will face in the feature. If you choose one testing framework and it’s failed to do that complex case, then you have to revert and choose a different one and that means all the effort of trying to learn and write tests and adapt to the new testing framework got wasted.&lt;/p&gt;

&lt;p&gt;And be ready for questions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Change the stack, or make the best out of it
&lt;/h3&gt;

&lt;p&gt;There are several things that you can do to make the best out of the stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep the coding standard&lt;/li&gt;
&lt;li&gt;Use TypeScript&lt;/li&gt;
&lt;li&gt;Be open-minded&lt;/li&gt;
&lt;li&gt;Create solutions, not refactor first&lt;/li&gt;
&lt;li&gt;Understand your window nature first&lt;/li&gt;
&lt;li&gt;Plan your window&lt;/li&gt;
&lt;li&gt;Instead of thy, try “What can be better?”&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  End of the &lt;strong&gt;fourth&lt;/strong&gt; Talk
&lt;/h2&gt;

&lt;p&gt;I hope you enjoyed this part and it can be as valuable to you as it was to me.&lt;/p&gt;

&lt;p&gt;You can find the next Talk &lt;a href="https://dev.to/mohsen_vaziri/reusable-widgets-that-work-vue-amsterdam-conference-2022-summary-series-fifth-talk-473f"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>jsworld</category>
      <category>vueamsterdam</category>
      <category>techstack</category>
    </item>
    <item>
      <title>Fast stories powered by Vite; Histoire — Vue Amsterdam Conference 2022 Summary series — Third Talk</title>
      <dc:creator>Mohsen Vaziri</dc:creator>
      <pubDate>Wed, 22 Jun 2022 18:39:38 +0000</pubDate>
      <link>https://dev.to/mohsen_vaziri/fast-stories-powered-by-vite-histoire-vue-amsterdam-conference-2022-summary-series-third-talk-543n</link>
      <guid>https://dev.to/mohsen_vaziri/fast-stories-powered-by-vite-histoire-vue-amsterdam-conference-2022-summary-series-third-talk-543n</guid>
      <description>&lt;p&gt;Welcome! Happy to see you in the third part of my Vuejs Amsterdam Conference 2022 summary series, in which I share a summary of all the talks with you.&lt;/p&gt;

&lt;p&gt;You can read my JSWorld Conference 2022 Summary series (in four parts) &lt;a href="https://dev.to/mohsen_vaziri/series/18427"&gt;here&lt;/a&gt;, where I summarized all the first day's talks. You can also find the previous parts of Vue Amsterdam in my blog.&lt;/p&gt;

&lt;h2&gt;
  
  
  (Recurring) Introduction
&lt;/h2&gt;

&lt;p&gt;After two and a half years, JSWorld and Vue Amsterdam Conference were back in Theater Amsterdam between 1 and 3 June, and I had the chance to attend this conference for the first time. I learned many things, met many wonderful people, spoke with great developers, and had a great time. On the first day the JSWorld Conference was held, and on the second and third days, the Vue Amsterdam.&lt;/p&gt;

&lt;p&gt;The conference was full of information with great speakers, each of whom taught me something valuable. They all wanted to share their knowledge and information with other developers. So I thought it would be great if I could continue to share it and help others use it.&lt;/p&gt;

&lt;p&gt;At first, I tried to share a few notes or slides, but I felt it was not good enough, at least not as good as what the speaker shared with me. so I decided to re-watch each speech, dive deeper into them, search, take notes and combine them with their slides and even their exact words in their speech and then share it with you so that what I share with you is at least at the same level as what I learned from them&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;A very important point&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Everything you read during these few articles is the result of the effort and time of the speaker itself,&lt;/strong&gt; and I have only tried to learn them so that I can turn them into these articles. Even &lt;strong&gt;many of the sentences written in these articles are exactly what they said or what they wrote in Slides.&lt;/strong&gt; This means if you learn something new, it is because of their efforts. (So if you see some misinformation blame them, not me, right? xD)&lt;/p&gt;

&lt;p&gt;Last but not least, I may not dig into every technical detail or live codings in some of the speeches. But if you are interested and need more information, let me know and I’ll try to write a more detailed article separately. Also, don’t forget to check out their Twitter/Linkedin.&lt;/p&gt;

&lt;p&gt;Here you can find the program of the conference:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.jsworldconference.com/program" rel="noopener noreferrer"&gt;JSWORLD Conference&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Fast stories powered by Vite; Histoire
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://twitter.com/Akryum" rel="noopener noreferrer"&gt;Guillaume Chau&lt;/a&gt; - Vue.js Core Team&lt;/p&gt;

&lt;p&gt;The Talk is about writing component stories. Histoire is a tool like Storybook specifically built for the Vue ecosystem, which makes it easier to integrate and use.&lt;/p&gt;

&lt;p&gt;I liked this project and I think Guillaume did a great job.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why stories?
&lt;/h2&gt;

&lt;p&gt;A story is a small number of components mounted in an isolated environment.&lt;/p&gt;

&lt;p&gt;A Story makes it easier to organize and document components for other developers, Showcase features and components, Develop components in isolation, and test components.&lt;/p&gt;

&lt;p&gt;Usually, we end up writing stories when we have a design system in the company which is common these days, where you define how each component is going to look, so it’s nice to have a place where you can showcase your design system to other developers or stakeholders. It’s also very useful when you have a component library.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing Stories
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;I found the way we write our stories could be better. So my goal was to improve the developer experience when you create stories. My experience was mostly with Storybook which is great and has a lot of features, but I felt the experience was not optimal for Vue developers specifically. I also wanted to make the stories fit into your project so that they don’t feel out of place [make them feel ‘native’ to the project]. I also wanted to use most of the same tools that developers are already using so that you don’t have to learn a new syntax and use entirely different tools to write stories, and also I wanted something which has a very nice UI and also is easily customizable to match your brand. And lastly, I wanted to be fast.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you are a Vue developer and look at these, it’s straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Meow.story.vue --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Story&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"🐱 Mewo"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        🐱
    &lt;span class="nt"&gt;&amp;lt;/Story&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Meow.story.vue --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;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="nx"&gt;Meow&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;./Meow.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Story&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Meow&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/Story&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Cars.story.vue --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;Story&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Cars"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Variant&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"default"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      🚗
    &lt;span class="nt"&gt;&amp;lt;/Variant&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Variant&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Fast"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      🏎️
    &lt;span class="nt"&gt;&amp;lt;/Variant&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Variant&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Slow"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      🚜
    &lt;span class="nt"&gt;&amp;lt;/Variant&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/Story&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Vite Native
&lt;/h2&gt;

&lt;p&gt;Some of the benefits of using Vite are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reuse the same build pipeline&lt;/li&gt;
&lt;li&gt;Less time and effort setting up&lt;/li&gt;
&lt;li&gt;Fast boot and instant HMR&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Histoire?
&lt;/h2&gt;

&lt;p&gt;It’s native to Vite projects, idiomatic to the developers — currently only supports Vue but in the feature, it will support other frameworks.&lt;/p&gt;

&lt;p&gt;It’s also fast, light, customizable, and seems to have a great user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Packed with features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;⚡ Dynamic source: It generates the template dynamically and you can copy-paste it.&lt;/li&gt;
&lt;li&gt;🎨 Automatic design tokens: If you have e.g. tailwind configuration, it will automatically generate stories with design tokens such as colors, shadows, text sizes, etc.&lt;/li&gt;
&lt;li&gt;🎹 Flexible controls: Not only with props, but it also works with Vue slots.&lt;/li&gt;
&lt;li&gt;🌔 Dark theme&lt;/li&gt;
&lt;li&gt;📖 Markdown docs&lt;/li&gt;
&lt;li&gt;📱 Responsive testing&lt;/li&gt;
&lt;li&gt;🍱 Variant grids&lt;/li&gt;
&lt;li&gt;🔍 Fast fuzzy search&lt;/li&gt;
&lt;li&gt;📷 Visual regression testing&lt;/li&gt;
&lt;li&gt;More to come...&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Hands-on&lt;/strong&gt;
&lt;/h2&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;pnpm i -D histoire
&lt;span class="gh"&gt;# OR&lt;/span&gt;
npm i -D histoire
&lt;span class="gh"&gt;# OR&lt;/span&gt;
yarn add -D histoire
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Useful scripts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;"story:dev": "histoire dev",
"story:build": "histoire build",
"story:preview": "histoire preview"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The live example code from the Talk
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// BaseButton.vue&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nf"&gt;defineProps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;color&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="nb"&gt;String&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;count&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="nb"&gt;Number&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;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;slot&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/template&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// BaseButton.story.vue&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="o"&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;hstEvent&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;histoire/client&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;BaseButton&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;./BaseButton.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;text&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;toto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Story&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;BaseButton&lt;/span&gt;
            &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;click&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hstEvent('click', $event)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/BaseButton&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;controls&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HstText&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/template&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Story&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/template&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;docs&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;md&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;BaseButton&lt;/span&gt;


&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;BaseButton&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;Hulk&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/BaseBUtto&lt;/span&gt;&lt;span class="err"&gt;n
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/template&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/docs&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

&lt;h2&gt;
  
  
  Nuxt
&lt;/h2&gt;

&lt;p&gt;Histoire fully supports Nuxt out of the box and it’s easy to install.&lt;/p&gt;

&lt;p&gt;Histoire also automatically generates some useful stories from your Tailwind config.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Useful links
&lt;/h2&gt;

&lt;p&gt;Documentation:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://histoire.dev/" rel="noopener noreferrer"&gt;Histoire&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Online demo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vue3.examples.histoire.dev/" rel="noopener noreferrer"&gt;Histoire&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Try it in a live editor:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackblitz.com/edit/histoire-vue3-starter" rel="noopener noreferrer"&gt;histoire-vue3-starter - StackBlitz&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  End of the third Talk
&lt;/h2&gt;

&lt;p&gt;I hope you enjoyed this part and it can be as valuable to you as it was to me.&lt;/p&gt;

&lt;p&gt;You can find the next Talk about Unwanted Stack &lt;a href="https://dev.to/mohsen_vaziri/the-unwanted-stack-vue-amsterdam-conference-2022-summary-series-forth-talk-3n94"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
      <category>histoire</category>
      <category>vueamsterdam</category>
    </item>
    <item>
      <title>Getting more out of your Pinia Stores  — Vue Amsterdam Conference 2022 Summary series — Second Talk</title>
      <dc:creator>Mohsen Vaziri</dc:creator>
      <pubDate>Tue, 21 Jun 2022 08:22:05 +0000</pubDate>
      <link>https://dev.to/mohsen_vaziri/getting-more-out-of-your-pinia-stores-vue-amsterdam-conference-2022-summary-series-second-talk-4n54</link>
      <guid>https://dev.to/mohsen_vaziri/getting-more-out-of-your-pinia-stores-vue-amsterdam-conference-2022-summary-series-second-talk-4n54</guid>
      <description>&lt;p&gt;Welcome! Happy to see you in the second part of my Vuejs Amsterdam Conference 2022 summary series, in which I share a summary of all the talks with you.&lt;/p&gt;

&lt;p&gt;You can read my JSWorld Conference 2022 Summary series (in four parts) &lt;a href="https://dev.to/mohsen_vaziri/series/18427"&gt;here&lt;/a&gt;, where I summarized all the talks of the first day. You can also find the &lt;a href="https://dev.to/mohsen_vaziri/state-of-the-vuenion-vue-amsterdam-conference-2022-summary-series-first-talk-i6b"&gt;first Talk where Evan You talks about the State of Vue in 2022 here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  (Recurring) Introduction
&lt;/h2&gt;

&lt;p&gt;After two and a half years, JSWorld and Vue Amsterdam Conference were back in Theater Amsterdam between 1 and 3 June, and I had the chance to attend this conference for the first time. I learned many things, met many wonderful people, spoke with great developers, and had a great time. On the first day the JSWorld Conference was held, and on the second and third days, the Vue Amsterdam.&lt;/p&gt;

&lt;p&gt;The conference was full of information with great speakers, each of whom taught me something valuable. They all wanted to share their knowledge and information with other developers. So I thought it would be great if I could continue to share it and help others use it.&lt;/p&gt;

&lt;p&gt;At first, I tried to share a few notes or slides, but I felt it was not good enough, at least not as good as what the speaker shared with me. so I decided to re-watch each speech, dive deeper into them, search, take notes and combine them with their slides and even their exact words in their speech and then share it with you so that what I share with you is at least at the same level as what I learned from them&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;A very important point&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Everything you read during these few articles is the result of the effort and time of the speaker itself,&lt;/strong&gt; and I have only tried to learn them so that I can turn them into these articles. Even &lt;strong&gt;many of the sentences written in these articles are exactly what they said or what they wrote in Slides.&lt;/strong&gt; This means if you learn something new, it is because of their efforts. (So if you see some misinformation blame them, not me, right? xD)&lt;/p&gt;

&lt;p&gt;Last but not least, I may not dig into every technical detail or live codings in some of the speeches. But if you are interested and need more information, let me know and I’ll try to write a more detailed article separately. Also, don’t forget to check out their Twitter/Linkedin.&lt;/p&gt;

&lt;p&gt;Here you can find the program of the conference:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.jsworldconference.com/program"&gt;JSWORLD Conference&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Getting more out of your Pinia Stores
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://twitter.com/posva"&gt;Eduaro San Martin Morote&lt;/a&gt; - Creator at Vue-Router&lt;/p&gt;

&lt;p&gt;Pinia might be a light library with a simple API but it takes advantage of many Vue Reactivity concepts like Effect Scopes, which are unknown by most. In this talk we will go through some of the internals of Pinia, understanding them and discovering how to enhance our usage of Pinia.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;During the time I was creating Pinia, I had a lot of experimenting going on with the &lt;code&gt;Refs&lt;/code&gt; and &lt;code&gt;Reactives&lt;/code&gt; and the whole reactivity system of Vue, which gave me a lot of insights on how to keep that one single source of truth that we love so much in Vue.****&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  State Alchemy with Pinia
&lt;/h2&gt;

&lt;p&gt;Pinia is the successor of Vuex, without compromising all the developer experience that comes with Vuex. It is compatible with Vue 2 and Vue 3, and it’s lighter and Vuex.&lt;/p&gt;

&lt;p&gt;One of the advantages of Pinia is that it’s Fully (automatically) type-safe. This library is based on the Composition API, but you don’t need to use the Composition API to use Pinia.&lt;/p&gt;

&lt;p&gt;It has a testing library and a Nuxt module as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vuex vs Pinia
&lt;/h2&gt;

&lt;p&gt;In Vuex you have some important rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can only change the state in mutations.&lt;/li&gt;
&lt;li&gt;You have to shout in action if you want to do it! (That’s why we write it in uppercase!)&lt;/li&gt;
&lt;li&gt;Mutations have to be synchronous and only actions can be asynchronous
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Vuex&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;createApp&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createStore&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;vuex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// Create the store instance&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;state&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="na"&gt;count&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="na"&gt;mutations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;INCREMENT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="o"&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;getters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;double&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;increment&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;commit&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;someAsyncCall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nx"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;increment&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="c1"&gt;// You have to use it as an Application plugin&lt;/span&gt;
&lt;span class="nx"&gt;createApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&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;Now let’s take a look at Pinia:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Pinia&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;createApp&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineStore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createPinia&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;pinia&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;useStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;state&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="na"&gt;count&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="na"&gt;getters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;double&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;increment&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;someAsyncCall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="c1"&gt;// There is no mutation, you can access the state with this keyword&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="o"&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="nx"&gt;createApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createPinia&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&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;There aren’t many changes, except you no longer have to shout to change the state, and there is a function that is not creating a store, it’s defining a store. The difference is, that function is going to return another function that we call to get the actual store. The reason is to handle all the different ways we use the store to have an out of the box dynamic module registrations. In the end, &lt;code&gt;CreatePinia()&lt;/code&gt; the function creates the Pinia instance.****&lt;/p&gt;

&lt;h2&gt;
  
  
  What does the Pinia instance really do?
&lt;/h2&gt;

&lt;p&gt;If you look at the Pinia instance you’re going to notice two things.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;use()&lt;/code&gt; function which is for Pinia plugins.&lt;/p&gt;

&lt;p&gt;A state, which is just a &lt;code&gt;ref&lt;/code&gt; of an initially empty object which get’s populated after you call some stores.&lt;/p&gt;

&lt;p&gt;That state is instantiated inside its own &lt;code&gt;EffectScope&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;To explain &lt;code&gt;EffectScope&lt;/code&gt; we can talk about components. When you have a component that is mounted, it’s going to create its own &lt;code&gt;EffectScope&lt;/code&gt; , which is going to collect all the reactivity variables like watchers, computed, etc. under its umbrella, and when the component is unmounted, this &lt;code&gt;EffectScope&lt;/code&gt; is disposed and all the variables go away.&lt;/p&gt;

&lt;p&gt;It’s the same for Pinia, except it never disappears and is always there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pinia Holds State
&lt;/h2&gt;

&lt;p&gt;The stores are never going to hold the state by themselves, they're going to transfer that to the Pinia instance. So you can access the state at any time with &lt;code&gt;pinia.state.value&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The first time you call the &lt;code&gt;useSomeStore()&lt;/code&gt; in your application, it’s going to put the initial state into the store using the id of the store as the key.&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;authStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useAuthStore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// Here the id will be "auth"&lt;/span&gt;
&lt;span class="nx"&gt;pinia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// If we call another store, It will add another object&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cartStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useCartStore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;pinia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So as the user navigates through the application, the store keeps growing as it needed.&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;pinia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="c1"&gt;// other stores' state&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pinia connects state
&lt;/h2&gt;

&lt;p&gt;You can access the whole state of a store through &lt;code&gt;$state&lt;/code&gt;. This variable is just a getter to access the store in Pinia.&lt;/p&gt;

&lt;p&gt;There are three different ways of accessing a state in the store.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Through the Pinia instance: &lt;code&gt;pinia.state.value.auth.user.login&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Through &lt;code&gt;$state&lt;/code&gt; on the store instance: &lt;code&gt;authStore.$state.user.login&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Directly through the store instance: &lt;code&gt;authStore.user.login&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any of these variables is going to yield the same result, and also if you write to any of these variables you are also going to write to the three of them, in fact, you are only writing to the Pinia state, because &lt;strong&gt;there is only one source of Truth.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Vue composition API there is a &lt;code&gt;toRef&lt;/code&gt; function that gives you a &lt;code&gt;ref&lt;/code&gt; to a reactive object. So if you have something that is reactive, you can get a &lt;code&gt;ref&lt;/code&gt; to any part of the object and it will be connected and if one of them changes, the other one will change as well (and you have only one single source of truth).&lt;/p&gt;

&lt;p&gt;When we define the store with &lt;code&gt;defineStore&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useAuthStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auth&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;state&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="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;alice&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;}),&lt;/span&gt;

&lt;span class="c1"&gt;// pinia.state.value.auth&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and when we instantiate the store with the &lt;code&gt;useAuthStore&lt;/code&gt; function and pass an object to the state, effectively what is happening is that we are getting a &lt;code&gt;ref&lt;/code&gt; out of the state.&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;useAuthStore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;pinia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;alice&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;authStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;toRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pinia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&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;We don’t have to write &lt;code&gt;authStore.user.value.login&lt;/code&gt;, we just read the property or write to it using &lt;code&gt;.value&lt;/code&gt; which is called ref unwrapping.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;authStore&lt;/code&gt; is a reactive object so any &lt;code&gt;ref&lt;/code&gt; passed inside is going to get unwrapped.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ref Unwrapping
&lt;/h2&gt;

&lt;p&gt;When you create a reactive object, any &lt;code&gt;ref&lt;/code&gt; passed inside at any level of that object gets automatically unwrapped, so you don’t need &lt;code&gt;.value&lt;/code&gt; anywhere and is gonna be type-safe.&lt;/p&gt;

&lt;p&gt;💡 You can avoid this behavior with &lt;code&gt;shallowRef()&lt;/code&gt; and &lt;code&gt;shallowReactive()&lt;/code&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;pinia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt; &lt;span class="c1"&gt;// or reactive({})&lt;/span&gt;
&lt;span class="nx"&gt;pinia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;login&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;alice&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// Don't do this! 🙅🏻‍♂️&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;pinia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;login&lt;/span&gt; &lt;span class="c1"&gt;// alice&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should never write a &lt;code&gt;ref&lt;/code&gt; inside a reactive object because there is no point in doing so, writing &lt;code&gt;ref(’alice’)&lt;/code&gt; in the code above is the same as writing the string &lt;code&gt;‘alice’&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But what is interesting is not refs themselves, but refs with all their behaviors attached to them.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Composables&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Composables are functions that have a stateful return. One of the common composables is &lt;code&gt;useLocalStorage&lt;/code&gt; which is from a library called &lt;code&gt;VueUse&lt;/code&gt;, and it gives you a &lt;code&gt;ref&lt;/code&gt; that is going to read from and write to local storage.&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;pinia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt; &lt;span class="c1"&gt;// or reactive({})&lt;/span&gt;
&lt;span class="nx"&gt;pinia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;useLocalStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pinia/user/login&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;alice&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;pinia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;login&lt;/span&gt; &lt;span class="c1"&gt;// alice&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means that we can call that composable inside of the state function when we define a store:&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;useLocalStorage&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;@vueuse/core&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;useAuthStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auth&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;state&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="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;useLocalStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pinia/user/login&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;alice&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="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;So if you have composables that return a writable source of truth (like a &lt;code&gt;ref&lt;/code&gt;), you can put them inside state and they are going to get unwrapped. So the actual behavior that may be interesting for us becomes an implementation detail we don’t need to care about anymore because it is just going to work out of the box. For example &lt;code&gt;useColorMode&lt;/code&gt; or &lt;code&gt;useRouteHash&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But if you have a read-only state — which is more like a computed property — or you have a function — which is more like an action — it’s going to be a little different and we will see later how to use them.****&lt;/p&gt;

&lt;h3&gt;
  
  
  When does this not work?
&lt;/h3&gt;

&lt;p&gt;If you are doing CSR it works fine. However, if you are doing SSR or SSG there will be some problems.&lt;/p&gt;

&lt;p&gt;The problem is the state function is only called once the first time we instantiate the store.&lt;/p&gt;

&lt;p&gt;In CSR, we start with an empty state, then we call the store with &lt;code&gt;useAuthStore()&lt;/code&gt; and that’s going to instantiate the state and become reactive, easy!&lt;/p&gt;

&lt;p&gt;In SSR, we do the same, But the problem is when the page comes back to the client on the browser, although we have the Client Side Rendering again, but on the server, the state was already executed and it was already instantiated once and we are not going to do that again on the client. That means we don’t get an empty object here and we get the object from the server.&lt;/p&gt;

&lt;p&gt;So when we call &lt;code&gt;useAuthStore&lt;/code&gt;, &lt;code&gt;useLocalStorage&lt;/code&gt; is no longer called, and we no longer have that composable creating all the watchers, connecting all the event listeners to the window, it becomes just a string and probably the server is going to give us &lt;code&gt;‘alice’&lt;/code&gt; because there is no local storage.&lt;/p&gt;

&lt;p&gt;💡 Fortunately VueUse is going to make the local storage function work on the server as well.&lt;/p&gt;

&lt;p&gt;💡 Some composables require a little bit more work if you want to make them work on SSR. For example, you have to check your current instance or check if there is a window object that you can rely on. &lt;br&gt;
If you want to learn more, you can check the source code of VueUse. It’s very comfortable because in the documentation, at the very bottom of every function you see a link to the source in the Github repository.&lt;/p&gt;

&lt;p&gt;But what do we need to make this work on SSR?&lt;/p&gt;

&lt;p&gt;We need an extra function called &lt;code&gt;hydrate()&lt;/code&gt; that is going to create the watchers and event listeners on the client-side. This function is called if the initial state exists at store creation.&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;useLocalStorage&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;@vueuse/core&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;useAuthStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auth&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;state&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="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;useLocalStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pinia/user/login&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;alice&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="nx"&gt;hydrate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;login&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useLocalStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pinia/user/login&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;alice&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So that state being set by &lt;code&gt;UseAuthStore&lt;/code&gt; is going to be replaced by the hydrate function. To recap:&lt;/p&gt;

&lt;p&gt;On SSR:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We have an initial state:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;pinia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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;ul&gt;
&lt;li&gt;We call &lt;code&gt;useAuthStore()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;useAuthStore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;We have the new state:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;pinia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&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;and that is going to be sent to the client. Then on CSR:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We start with that state
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;pinia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&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;ul&gt;
&lt;li&gt;We call &lt;code&gt;useAuthStore()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;useAuthStore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;// does not call state()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;And then we have the &lt;code&gt;hydrate&lt;/code&gt; function adding the little bit that we were missing from the state function again
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;login&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useLocalStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pinia/user/login&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;alice&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;h2&gt;
  
  
  Options Store vs Setup Store
&lt;/h2&gt;

&lt;p&gt;Options store which is pretty much like options API is what we talked about so far.&lt;/p&gt;

&lt;p&gt;Setup stores are stores that are defined with a function similar to the setup function in composition API.&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;useAuthStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auth&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="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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useLocalStorage&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;user&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;So in this case we don’t have multiple properties like state, getters, and actions, we just have one function and it has to create reactive objects if you want a state and return them, and it’s going to have computed for getters and functions for actions.&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;useAuthStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auth&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="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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useLocalStorage&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;isLoggedIn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;logout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&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;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;logout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isLoggedIn&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;In the end, you return anything you want to expose and you can keep anything you want to keep private.&lt;/p&gt;

&lt;p&gt;Because we have just one function that defines everything, we can not just not call it! We have to call it both on the server and the client. We need to hint to Pinia that e.g. &lt;code&gt;useLocalStorage&lt;/code&gt; shouldn’t be hydrated.&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;defineStore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;skipHydrate&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;pinia&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;useAuthStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auth&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="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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;skipHydrate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;useLocalStorage&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;isLoggedIn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;logout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&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;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;logout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isLoggedIn&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 behind the scene is that normally when we’re on the client after the server has rendered the application, the store goes through all the different properties that have been put into the initial state, takes the values from the initial state, and put them into the store state; more exactly into the ref that we return in the function: &lt;code&gt;user.value = pinia.state.value.auth.user // alice&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That ref created by the store is then transferred into the Pinia state so that we have one single source of truth: &lt;code&gt;pinia.state.value.auth.user = user // 1 source of truth&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The thing is with skipHydrate, we are skipping the first line, so the &lt;code&gt;user.value = …&lt;/code&gt; that’s no longer happening.&lt;/p&gt;

&lt;p&gt;We should not use &lt;code&gt;skipHydrate&lt;/code&gt; everywhere. If we look at the &lt;code&gt;useEyeDropper&lt;/code&gt; for 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;defineStore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;skipHydrate&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;pinia&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;useEyeDropper&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;@vueuse/core&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;useColorStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;colors&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="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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;isSupported&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;open&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sRGBHex&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useEyeDropper&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;lastColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sRGBHex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Ref&amp;lt;string&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;open&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Function&lt;/span&gt;
        &lt;span class="nx"&gt;isSupported&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Boolean&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;Among these three, only the &lt;code&gt;lastColor&lt;/code&gt; is going to become a state.&lt;/p&gt;

&lt;p&gt;What is interesting is that we can stack these refs together. So we can pass the sRGBHex&lt;/p&gt;

&lt;p&gt;ref to the local storage.&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;defineStore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;skipHydrate&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;pinia&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;useEyeDropper&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useLocalStorage&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;@vueuse/core&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;useColorStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;colors&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="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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;isSupported&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;open&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sRGBHex&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useEyeDropper&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;lastColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useLocalStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lastColor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sRGBHex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&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;lastColor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Ref&amp;lt;string&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;open&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Function&lt;/span&gt;
        &lt;span class="nx"&gt;isSupported&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Boolean&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;In this scenario, we want to use &lt;code&gt;skipHydrate&lt;/code&gt;, because the &lt;code&gt;useLocalStorage&lt;/code&gt; relies on what the browser is seeing and doesn’t care at all about the server response on the initial value for the &lt;code&gt;lastColor&lt;/code&gt;. If we were using only the &lt;code&gt;useEyeDropper&lt;/code&gt;, wouldn’t need the &lt;code&gt;skipHydrate&lt;/code&gt; because most of the time we don’t care if we hydrate from the server-side response or not, because there is not a new value in the browser context that is interesting for us and that could get overwritten by what the server sent. But if we use the local storage then we need to make sure that the one in the browser prevails and the server one is just ignored.&lt;/p&gt;

&lt;p&gt;So what you need is not to use &lt;code&gt;skipHydrate&lt;/code&gt; on every single ref, just on the ones that you want to avoid setting the value from the initial state, and only on SSR of course.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Options Store
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Can use basic Composition API inside &lt;code&gt;state()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Can only return writable state&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;hydrate()&lt;/code&gt; for composables&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Setup Store
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use any Composable (like in &lt;code&gt;setup()&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Automatically tells apart state from actions from getters&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;skipHydrate()&lt;/code&gt; to ignore values from the server&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  End of the second Talk
&lt;/h2&gt;

&lt;p&gt;I hope you enjoyed this part and it can be as valuable to you as it was to me.&lt;/p&gt;

&lt;p&gt;You can find the next talk about Histoire &lt;a href="https://dev.to/mohsen_vaziri/fast-stories-powered-by-vite-histoire-vue-amsterdam-conference-2022-summary-series-third-talk-543n"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>pinia</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>State of the Vuenion — Vue Amsterdam Conference 2022 Summary series — First Talk</title>
      <dc:creator>Mohsen Vaziri</dc:creator>
      <pubDate>Sat, 18 Jun 2022 14:52:40 +0000</pubDate>
      <link>https://dev.to/mohsen_vaziri/state-of-the-vuenion-vue-amsterdam-conference-2022-summary-series-first-talk-i6b</link>
      <guid>https://dev.to/mohsen_vaziri/state-of-the-vuenion-vue-amsterdam-conference-2022-summary-series-first-talk-i6b</guid>
      <description>&lt;p&gt;Welcome! Happy to see you in the first part of my Vuejs Amsterdam Conference 2022 summary series, in which I share a summary of all the talks with you.&lt;/p&gt;

&lt;p&gt;You can read my JSWorld Conference 2022 Summary series (in four parts) &lt;a href="https://dev.to/mohsen_vaziri/series/18427"&gt;here&lt;/a&gt;, where I summarized all the talks of the first day.&lt;/p&gt;

&lt;h2&gt;
  
  
  (Recurring) Introduction
&lt;/h2&gt;

&lt;p&gt;After two and a half years, JSWorld and Vue Amsterdam Conference were back in Theater Amsterdam between 1 and 3 June, and I had the chance to attend this conference for the first time. I learned many things, met many wonderful people, spoke with great developers, and had a great time. On the first day the JSWorld Conference was held, and on the second and third days, the Vue Amsterdam.&lt;/p&gt;

&lt;p&gt;The conference was full of information with great speakers, each of whom taught me something valuable. They all wanted to share their knowledge and information with other developers. So I thought it would be great if I could continue to share it and help others use it.&lt;/p&gt;

&lt;p&gt;At first, I tried to share a few notes or slides, but I felt it was not good enough, at least not as good as what the speaker shared with me. so I decided to re-watch each speech, dive deeper into them, search, take notes and combine them with their slides and even their exact words in their speech and then share it with you so that what I share with you is at least at the same level as what I learned from them&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;A very important point&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Everything you read during these few articles is the result of the effort and time of the speaker itself,&lt;/strong&gt; and I have only tried to learn them so that I can turn them into these articles. Even &lt;strong&gt;many of the sentences written in these articles are exactly what they said or what they wrote in Slides.&lt;/strong&gt; This means if you learn something new, it is because of their efforts. (So if you see some misinformation blame them, not me, right? xD)&lt;/p&gt;

&lt;p&gt;Last but not least, I may not dig into every technical detail or live codings in some of the speeches. But if you are interested and need more information, let me know and I’ll try to write a more detailed article separately. Also, don’t forget to check out their Twitter/Linkedin.&lt;/p&gt;

&lt;p&gt;Here you can find the program of the conference:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.jsworldconference.com/program"&gt;JSWORLD Conference&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  State of the Vuenion
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://twitter.com/youyuxi"&gt;Evan You&lt;/a&gt; - Creator at Vue.js&lt;/p&gt;

&lt;p&gt;The talk was an overview of the Eco System and all the new things that have been happening. On February 7th, 2022 Vue 3 has become the default version alongside the new Brand new &lt;a href="http://vuejs.org/"&gt;Vuejs.org&lt;/a&gt; Website. &lt;/p&gt;

&lt;p&gt;Evan explains the adoption of Vue3 by the Community, Eco System updates with the Release of Nuxt3 RC since April 21st, Vuetify 3 Beta released on May 19th, and VitePress 1.0 Alpha and the work in progress on Vite 3.0.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=1ntuhMzAzU8&amp;amp;t"&gt;State of the Vuenion 2022 - Evan You&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Vue 3 adoption
&lt;/h2&gt;

&lt;p&gt;Currently, Vue 3 has around 800k weekly npm downloads (measured by npm downloads of @vue/runtime-core), which is +70% since the default version launch, and if we look back one year from now, that's 4x in the past year, and it counts for more than 25% of all Vue downloads and this number will probably get much higher by the end of the year.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ecosystem updates
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Nuxt 3
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://twitter.com/nuxt_js/status/1516888137716449280"&gt;https://twitter.com/nuxt_js/status/1516888137716449280&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nuxt 3 is now in RC. A lot of work went into it and the core will also be working actively with Nuxt 3 to stabilize some of the final pieces such as suspense hopefully in 3.3.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vuetify 3
&lt;/h3&gt;

&lt;p&gt;To a lot of people, Nuxt and Vuetify are two of the major pieces that block them from upgrading from Vue 2 to Vue 3. But now, Vuetify 3 hit beta on May 19th too and that’s good news.&lt;/p&gt;

&lt;h3&gt;
  
  
  VitePress
&lt;/h3&gt;

&lt;p&gt;VitePress has just released 1.0 alpha and has been used in the new Vue documentation.&lt;/p&gt;

&lt;p&gt;They focused more on the lower-level details, but right now they are working on completely overhauling the VitePress default theme. Now it comes with dark mode and has a consistent design language with the official view documentation but with a distinction so that you know this is a VitePress site instead of the actual view documentation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There are some small breaking changes but we are really excited because VitePress has really been proven to be a pleasure to work with when we're working on the official docs and it's super flexible and super powerful as well. We are still debating whether we should officially make it the to replace VuePress, just call the VuePress 3 or maybe it should remain a separate project but the idea is if you're looking for a Vue 3 powered static site generator VitePress will be the official recommendation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Volar
&lt;/h3&gt;

&lt;p&gt;If you're using v3 you probably know Volar which is the new recommended VSCode extension.&lt;/p&gt;

&lt;p&gt;Starting march Vue has been sponsoring Johnson Chu who is the author of Volar, to work full time on improving it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Johnson has been cranking out releases and bug fixes and working on refactoring the internal code base to make it more efficient and even cover more features&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Vite 3.0 (WIP)
&lt;/h3&gt;

&lt;p&gt;Another important piece of the new ecosystem is Vite and the team is working on version 3.&lt;/p&gt;

&lt;p&gt;As you may know, node 12 went end of life, and that was the initial motivator for Vite 3, which drops the support for node 12.&lt;/p&gt;

&lt;p&gt;This is not a big rewrite but it comes with a number of relatively minor breaking changes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We always actively work with all the ecosystem partners who are building higher-level tools on top of Vite to ensure these changes comes with a reasonable amount of changes needed to upgrade.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you’re using just the basic features of Vite you most likely won’t be affected much, also if you’re using a higher-level tool like Nuxt 3 or other frameworks on top of Vite, this upgrade path will probably be more or less transparent for you because the higher-level framework will absorb the underlying changes from Vite.&lt;/p&gt;

&lt;p&gt;But there is still a chance of shipping some potentially breaking changes in return for big benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Moving Vite itself to full ESM&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SSR build defaults to ESM output&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Both of these are also part of our overall efforts to make Vite an important factor in pushing the whole JS ecosystem towards pure ESM. So both of these will hopefully make the whole ecosystem transition process to ESM a bit faster.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Non-blocking dependency discovery + optimization&lt;/p&gt;

&lt;p&gt;One of the reasons Vite can start up so fast despite having huge dependencies is that it scans your code base to look for dependencies and then pre-optimizes them.&lt;/p&gt;

&lt;p&gt;But the initial implementation comes with two limitations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The scan phase can be costly if your codebase is big.&lt;/li&gt;
&lt;li&gt;Sometimes the scan phase will fail to discover dependencies because some of the code may introduce the dependency after it's been transformed by an actual plugin, so it has to wait until the app loads.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In 2.9 they introduced an improvement so that it no longer late discover dependencies and it can be non-blocking so it optimizes as it discovers them.&lt;/p&gt;

&lt;p&gt;In 3.0 it is going to make this whole process seamless: No longer need the scan phase, no more late discovered dependencies.&lt;/p&gt;

&lt;p&gt;Vite will discover dependencies as it serves your modules and it'll automatically wait for everything to be finalized to do one single optimization run.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Esbuild-powered dep optimization for both development server and production builds, More consistent behavior between dev/prod&lt;/p&gt;

&lt;p&gt;For packages that are authored in commonJS, Vite used to use esbuild to process dependencies during development and rollup commonJS plugin to build the application for production, which creates inconsistency between development and production.&lt;/p&gt;

&lt;p&gt;In 3.0 the goal is to eliminate that by using esbuild for both phases to ensure the same outcome, especially for commonJS, and it is expected to land within the next month.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Vue Core
&lt;/h3&gt;

&lt;p&gt;During April and May they spent approximately a whole month on v3 core bug squash, which resulted in massive patch releases (3.2.24~26),  ~70 PRs merges, and ~140 closed issues.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All of this is a preparation for other work that’s paving the road for 3.3 because we want to make sure that we get a good sense of the current outstanding bugs and make sure that we have a stable foundation to build upon for the next generation of new features.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  SFC Playground
&lt;/h3&gt;

&lt;p&gt;SFC Playground has been the recommended way to provide bug reproductions for v3, but there are two categories of bugs that are hard to reproduce in the SFC Playground:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Behavior inconsistency for &lt;code&gt;&amp;lt;script setup&amp;gt;&lt;/code&gt; between production and development mode:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We’ve seen quite a few bugs in this category in the past and most of them cannot be reproduced in the SFC Playground because the SFC Playground was production by default. So we added a toggle so that you can toggle between the prod/dev mode so you can actually show us the behavior inconsistency in the case that it happens.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, SFC Playground now supports switching between prod/dev mode for &lt;code&gt;&amp;lt;script setup&amp;gt;&lt;/code&gt; compilation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SSR hydration mismatch bugs:&lt;/p&gt;

&lt;p&gt;In the past usually, you would have to create a whole repository with the full SSR setup just to show them a simple bug happening.&lt;/p&gt;

&lt;p&gt;But now SFC Playground supports SSR reproductions. That means the whole - Full compile → render → hydrate pipeline running in the browser - pipeline happens entirely in the browser and all you need to do is just toggle a button.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Vue 2.7
&lt;/h2&gt;

&lt;p&gt;Many who are stuck on Vue 2 have been asking about it and it's been delayed for various reasons. But they finally started working on it and made great progress.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scope
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Porting Composition API to become a Built-in for Vue 2 instead of using @vue/composition-api plugin.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can directly do the same &lt;code&gt;import { ref } from ‘vue’&lt;/code&gt; as you would do in Vue 3 and these implementations are also more tightly integrated with Vue 2 reactivity system, so they are more efficient than the plugin version.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;script setup&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;For many people script setup has been essential to use composition API, because it just makes your life so much easier.&lt;br&gt;
1.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If we are porting composition API to Vue 2 then it would make sense to also push setup because it’s such an essential part of the DX.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Improved TypeScript support&lt;/p&gt;

&lt;p&gt;They will not change the current shipped types of Vue 2, especially for Vue extend because they want to retain complete type compatibility for existing Vue 2 projects.&lt;/p&gt;

&lt;p&gt;Instead, they are going to have separate Vue 3 types also shipped in the types but you get them when you use the new &lt;code&gt;defineComponent&lt;/code&gt; API that's available in Vue 3. &lt;code&gt;defineComponent&lt;/code&gt; will also allow you to define components but with the types, that are directly ported back from Vue 3, which makes it easier for you to upgrade to Vue 3 as well and it also makes it easier for Volar to support both Vue 2 and Vue 3 at the same time.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Preparation work
&lt;/h3&gt;

&lt;p&gt;Vue 2 codebase is moved to TypeScript!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is a huge shout-out to Pikax (Carlos) who spearheaded to work, made the huge pr and then also to David Walsh who helped with some cleanup, so i picked up from their work and managed to convert the whole codebase to typescript.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is also now a &lt;code&gt;pnpm&lt;/code&gt; monorepo, with a modernized test setup with Vitest.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tests actually run much faster than Vue 3 now, so i need to really port the Vue 3 test to Vitest as well!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vitest Is a new and fast unit test runner internally powered by Vite and has a fully Jest compatible interface.&lt;/p&gt;

&lt;p&gt;Jest requires everything to have its own Jest version of it which is a painful process to configure with Vue-based setups, but if your project is running on Vite because Vitest is also powered by Vite, it’s going to be a smooth transition because Vitest can directly pick up your Vite configurations and you don’t need to configure it separately.&lt;/p&gt;

&lt;h3&gt;
  
  
  Current state
&lt;/h3&gt;

&lt;p&gt;Composition API is already fully ported with actually named exports and full type support, but with similar restrictions from the &lt;code&gt;@vue/composition-api&lt;/code&gt; plugin.&lt;/p&gt;

&lt;p&gt;Vue 2.7 is currently in the alpha stage and 2.7.0-alpha.4 was released on npm under v2-alpha distribution tag, and they are focused on compatibility and stability testing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Next steps
&lt;/h3&gt;

&lt;p&gt;The next step is to port &lt;code&gt;&amp;lt;script setup&amp;gt; support&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;There is a lot of logic — e.g. &lt;code&gt;@vue/component-compiler-utils&lt;/code&gt; - that is split into separate packages and should move back into the Vue 2 repo similar to how v3 does it which makes it easier to sync changes across the places and keep everything consistent.&lt;/p&gt;

&lt;p&gt;The new single file compiler logic will be exposed as &lt;code&gt;vue/compiler-sfc&lt;/code&gt; the same way as Vue 3. This also means when you upgrade to 2.7 and opt in to the new setup, it will be fully compatible with the existing setups. You can then just remove &lt;code&gt;vue-template-compiler&lt;/code&gt; as a peer dependency and then upgrade to &lt;code&gt;vue-loader 16+&lt;/code&gt;  or just directly use &lt;code&gt;@vitejs/plugin-vue&lt;/code&gt; because the single file component compiler will have the exact same interface as Vue 3.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Our goal is so that once you upgrade to 2.7, you’ll be able to just leverage the latest versions of Vue loader or the Vite plugin Vue for both Vue 2 and Vue 3 so you no longer need to use a separate Vite plugin Vue 2 or you’re stuck on the old version of Vue loader.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It will reach Beta after &lt;code&gt;&amp;lt;script setup&amp;gt;&lt;/code&gt; is ported and the estimated release is the end of June 2022.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implications
&lt;/h3&gt;

&lt;p&gt;2.7 will be the final minor release of Vue 2.x and there will be no new features added to Vue 2.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We will still fix bugs obviously, we'll make sure view 2.7 has a smooth upgrade path.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vue 2 will have 18 months of LTS starting from the release of 2.7 stable. That means Vue will be End Of Life by the end of the year 2023.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We may consider offering extended support on a case-by-case basis so this will likely be a paid service. So if you’re interested, you can register interest at &lt;a href="http://link.vuejs.org/xlts"&gt;link.vuejs.org/xlts&lt;/a&gt;. So we do want to make sure that our main bandwidth is invested in Vue 3 and into the future but also understand that some of Vue 2 users may have reasons to have to stay on Vue 2 for longer than expected so we want to make sure there is a good solution for users in that scenario.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Vue 3.3
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Major planned features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Stabilize Suspense&lt;/li&gt;
&lt;li&gt;Stabilize Reactivity Transform&lt;/li&gt;
&lt;li&gt;SSR Improvements

&lt;ul&gt;
&lt;li&gt;Lazy / Conditional hydration for async components&lt;/li&gt;
&lt;li&gt;Improved SSR mismatch warnings&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Support imported types in &lt;code&gt;&amp;lt;script setup&amp;gt;&lt;/code&gt; type-based-macros&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Work on this version starts after the 2.7 stable release and hopefully get it ready by Q3 2022.&lt;/p&gt;

&lt;h2&gt;
  
  
  Experimental new compilation strategy
&lt;/h2&gt;

&lt;p&gt;This is a truly experimental early exploration phase of the feature! So it even may not land!&lt;/p&gt;

&lt;p&gt;The majority of users use Vue through the template and most of us in our day-to-day work interact with Vue through the single-file component format and this is a source format.&lt;/p&gt;

&lt;p&gt;Vue as a framework has the opportunity to compile the file into vanilla JavaScript and CSS, and this step allows Vue to be a super compiler-oriented framework.&lt;/p&gt;

&lt;p&gt;This new compilation strategy is inspired by solid.js. Instead of compiling templates into Virtual DOM render functions, it compiles them into imperative DOM initialization and reactive binding setup code.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// &amp;lt;script setup&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;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&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;/code&gt;&lt;/pre&gt;

&lt;/div&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;template&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;button&lt;/span&gt;
            &lt;span class="na"&gt;:id=&lt;/span&gt;&lt;span class="s"&gt;"`foo-${count}`"&lt;/span&gt;
            &lt;span class="na"&gt;:class=&lt;/span&gt;&lt;span class="s"&gt;"{ red: count % 2 }"&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;"count++"&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ count }}&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This button contains several bindings.&lt;/p&gt;

&lt;p&gt;The output code will look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&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;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;effect&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setClass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setAttr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setText&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/vapor&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;t0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&amp;lt;div&amp;gt;&amp;lt;button&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="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="nx"&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;t0&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstChild&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;_button_class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;_button_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;_button_text&lt;/span&gt;
    &lt;span class="nx"&gt;effect&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;setClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;_button_class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_button_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;red&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="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;
        &lt;span class="nx"&gt;setAttr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;_button_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_button_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`foo-&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="nx"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;_button_text&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="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;div&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The general idea is instead of generating a virtual DOM representation of the tree first and then walking it to initialize the actual DOM, we will analyze the base HTML structure of the template during compilation time and stringify it into the plain HTML without those bindings, then we initialize them directly using a template clone node which is faster than initializing all these nodes individually and stitch them together. Then we generate imperative code that directly locates the nodes that need bindings. Then we generate code that set up the effect directly by setting up reactive updates for class, attribute bindings, and inner text.&lt;/p&gt;

&lt;p&gt;Some of the benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better v-for performance even without v-memo&lt;/li&gt;
&lt;li&gt;Significantly lower memory usage&lt;/li&gt;
&lt;li&gt;Significantly lighter base runtime size (if fully opt-in)&lt;/li&gt;
&lt;li&gt;Potentially lighter component abstraction cost&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Adoption Strategy:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Opt-in at the component level

&lt;ul&gt;
&lt;li&gt;Embed in the existing Vue 3 virtual DOM-based app&lt;/li&gt;
&lt;li&gt;Fully compatible with existing libraries&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Opt-in at the app level

&lt;ul&gt;
&lt;li&gt;Entirely drops Virtual DOM runtime&lt;/li&gt;
&lt;li&gt;Cannot use Virtual DOM-based components&lt;/li&gt;
&lt;li&gt;Suitable for extremely performance-sensitive use cases&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;This doesn't really change the development aspect of it. The template syntax and the way you write your components will remain exactly the same. This is purely just how the compiler handles the output.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  End of the first Talk
&lt;/h1&gt;

&lt;p&gt;I hope you enjoyed this part and it can be as valuable to you as it was to me.&lt;/p&gt;

&lt;p&gt;You can find the next Talk about Pinia &lt;a href="https://dev.to/mohsen_vaziri/getting-more-out-of-your-pinia-stores-vue-amsterdam-conference-2022-summary-series-second-talk-4n54"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
      <category>vueamsterda</category>
      <category>nuxt</category>
    </item>
    <item>
      <title>JSWorld Conference 2022 Summary - 1 June 2022 - Part IV</title>
      <dc:creator>Mohsen Vaziri</dc:creator>
      <pubDate>Sun, 12 Jun 2022 14:50:47 +0000</pubDate>
      <link>https://dev.to/mohsen_vaziri/jsworld-conference-2022-summary-1-june-2022-part-iv-24p4</link>
      <guid>https://dev.to/mohsen_vaziri/jsworld-conference-2022-summary-1-june-2022-part-iv-24p4</guid>
      <description>&lt;p&gt;Welcome! Happy to see you in the last part of my JSWorld Conference 2022 summary series, in which I share a summary of all the talks with you.&lt;/p&gt;

&lt;p&gt;You can read &lt;a href="https://dev.to/mohsen_vaziri/jsworld-conference-2022-summary-1-june-2022-part-i-3b2m"&gt;the first part here&lt;/a&gt;, &lt;a href="https://dev.to/mohsen_vaziri/jsworld-conference-2022-summary-1-june-2022-part-ii-8o0"&gt;the second part here&lt;/a&gt;, and &lt;a href="https://dev.to/mohsen_vaziri/jsworld-conference-2022-summary-1-june-2022-part-iii-2cfl"&gt;the third part here&lt;/a&gt;, where I summarized the first ten talks of the first day that were about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First Talk: Colin talks about the state of Deno in 2022, compares Deno with Node.js, and gives us a taste of working with Deno.&lt;/li&gt;
&lt;li&gt;Second Talk: Negar talks about how browsers render CSS, and then introduces us to CSS Houdini, which is a set of low-level APIs that exposes parts of the CSS engine.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Third Talk: Dexter goes over his “perfect” stack, using graphQL, SvelteKit, Docker, and Github.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fourth Talk: Gift begins with how servers have been managed in the past, continues with how it got better over time with serverless, and what can we expect with Cloudflare Edge services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fifth Talk: Stacy talks about creating a personal brand (blog), using Angular, TypeScript, and static web apps in Azure, and eating the elephant one bite at a time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sixth Talk: Sendil’s talk is about performance and why it matters. He gives some great tips to improve the performance of your app.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Seventh Talk: Natalia talks about a new provisioning experience in Azure Developer CLI which goes Public preview at end of June.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Eighth Talk: Max shares lessons he learned after dealing for 4 years with Micro-Frontend at DAZN.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ninth Talk: Eleftheria talks about UX and UI from the perspective of both users and developers and why you should care as a developer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tenth Talk: Jemima takes a look at the humble beginnings of JS and how it exploded into the chimaera of frameworks and libraries that we have today&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  (Recurring) Introduction
&lt;/h1&gt;

&lt;p&gt;After two and a half years, JSWorld and Vue Amsterdam Conference were back in Theater Amsterdam between 1 and 3 June, and I had the chance to attend this conference for the first time. I learned many things, met many wonderful people, spoke with great developers, and had a great time. On the first day the JSWorld Conference was held, and on the second and third days, the Vue Amsterdam.&lt;/p&gt;

&lt;p&gt;The conference was full of information with great speakers, each of whom taught me something valuable. They all wanted to share their knowledge and information with other developers. So I thought it would be great if I could continue to share it and help others use it.&lt;/p&gt;

&lt;p&gt;At first, I tried to share a few notes or slides, but I felt it was not good enough, at least not as good as what the speaker shared with me. so I decided to re-watch each speech, dive deeper into them, search, take notes and combine them with their slides and even their exact words in their speech and then share it with you so that what I share with you is at least at the same level as what I learned from them&lt;/p&gt;

&lt;p&gt;Since I’m trying to include all the important points, I have to split each day into three, four, or maybe five parts to prevent the article from getting too long.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;A very important point&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Everything you read during these few articles is the result of the effort and time of the speaker itself,&lt;/strong&gt; and I have only tried to learn them so that I can turn them into these articles. Even &lt;strong&gt;many of the sentences written in these articles are exactly what they said or what they wrote in Slides.&lt;/strong&gt; This means if you learn something new, it is because of their efforts. (So if you see some misinformation blame them, not me, right? xD)&lt;/p&gt;

&lt;p&gt;Last but not least, I don’t dig into every technical detail or live codings in some of the speeches. But if you are interested and need more information, let me know and I’ll try to write a more detailed article separately. Also, don’t forget to check out their Twitter/Linkedin.&lt;/p&gt;

&lt;p&gt;Here you can find the program of the conference:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.jsworldconference.com/program"&gt;JSWORLD Conference&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, let’s start with the last part of the first day.&lt;/p&gt;

&lt;h1&gt;
  
  
  Table of Content
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Storybook embedding: Gert Hengeveld - Principal software engineer at Chromatic&lt;/li&gt;
&lt;li&gt;The hurdles of releasing and maintaining a mobile app: Wim Selles - Lead solution architect at Saucelabs&lt;/li&gt;
&lt;li&gt;SDKs, Relations, love &amp;amp; thunder: Samuel Snopko - head of developer relations at Storyblok&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  TL;DR
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Eleventh Talk: Gert Talk about upcoming Storybook 6.4, 6.5, and 7.0.&lt;/li&gt;
&lt;li&gt;Twelfth Talk: The problems or difficulties that must be overcome to allow our app to move freely to the phones of our end users and give ourselves the necessities to keep this app running.&lt;/li&gt;
&lt;li&gt;Last Talk: This talk is mostly about experience. What is the best developer experience? Are the answers in SDKs, Relations, Love, or Thunder?&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Storybook embedding
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://twitter.com/GHengeveld"&gt;Gert Hengeveld&lt;/a&gt; - Principal software engineer at Chromatic&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Storybook 6.4 will bring interaction testing to Storybook, enabled by CSF 3. In 6.5, we're going all-in on accessibility testing and will enable addon authors to provide additional testing methods. With Storybook 7.0, stories and their components become the source of truth for the entire UI development lifecycle.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Do you remember working like this?
&lt;/h2&gt;

&lt;p&gt;You working on a web app and in order to do that you have to first Spin up the whole platform, Recompile with every change you make, when designers review your stuff 2 weeks later they always find something that you have to tweak or change, and that means you have to rework stuff that’s already shipped.&lt;/p&gt;

&lt;p&gt;But now days Modern UIs are &lt;del&gt;built&lt;/del&gt; assembled from components because for these reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Efficiency:&lt;/strong&gt; Reuse existing components&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speed:&lt;/strong&gt; Parallelize development across people and teams&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quality:&lt;/strong&gt; Verify that UIs work in different scenarios&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintenance:&lt;/strong&gt; Pinpoint bugs at the component level.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s easier to work on isolated components and not have to consider the entire context of a running app. This is where Storybook comes in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Storybook
&lt;/h2&gt;

&lt;p&gt;Storybook is a frontend tool for building UI components faster and easier in isolation. It gives you a catalog of all components in different states, and you can document your component library.&lt;/p&gt;

&lt;p&gt;The general concept in Storybook is a story:&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;Badge&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;./Badge&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// Metadata&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Badge&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// First Story&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Small&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;small&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="c1"&gt;// Second Story&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Large&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;large&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Storybook is framework agnostic, so you can choose your favorite framework. &lt;/p&gt;

&lt;h3&gt;
  
  
  Component variants aka “stories”
&lt;/h3&gt;

&lt;p&gt;What would you define a story for?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Different states:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Loading&lt;/li&gt;
&lt;li&gt;Disabled&lt;/li&gt;
&lt;li&gt;In progress&lt;/li&gt;
&lt;li&gt;Error&lt;/li&gt;
&lt;li&gt;Accepted / denied&lt;/li&gt;
&lt;li&gt;Expanded / collapsed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Edge cases:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Long or short text&lt;/li&gt;
&lt;li&gt;Big or small images&lt;/li&gt;
&lt;li&gt;Extreme numbers&lt;/li&gt;
&lt;li&gt;Missing data&lt;/li&gt;
&lt;li&gt;Special characters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Context:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Signed in / signed out&lt;/li&gt;
&lt;li&gt;Language / location&lt;/li&gt;
&lt;li&gt;Color preference&lt;/li&gt;
&lt;li&gt;A/B test&lt;/li&gt;
&lt;li&gt;Offline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And it gets more complicated because there are countless combinations of these situations.&lt;/p&gt;

&lt;h2&gt;
  
  
  UI Development is teamwork
&lt;/h2&gt;

&lt;p&gt;Sharing is essential in the workflow because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;👩‍🎨 &lt;strong&gt;Designers&lt;/strong&gt; want to make corrections in the right time&lt;/li&gt;
&lt;li&gt;🧐 &lt;strong&gt;QA&lt;/strong&gt; should be part of the development cycle and not after it’s already deployed&lt;/li&gt;
&lt;li&gt;🎯 &lt;strong&gt;Product owners&lt;/strong&gt; want to check deliverables&lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;Everyone&lt;/strong&gt; wants to be aware of new features&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and in Storybook, there are so many features that allow you to share your stories and your components with other people.&lt;/p&gt;

&lt;h3&gt;
  
  
  Publish to the web
&lt;/h3&gt;

&lt;p&gt;Storybook provides &lt;code&gt;npm run build-storybook&lt;/code&gt; command which gives you a statically exported version of your story and you can upload it on Github pages, netlify, or on chromatic, and then you can share a link to that with for example your stakeholders so that they can play around with them and verify that is what they had in mind.&lt;/p&gt;

&lt;p&gt;Chromatic is a service on top of Storybook. You can upload your stories to chromatic and it gives you a library of your components.&lt;/p&gt;

&lt;h3&gt;
  
  
  Design with Figma
&lt;/h3&gt;

&lt;p&gt;There is a Storybook Connect for Figma, in which you can Inspect stories in Figma, Link components to stories, Play with interactive stories in Figma, compare the design with implementation, or inspect the sizing of the component to verify whether or not that is developed pixel perfect or you can use accessibility add-on in Storybook to verify what the component looks like when you have blurred vision or you are color blind.&lt;/p&gt;

&lt;h3&gt;
  
  
  Embed anywhere with oEmbed
&lt;/h3&gt;

&lt;p&gt;You can simply Paste a Storybook URL in Medium or Notion. It Automatically converts them to iframe embed and Dynamically adjusts the height of that iframe.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build your own docs site
&lt;/h2&gt;

&lt;p&gt;It’s more convenient to extract the Docs from Storybook and put them into a custom build website, and that’s Storybook Docs 2.0 (alpha) which allows you to take those MDX pages that you write in Storybook and throw them into your custom Website.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Testing UI code is really hard&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Components break in unexpected places, Testing all scenarios is a lot of work, and Reproducing a specific state is tricky. On the other hand, customers have high expectations these days because they are used to the way that Apple builds their software which always works the same way.&lt;/p&gt;

&lt;p&gt;Testing is crucial if you are building software that needs to be reliable and always works.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interactive stories
&lt;/h3&gt;

&lt;p&gt;It was a top request from the community and what it allows you to do is to Define a &lt;code&gt;play&lt;/code&gt; function on your story, which is a function that gets executed as soon as stories run on your browser and you can use that to build Stories for complex components &amp;amp; pages.&lt;/p&gt;

&lt;p&gt;You can now Simulate user behavior in the browser. That is Powered by Testing Library and they didn’t reinvent the wheel.&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;whithin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;userEvent&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;@storybook/testing-library&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;SearchForm&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;./SearchForm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SearchForm&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Submitted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Play function&lt;/span&gt;
    &lt;span class="na"&gt;play&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="nx"&gt;canvasElement&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;canvas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;within&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canvasElement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Simulated events &lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;userEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;searchbox&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;query&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;userEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Search&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is familiar to people written end-to-end tests and integration tests in the past with other tools, but it’s now possible directly in your Storybook as you are working on your stories.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interaction testing
&lt;/h3&gt;

&lt;p&gt;This gives you Assertions powered by Jest and gives you an In-browser debugger. They also built a Node.js test runner so that we can run all of those tests in one go in a headless browser. And when something went wrong, Storybook can give you a URL which you can click, and it opens up your Storybook exactly at that state and then you can check and figure out what was wrong.&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;expect&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;@storybook/jest&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;whithin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;userEvent&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;@storybook/testing-library&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;SearchForm&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;./SearchForm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SearchForm&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Submitted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Play function&lt;/span&gt;
    &lt;span class="na"&gt;play&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="nx"&gt;canvasElement&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;canvas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;within&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canvasElement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Simulated events &lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;userEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;searchbox&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;query&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;userEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Search&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;

        &lt;span class="c1"&gt;// Assertion | Automatic spy on actions&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;query&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All of this is possible in Storybook 6.5.&lt;/p&gt;




&lt;h1&gt;
  
  
  The hurdles of releasing and maintaining a mobile app
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://twitter.com/wswebcreation"&gt;Wim Selles&lt;/a&gt; - Lead solution architect at saucelabs&lt;/p&gt;

&lt;p&gt;Building a mobile app nowadays is pretty easy. If you have some JavaScript/HTML/CSS skills you can use technologies like Ionic, NativeScript, or React Native to release your first app to the App Stores. Building your app might seem easy but releasing and maintaining your app when it’s in production can be difficult. During this talk, Wim will walk us through most of the hurdles of releasing and maintaining a Mobile app in production.&lt;/p&gt;

&lt;p&gt;According to Wim himself, the actual title that he chose was “The problems or difficulties that must be overcome to allow our app to move freely to the phones of our end users and give ourselves the necessities to keep this app running.” but it was too long!&lt;/p&gt;

&lt;p&gt;Imagine a situation where you want to build your own app and release it in stores, and to do so, you need to start with an idea.&lt;/p&gt;

&lt;p&gt;Then you need some skills. You are maybe a master in HTML, CSS, and JavaScript/TypeScript, but to develop an app and publish it in app stores you need to have some ios skills (Swift) and android skills (Java/Kotlin). But maybe it’s easier for Web developers to work with tools like React Native, NativeScript, and Ionic.&lt;/p&gt;

&lt;p&gt;So, now grab your Coffee and your mac - if you wanna develop something for iOS you need to have a mac - and open up your favorite IDE!&lt;/p&gt;

&lt;p&gt;Based on tools of your choice like React Native or the other tools mentioned, Start reading Docs, and you’ll see that you need some extra tools. For example, you need Xcode for iOS or Android Studio for android.&lt;/p&gt;

&lt;p&gt;Depending on the type of framework that you selected, you might have a challenge, and the only thing you need to do is use your best friend, Google.&lt;/p&gt;

&lt;p&gt;A couple of days later, when you built your first screens, you tested your app manually on emulators, you maybe want to test it on your real device. On Android, you need to do some signings and when you got your key, you can push an android application to your android phone. But when you start with apple, the first thing you need to do is use your credit card! You need to have a membership and there are two types of them. There is a free one but you can not push your app into the store. There is a default option that costs you 99$ but then you have the option to push your application to your own phone but also in the end into the app store so that you make some money from your app, but remember, They will still take 30%.&lt;/p&gt;

&lt;p&gt;There is one thing that you need to be aware of. If you start with the developer certificate, there is a limitation on the number of friends that you can invite to push the application to their phones, especially iOS phones. Apple can also make it a little bit easier for you as long as you pay 299$ and you will get the enterprise certificate.&lt;/p&gt;

&lt;p&gt;Building your app — which is better, cooler, and faster with m1 macs — and deploying it is so slow in comparison to the web.&lt;/p&gt;

&lt;p&gt;In addition to that, you need to start testing your app with unit tests and UI tests. But when you start to run your test cases and again compare that to what you are used to, you’ll see that it’s much slower.&lt;/p&gt;

&lt;p&gt;Now, maybe it’s time to push your app to the app store. Android would be the easier one, but for that, we also need to use our credit card and pay 25$ to be able to push our app into the store. But when you are then looking to the apple or the android app stores, you’ll see that you need to wait for a review, which will take between 1 and 7 days. The other problem is, that after a couple of days you may receive an email that tells you: “Your application has been rejected” maybe because you forgot to provide credentials or another reason. Even after acceptance it can take up to 1 day before the app or your update is in the stores, and it will be the same for every release!&lt;/p&gt;

&lt;p&gt;After a while, and after those hard days and so much waiting, you’ll get your first review from a user, a 1.0 Star review!&lt;/p&gt;

&lt;p&gt;Why this story?&lt;/p&gt;

&lt;p&gt;These are the things that could happen if you compare this with your web app experiences.&lt;/p&gt;

&lt;p&gt;Let's take a look at Software development cycles and compare each step for web applications and hybrid/native applications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3_TljJp2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z4ncieyduqejlh5plzlj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3_TljJp2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z4ncieyduqejlh5plzlj.png" alt="Image description" width="880" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why is it hard you may ask? If we’re talking about mobile, first thing is that we could have 20 different versions out there on the phones of our end-users, especially if we do not implement a proper way to do some version management, and unlike with web apps, a mobile native app can’t be reverted/removed from a user’s phone. This can result in having more business impact when a Native app contains bugs.&lt;/p&gt;

&lt;p&gt;Secondly Mobile is remote by default, meaning an issue with your app is always happening somewhere else, not at your desk or your screen. it happens in the hand of a person whom you cannot easily communicate with to understand why and how the issue happened.&lt;/p&gt;

&lt;p&gt;Last but not least, fragmented market. There is a massive variety of android and ios devices across hardware and software configurations, different levels of os versions, and locals. and this is before we get to the mobile device itself that needs reception, wifi, battery, and more.&lt;/p&gt;

&lt;p&gt;If we go back to those pain points, the first thing that we should be aware of is Deploy. If we want to release something quickly, we are limited here and can not roll back. You can not fix something fast in production. it will take time and that time will annoy your customer.&lt;/p&gt;

&lt;p&gt;Also, you need to focus on getting the right feedback from the devices. If you know what happens and what your customers doing, it could help you to replicate what was causing that issue.&lt;/p&gt;

&lt;p&gt;Next, do not forget to test properly. Do not test only the web content in the case of hybrid. Your user is using his fingers. he is not using JavaScript executors to scroll something into the view, no, we are all swiping through our apps. test that, manually or automated.&lt;/p&gt;

&lt;p&gt;And last but not least in all three parts of this process the debugging information is important. If you already have the right debugger in your test build, you might be able to retrieve information that could be valuable for you before releasing it to the stores.&lt;/p&gt;




&lt;h1&gt;
  
  
  SDKs, Relations, love &amp;amp; thunder
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://twitter.com/samuelsnopko"&gt;Samuel Snopko&lt;/a&gt; - head of developer relations at Storyblok&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The time flies fast. We spent more than the last two years in the online bubble. Our work and life merged slowly together. We don't commute, and we are so much more effective! But are we? Did we change? Let's stop for a second. Let's put our heads together. Let's question our creativity and productivity. What is the best developer experience? Are the answers in SDKs, Relations, Love, or Thunder?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  SDKs
&lt;/h2&gt;

&lt;p&gt;This talk is mostly about the experience, and about having a good developer experience to enhance the final user experience.&lt;/p&gt;

&lt;p&gt;If you work in an agency, stakeholders, clients, salespersons, and managers are asking not to create the best backend experience, but to create something for customers that can quickly use, something powerful which will make them better sales, better search optimization ratings, better accessibility and which will look cool. To do that, we as developers need one thing, and that’s time.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We spend most of our time usually on the monolithic CMSs and building and shaping them to the state that we can achieve some cool new frontend stuff because they are not ready. SDKs are here to save you time, and to use them to build a better user experience at the end.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With better SDKs → you as a developer have more time → to build a better app.&lt;/p&gt;

&lt;h2&gt;
  
  
  (Developer) Relations
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Developer relations, which i’m currently head of, is not about developers, it’s about building the relations between all the people.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You need relations because you can not scale your knowledge in every aspect of something. On the other hand, relations are like a guide on your journey and will help you to build better products. Those relations will shape your future of you.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I can backtrace my relations and go to my high school.&lt;br&gt;
I had a math teacher who lead me to the point that I started coding.&lt;br&gt;
My first job as a frontend developer where I met someone and he opened for me the word of CSS and HTML and he showed me some magazines and books and conferences where I got all the inspiration. where then I made some other relations with others who show me the beauty of HTML and CSS. I really loved what I was doing and that’s also the reason why I headed to Vue and then Nuxt.&lt;br&gt;
And then after the next, I met the CEO of Storyblok, and that's the reason why I’m here as head of developer relations and speaking right now.&lt;br&gt;
If you think about it, it's only one person and one relation that I was building that could change the directions that I was going.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So relations are important because your success depends on them, and not only it can help you to succeed, it can save you when you have some problems, and not only the people from your bubble or your team but also the people from other teams, from the community and ambassadors.&lt;/p&gt;

&lt;p&gt;When we have different views on the same topic, we can inspire each other.&lt;/p&gt;

&lt;p&gt;We all need to practice it and it takes time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creativity
&lt;/h3&gt;

&lt;p&gt;Those relations will also inspire you and give you the creative boost, the boost that we can not get if we are sitting alone in the room and just coding all the time.&lt;/p&gt;

&lt;p&gt;On the other hand, you need to get bored and then get rest to let the creativity take over.&lt;/p&gt;

&lt;p&gt;Next time when you face a bug, don’t drink the 20th cup of coffee and try to work 12 hours on it, just do something else or take a rest or go for a walk so that your brain has time to think and you will come up with the solution more easily.&lt;/p&gt;

&lt;h2&gt;
  
  
  Love
&lt;/h2&gt;

&lt;p&gt;Love what you do, your community, and your time. if you don’t like it it doesn’t matter how much money you make.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thunder
&lt;/h2&gt;

&lt;p&gt;Struggles are good. We have different opinions, but the point is don’t take them personally.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There will be always some decisions that you don’t like, and there will be also some decisions that the community doesn’t like. But it’s not personal, it’s not about us. It’s because we all want to move to the next level and make it better.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Last but not least, we all need to learn to say sorry.&lt;/p&gt;




&lt;h1&gt;
  
  
  End of Part IV
&lt;/h1&gt;

&lt;p&gt;This is the end of my JSWorld Conference summary series. Thank you for coming so far, I hope you enjoyed the journey and it can be as valuable to you as it was to me.&lt;/p&gt;

&lt;p&gt;You can read the previous parts here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/mohsen_vaziri/jsworld-conference-2022-summary-1-june-2022-part-i-3b2m"&gt;Part I&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mohsen_vaziri/jsworld-conference-2022-summary-1-june-2022-part-ii-8o0"&gt;Part II&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mohsen_vaziri/jsworld-conference-2022-summary-1-june-2022-part-iii-2cfl"&gt;Part III&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Over the next few days, I’ll do the same for Vue Amsterdam Conference which was held on 2. and 3. June right after JSWorld Conference. Stay tuned…&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>jsworld</category>
      <category>storybook</category>
    </item>
  </channel>
</rss>
