<?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: Jesus Guerrero</title>
    <description>The latest articles on DEV Community by Jesus Guerrero (@jesusantguerrero).</description>
    <link>https://dev.to/jesusantguerrero</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%2F35933%2Febf222b3-6dba-4af6-8404-c6c7dc09972e.jpeg</url>
      <title>DEV Community: Jesus Guerrero</title>
      <link>https://dev.to/jesusantguerrero</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jesusantguerrero"/>
    <language>en</language>
    <item>
      <title>Introducing NeatCoach.ai: A running Plan Generator</title>
      <dc:creator>Jesus Guerrero</dc:creator>
      <pubDate>Sat, 13 Apr 2024 11:59:55 +0000</pubDate>
      <link>https://dev.to/jesusantguerrero/running-plan-generator-35fg</link>
      <guid>https://dev.to/jesusantguerrero/running-plan-generator-35fg</guid>
      <description>&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%2Fqjb6vbxshilb9kyj3d1s.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%2Fqjb6vbxshilb9kyj3d1s.png" alt="NeatCoach" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/devteam/join-us-for-the-cloudflare-ai-challenge-3000-in-prizes-5f99"&gt;Cloudflare AI Challenge&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;It is a smart running coach. It will take a distance and minutes and Build well structured a training plan to run the entered distance in the desired minutes by the end of the last week of the training plan. &lt;/p&gt;

&lt;p&gt;It will include speed work, tempo runs, and long runs in the plan as suggested by experts.&lt;/p&gt;

&lt;p&gt;Additionally, you can save a plan and update your progress on them&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://neatcoach.pages.dev/"&gt;https://neatcoach.pages.dev/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/jesusantguerrero/running-coach"&gt;https://github.com/jesusantguerrero/running-coach&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Journey
&lt;/h2&gt;

&lt;p&gt;One of my main hobbies is running, I've been training and participating in local 5k races for a couple of years now and I am always looking for training plans to improve my record.&lt;/p&gt;

&lt;p&gt;I went through the documentation on workers and pages and followed the instructions to do the project, which was pretty straightforward.&lt;/p&gt;

&lt;p&gt;I went to the &lt;a href="https://playground.ai.cloudflare.com/"&gt;Model playground&lt;/a&gt; to test and modify the prompt until I got the output structure I had in mind.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What model do I use?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@cf/meta/llama-2-7b-chat-int8&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I learned?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To create Cloudflare Pages and Workers and to add bindings.&lt;/li&gt;
&lt;li&gt;Even though I just used one I explored multiple models and tried its capabilities as well as how to use @cloudflare/ai package&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What's next?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allow users to store plans online using a DB&lt;/li&gt;
&lt;li&gt;Train the AI to obtain better plans and take more user inputs like the current pace.&lt;/li&gt;
&lt;li&gt;Add more widgets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading and have a nice day.&lt;/p&gt;

</description>
      <category>cloudflarechallenge</category>
      <category>devchallenge</category>
      <category>ai</category>
      <category>vue</category>
    </item>
    <item>
      <title>App structure for big Vue projects</title>
      <dc:creator>Jesus Guerrero</dc:creator>
      <pubDate>Fri, 09 Feb 2024 09:29:18 +0000</pubDate>
      <link>https://dev.to/jesusantguerrero/app-structure-for-vue-projects-2pbf</link>
      <guid>https://dev.to/jesusantguerrero/app-structure-for-vue-projects-2pbf</guid>
      <description>&lt;p&gt;Choosing the right folder structure for a middle-size or big vue application might be intimidating and it's even more so when there are not many suggestions about the topic.&lt;/p&gt;

&lt;p&gt;From 2017 to the moment of writing this post, I've been working on Vue applications for years from medium to large, established apps migrating to Vue to projects at the start of the process. From Nuxt, Laravel, and Vue SPA; here I will try my best to describe what I think has been the more intuitive easy to work and maintain folder structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  The alternatives
&lt;/h2&gt;

&lt;p&gt;First I want to talk about the alternatives considered. &lt;/p&gt;

&lt;h3&gt;
  
  
  Atomic Design
&lt;/h3&gt;

&lt;p&gt;This is a very complete structure to define your building blocks according to their complexity, size, and how they interact with each other taking inspiration from one of the most well-structured systems the building blocks that compose our body&lt;/p&gt;

&lt;p&gt;It is organized as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Atoms&lt;/li&gt;
&lt;li&gt;Molecules&lt;/li&gt;
&lt;li&gt;Organisms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those will help us to aisle functionality, making portable and reusable components even easier to unit test.&lt;/p&gt;

&lt;p&gt;Then we used to group those organisms in &lt;strong&gt;templates&lt;/strong&gt; to give them context and form in a layout and pages that are the single entry point of the content we show to our users.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Atoms&lt;/li&gt;
&lt;li&gt;Molecules&lt;/li&gt;
&lt;li&gt;Organisms&lt;/li&gt;
&lt;li&gt;Templates&lt;/li&gt;
&lt;li&gt;Pages
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|_atoms/
   |__Input.vue
   |__Button.vue
   |__Label.vue
|_molecules
   |__FieldGroup.vue
|__organisms
   |__ContactForm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Benefits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hint of complexity&lt;/strong&gt;&lt;br&gt;
You get a hint about the complexity of your components ahead. just by seeing where the component is placed: atoms are an indicator that the complexity is low and if are placed in organisms it is more complex.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reusability&lt;/strong&gt;&lt;br&gt;
As you are working with building blocks they are like Legos that you can move around atoms can be part of many molecules and organisms&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Testability&lt;/strong&gt;&lt;br&gt;
As components tend to be smaller and only do in isolation &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Perfect match with design systems&lt;/strong&gt;&lt;br&gt;
If you are starting an application from 0 and need to build a consistent design system this is almost a no-brainer &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt; When applied directly in an application structure you'll feel your components are all over the place.&lt;/li&gt;
&lt;li&gt;If an atom is just used by one molecule or single organism you can't group them by context&lt;/li&gt;
&lt;li&gt;Business logic &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In my experience, we can get the most from Atomic Design when we are building a component library/Design System that will be the foundation of our system: Buttons, Input, Input groups, Form Wizards, SearchBars, Selectors, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Chosen One
&lt;/h2&gt;

&lt;p&gt;When you are building an application you need as much context as possible in your project in the components that handle the business logic. For example, if I have a budget&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|_Budget/
   |__Budget.vue
   |__BudgetCategory.vue
   |__BudgetCategoryItem.vue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The dev experience could improved greatly when building a new feature or removing or refactoring a component because it has much more context of where is used and its props (BudgetCategoryItem could have a &lt;code&gt;BudgetCategory&lt;/code&gt; prop for example, and not a generic &lt;code&gt;row&lt;/code&gt; prop) en what domain dominio y and which is its closest parent component.&lt;/p&gt;

&lt;h2&gt;
  
  
  Proposed structure:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|__ assets
|__ components/
|__ locales/
|__ plugins
    |__ i18n/index.ts
    |__ auth0/index.ts
    |__ loger/index.ts
    |__ axios/index.ts
|__ config/
|   |__ index.ts
|__ domains/
    |__ [domain]
       |__ api/  
       |__ models/
       |__ enums/
       |__ components/
           |__ RequestModal.vue
       |__ composables/
       |__ tests/unitTest.ts 
|__ pages
|   |__ auth/
|       |__ Partials/
|           |__ AuthLayout.vue     
|       |__ AuthSignIn.vue
|       |__ AuthSignUp.vue
|       |__ AuthRecover.vue
|       |__ AuthReset.vue
|   |__ [domain]
|        |__ Partials/
|            |__ SubpageLayout.vue
|            |__ [ComponentUsedOnce].vue
|        |__ subpageList.vue
|        |__ subpageEdit.vue
|        |__ subpagesCreate.vue
|__ router/index.ts     
|__ store/
     |__ Modules/
     |__ index.ts 
|__ utils/   
|__ App.vue
|__ main.ts

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  assets
&lt;/h3&gt;

&lt;p&gt;This directory can contain images, SVG, CSS or SCSS for the application.&lt;/p&gt;

&lt;h3&gt;
  
  
  components
&lt;/h3&gt;

&lt;p&gt;This component holds all the shared components of the application and they can be used in any part of the system.&lt;/p&gt;

&lt;h3&gt;
  
  
  config
&lt;/h3&gt;

&lt;p&gt;Access to env variables with &lt;code&gt;import.env.VITE_VARIABLE_NAME&lt;/code&gt; across our app loads too much dependency on the bundler to centralize all this in a single place and give us some good ts support and add default values.  &lt;/p&gt;

&lt;p&gt;In one of my projects, it looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;``// config/index.ts 
interface AppConfig {
    FIREBASE_API_KEY: string;
    FIREBASE_PROJECT_ID: string;
    FIREBASE_APP_ID: string;
    FIREBASE_SENDER_ID: string;
    PUSH_PK: string;
    MEASUREMENT_ID: string;
    GOOGLE_APP_KEY: string;
    GOOGLE_APP_CLIENT: string;
    FIREBASE_VAPID_KEY: string;
    IS_DEMO: boolean;
}

const isDemo = import.meta.env?.VITE_APP_DEMO

export const config: AppConfig = {
    FIREBASE_API_KEY: import.meta.env.VITE_FIREBASE_APP_KEY,
    FIREBASE_PROJECT_ID: import.meta.env.VITE_FIREBASE_PROJECT_ID,
    FIREBASE_APP_ID: import.meta.env.VITE_FIREBASE_APP_ID,
    FIREBASE_SENDER_ID: import.meta.env.VITE_FIREBASE_SENDER_ID,
    PUSH_PK: import.meta.env.VITE_PUSH_PK,
    MEASUREMENT_ID: import.meta.env.VITE_MEASUREMENT_ID,
    GOOGLE_APP_KEY: import.meta.env.VITE_GOOGLE_APP_KEY,
    GOOGLE_APP_CLIENT: import.meta.env.VITE_GOOGLE_CLIENT_ID,
    FIREBASE_VAPID_KEY: import.meta.env.VITE_FIREBASE_VAPID_KEY,
    IS_DEMO: Boolean(isDemo) &amp;amp;&amp;amp; isDemo !== 'false'
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  domains
&lt;/h3&gt;

&lt;p&gt;Contains the business logic of the application grouped by domain (remember DDD?) and each domain will have the sections: api, models, components, composables, unit tests&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Subfolders&lt;/strong&gt;&lt;/em&gt;&lt;strong&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;api&lt;/strong&gt;: contains all the API calls of the application as endpoints are in a central place we change once if it used in different parts of the app&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;models&lt;/strong&gt;: Contains all the interfaces and types of the domain&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;components&lt;/strong&gt;: Contains all the domain-related components&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;composables&lt;/strong&gt;: Our domain-related vue composables &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;tests&lt;/strong&gt;: Our unit tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pages
&lt;/h3&gt;

&lt;p&gt;These components would be used only by the router and would make the main call to the endpoint, permissions (ACL), and also group different domain controllers or partials.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Subfolders&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Partials&lt;/strong&gt;: Partials are the only directory allowed on pages. They are only used by their respective pages &lt;code&gt;BudgetSectionTemplate.vue&lt;/code&gt; think about them as templates or layouts.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Plugins
&lt;/h3&gt;

&lt;p&gt;Third-party services that you can change like eg. Auth0, Axios, i18n&lt;/p&gt;

&lt;h2&gt;
  
  
  Trade-offs
&lt;/h2&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Provide context about business logic/business domain in the application. It would benefit onboarding new devs to the code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As the code is grouped by domains you can extract functionality easily to make a library if it's required for another project.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Nested folders&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Elements could have more than one domain&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Solving conflict points:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;How to avoid over-nested components?&lt;/strong&gt; Sometimes we tend to group subcomponents by their technical connotation eg.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Components 
   |__ Notifications 
      |__ NotificationCard 
      |__ NotificationTypes/ 
         |__ TaskApproved 
         |__ TaskRejected
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An unnecessary nesting could be avoided by naming the component with the domain in front or creating another domain.&lt;/p&gt;

&lt;p&gt;Eg.1&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Components 
   |__ Notifications 
   |__ NotificationCard 
   |__ NotificationTypeTaskApproved 
   |__ NotificationTypeTaskRejected
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eg. 2&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Components 
   |__ Notifications 
      |__ NotificationCard 
      |__ // ...more components 
   |__ NotificationTypes 
      |_ NotificationTypeTaskApproved 
      |_ NotificationTypeTaskRejected
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;How to deal with a component that seems to have multiple domains?&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;Sometimes a domain may cross with another for example widgets that are shown in the dashboard, should be put in a dashboard domain or its domain (Projects/ Tasks/ Tracks).  &lt;/p&gt;

&lt;p&gt;In this case we should analize the composition of the component and the requirements In this case the widgets are only used in the dashboard and if we go to its composition and props like &lt;code&gt;title&lt;/code&gt; &lt;code&gt;graphType&lt;/code&gt;and &lt;code&gt;data&lt;/code&gt; all are the same in structure. Then we can conclude that each widget can be safely placed in the &lt;code&gt;Dashboard&lt;/code&gt; domain.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>frontend</category>
      <category>vue</category>
    </item>
    <item>
      <title>Deploying and hosting Full-Stack Laravel apps</title>
      <dc:creator>Jesus Guerrero</dc:creator>
      <pubDate>Mon, 05 Dec 2022 21:04:55 +0000</pubDate>
      <link>https://dev.to/jesusantguerrero/deploying-and-hosting-full-stack-laravel-apps-1673</link>
      <guid>https://dev.to/jesusantguerrero/deploying-and-hosting-full-stack-laravel-apps-1673</guid>
      <description>&lt;p&gt;In today's development world is easier than ever to deploy your projects online with minimal configuration, with frontend and JAM Stack/node powered apps there are a lot of good options: Vercel, Netlify, GitHub Pages, Gitlab Pages, Firebase Hosting. &lt;/p&gt;

&lt;p&gt;Unfortunately for modern php/Laravel powered apps with Vue/React frontend there's no too many with minimal configuration with the quality of the options mentioned above out of &lt;a href="https://www.heroku.com/"&gt;Heroku&lt;/a&gt; before the change of its terms and I don't find a good one-to-one replacement for it.&lt;/p&gt;

&lt;p&gt;Here I want to share my journey replicate a workflow close to the Heroku experience with less than 10 dollars/month.&lt;/p&gt;

&lt;h2&gt;
  
  
  The needs
&lt;/h2&gt;

&lt;p&gt;I am talking about a semi-production ready app so what are our checklist&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Separated &lt;code&gt;landing page&lt;/code&gt; from the app. we don't want app errors affecting our marketing / guides pages neither slowing them down and want to implement SEO that probably our app itself doesn't need, because the routes are guarded.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;Main app&lt;/code&gt; with Laravel/Jetstream and all resources we need for it (Database, cron tabs, redis)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A &lt;code&gt;Database Manager&lt;/code&gt; to quick review the database if we are far from our computer and we need to manage the data online&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ownership, we don't need to pay extra money just to have a basic functionality we would like (now everything is a plugin, DB, Crons, etc...)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Build our frontend and deploy to the server when mergin our branch with master like Heroku and Vercel-like services do it.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;For production app with &amp;gt; 100 paying customers maybe is better option to migrate to something like &lt;a href="https://forge.laravel.com/"&gt;the Laravel services&lt;/a&gt; but for side projects maybe we just need to deploy and to show the app to your friends or get some users and see how it goes spending less as possible.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The solution (first attempt)
&lt;/h2&gt;

&lt;p&gt;In my first attempt I used docker-compose to set up the environment with the services I needed here the most difficult part was serve the landing and app through Nginx as load balancer and its ssl but I found tools that make the task easier.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cloud provider: Digital Ocean&lt;/li&gt;
&lt;li&gt;Apps: Docker, Docker Compose&lt;/li&gt;
&lt;li&gt;Tools: &lt;a href="https://dev.tojrcs/letsencrypt-nginx-proxy-companion"&gt;ssl-companion&lt;/a&gt;, jwilder/nginx-proxy&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Steps
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;On the server:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start a doplet with Digital Ocean (you have to give access to your ssh key when creating).&lt;/li&gt;
&lt;li&gt;Set up your domains in DO.&lt;/li&gt;
&lt;li&gt;Install docker&lt;/li&gt;
&lt;li&gt;Setup a &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-automatic-deployment-with-git-with-a-vps"&gt;git bare repository&lt;/a&gt; on your server to accept git push from your local as you push to Github (later I automized this step with a Laravel package &lt;a href=""&gt;insane/remotr&lt;/a&gt; and just need to set and set the &lt;code&gt;REMOTR_SERVER_IP&lt;/code&gt; and &lt;code&gt;REMOTR_REPO_NAME&lt;/code&gt; in your &lt;code&gt;.env&lt;/code&gt; doc.).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;On local:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify that you can connect to your server via SSH&lt;/li&gt;
&lt;li&gt;Setup a docker-compose.yml for your Laravel project here was mine &lt;a href="https://github.com/jesusantguerrero/atmosphere/blob/master/docker-compose.yml"&gt;Loger's docker-compose&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Add your server URL to git remote.&lt;/li&gt;
&lt;li&gt;git push&lt;/li&gt;
&lt;li&gt;Run your &lt;code&gt;docker compose up&lt;/code&gt; command on the server via SSH and that's it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Maybe there's a shorter way to doit but not at USD 6.00 / Month without cold starts or using other services.&lt;/p&gt;

&lt;h2&gt;
  
  
  My current solution
&lt;/h2&gt;

&lt;p&gt;Docker Compose with php and Laravel wasn't a good option for a $6 Doplet it was slower than my local environment out of the box so I ended up installing the &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-linux-nginx-mysql-php-lemp-stack-on-ubuntu-20-04"&gt;LEMP stack&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;One pain point I faced with the first approach was having to build the assets on my machine or the server it would be easier to manage this with GitHub actions so, I set it up.&lt;/p&gt;

&lt;p&gt;Later I found &lt;a href="https://zellwk.com/blog/github-actions-deploy/"&gt;a tutorial to connect Digital Ocean and GitHub actions&lt;/a&gt; I just needed the SSH key to push from GitHub Action instead of my local as the first approach. So, in every merge to master if the tests are green and after the archives of my frontend code is built a git push to the server is executed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Laravel App Deployment&lt;/span&gt;

  &lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;master"&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;master"&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

  &lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.event_name == 'push' }}&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy&lt;/span&gt;
      &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
      &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
      &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;demo&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SITE_URL }}&lt;/span&gt;
      &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;
          &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install SSH Key&lt;/span&gt;
          &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;shimataro/ssh-key-action@v2&lt;/span&gt;
          &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.DO_DOPLET_SECRET }}&lt;/span&gt;
            &lt;span class="na"&gt;known_hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unnecessary&lt;/span&gt;

       &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Adding Known Hosts&lt;/span&gt;
         &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ssh-keyscan -H ${{ secrets.SSH_HOST }}  &amp;gt;&amp;gt; ~/.ssh/known_hosts&lt;/span&gt;

       &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Download frontend build&lt;/span&gt;
         &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/download-artifact@v3&lt;/span&gt;
         &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;frontend-build&lt;/span&gt;
          &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;public&lt;/span&gt;

       &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Store live name&lt;/span&gt;
         &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;git remote add live ${{ secrets.DO_REPO_URL }}&lt;/span&gt;

       &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy with git&lt;/span&gt;
         &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
           &lt;span class="na"&gt;branch_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;live_digital_ocean&lt;/span&gt;
         &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
           &lt;span class="s"&gt;echo "Deploy to staging server"&lt;/span&gt;
           &lt;span class="s"&gt;git config --global user.email "&amp;lt;&amp;gt;"&lt;/span&gt;
           &lt;span class="s"&gt;git config --global user.name "Action Bot"&lt;/span&gt;
           &lt;span class="s"&gt;git add .&lt;/span&gt;
           &lt;span class="s"&gt;git checkout -b $branch_name&lt;/span&gt;
           &lt;span class="s"&gt;git commit -m "deploy: build"&lt;/span&gt;
           &lt;span class="s"&gt;git push live $branch_name:master -f&lt;/span&gt;
           &lt;span class="s"&gt;echo "deployed to prod-staging"&lt;/span&gt;

       &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Update Composer PHP&lt;/span&gt;
         &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;appleboy/ssh-action@master&lt;/span&gt;
         &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
           &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SSH_HOST }}&lt;/span&gt;
           &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SSH_USER }}&lt;/span&gt;
           &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.DO_DOPLET_SECRET }}&lt;/span&gt;
         &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;cd /var/www/loger.com&lt;/span&gt;
            &lt;span class="s"&gt;composer update --ignore-platform-reqs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;you can check the complete file here: &lt;a href="https://github.com/jesusantguerrero/atmosphere/blob/master/.github/workflows/laravel.yml"&gt;https://github.com/jesusantguerrero/atmosphere/blob/master/.github/workflows/laravel.yml&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Updated stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;IaaS: Digital Ocean Doplet&lt;/li&gt;
&lt;li&gt;Apps: NGINX, MariaDB, PHP 8.1&lt;/li&gt;
&lt;li&gt;Tools: cerbot, GitHub Actions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Steps
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;On the server:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start a Doplet with Digital Ocean (you have to give access to your SSH key when creating).&lt;/li&gt;
&lt;li&gt;Set up your domains in DO.&lt;/li&gt;
&lt;li&gt;Install docker&lt;/li&gt;
&lt;li&gt;Setup a &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-automatic-deployment-with-git-with-a-vps"&gt;git bare repository&lt;/a&gt; on your server to accept git push from your local as you push to GitHub (later I automized this step with a Laravel package &lt;a href=""&gt;insane/remotr&lt;/a&gt; and just need to set and set the &lt;code&gt;REMOTR_SERVER_IP&lt;/code&gt; and &lt;code&gt;REMOTR_REPO_NAME&lt;/code&gt; in your &lt;code&gt;.env&lt;/code&gt; doc.).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;On GitHub:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;setup the SSH secrets that we need for the action:&lt;br&gt;
&lt;code&gt;SITE_URL&lt;/code&gt;&lt;br&gt;
&lt;code&gt;DO_REPO_URL&lt;/code&gt;&lt;br&gt;
&lt;code&gt;SSH_HOST&lt;/code&gt;&lt;br&gt;
&lt;code&gt;SSH_USER&lt;/code&gt;&lt;br&gt;
&lt;code&gt;DO_DOPLET_SECRET&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Define our action &lt;a href="https://github.com/jesusantguerrero/atmosphere/blob/master/.github/workflows/laravel.yml"&gt;Loger's deploy action&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Honorable mentions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fly.io&lt;/li&gt;
&lt;li&gt;Digital Ocean App&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Wrapping up&lt;/p&gt;

&lt;p&gt;To summarize you can replicate the experience with a low cost using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Digital Ocean Doplet&lt;/li&gt;
&lt;li&gt;Create a git bare repository to push your changes with git&lt;/li&gt;
&lt;li&gt;Using Docker or LEMP Stack on the server&lt;/li&gt;
&lt;li&gt;Automate testing, build and deployment via SSH with GitHub actions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you for reading, if you have any questions or want to share a stack the comments are open, as well as my &lt;a href="https://twitter.com/JesusntGuerrero"&gt;Twitter&lt;/a&gt; and &lt;a href="https://github.com/jesusantguerrero"&gt;Github&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>laravel</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Five years into software development</title>
      <dc:creator>Jesus Guerrero</dc:creator>
      <pubDate>Tue, 02 Aug 2022 21:09:19 +0000</pubDate>
      <link>https://dev.to/jesusantguerrero/five-years-into-software-development-2f9p</link>
      <guid>https://dev.to/jesusantguerrero/five-years-into-software-development-2f9p</guid>
      <description>&lt;p&gt;This month of July 2022 marked my first 5 years of professional experience as a software developer, I will be always grateful for doing the thing I started as a hobby in my room back in the day. During that period It has been a lot of learning, some of my beliefs have been reinforced or challenged and others needed to be re-learned to fit into the real world.&lt;/p&gt;

&lt;p&gt;So here I will reflect on the lessons, my reinforced beliefs, and challenges.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Background.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Why software engineering?&lt;/p&gt;

&lt;p&gt;I can say that my life split in two the day I discover how software is made being able to create something from text and dragging components from an editor. I would go to the lab doing the common programs for the class (calculators) and doing my little projects like a clone of the login and home of Facebook in Delphi back in the day.&lt;/p&gt;

&lt;p&gt;From that year until 2017 I was just playing around with languages like C, C++, Java, and C# doing CLI programs for my classes or experiments just as a hobby until I learned decent English and met the programming languages of the web, made my first web application an sold it to a local ISP company.&lt;/p&gt;

&lt;p&gt;My drivers were &lt;strong&gt;curiosity&lt;/strong&gt; and the &lt;strong&gt;creative nature&lt;/strong&gt; of software development but also the fact that I could create things to make other people's jobs easier, we are &lt;strong&gt;the support career by excellence&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Beliefs&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Do Something you like&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;There’s a dilemma I hear constantly about if you need to have passion for your job or give the extra mile. I find more regarding doing something you like for work (if you have the opportunity to do it), as learning and progress will be something that you see as challenges.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Discipline:&lt;/strong&gt; It is easier to keep discipline by doing things you like rather than doing it just for the bag.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better to have rather than 2 days a month:&lt;/strong&gt; If you are just happy on the paydays the other days must be like a prison.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Holistic Approach
&lt;/h3&gt;

&lt;p&gt;Try to see the whole picture, even when you don't have to take part in the whole process to learn how it works. Product Owners, Project Managers, Scrum Masters, Designers, Backend Development, and Frontends whatever the position you are doing try to know the limits, the responsibilities of each other.&lt;/p&gt;

&lt;p&gt;Being concerned about the value that every part of the team brings to the table, the effort makes you don't undervalue the Job of anybody, help where you can, and analyze better some technical details when it includes cross-teams effort.&lt;/p&gt;

&lt;p&gt;Understand the business side of the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges and Lessons
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Beyond code
&lt;/h3&gt;

&lt;p&gt;I am one of those who thinks that not everything that comes to mind needs to be told and it's ok to not have an opinion on everything (unless this is your Job)&lt;/p&gt;

&lt;p&gt;There are a lot of no-code-related things we need to work on and learn&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Communication:&lt;/strong&gt; Be able to communicate effectively with the people involved in the product and clients is a multiplier. The most productive teams I have been on has been the ones that understand that the team is a single unit and we all are pushing to same goal and we need to back each other from the sales team, designers, back and frontend developers to testers.&lt;/p&gt;

&lt;p&gt;Maybe this is one goal of every team but in practice it is a hard one specially when the pressure and deadlines are tight.&lt;/p&gt;

&lt;p&gt;Documenting, Talking about the scope of a ticket between backend and frontend before writing any line of code, having a clear definition of ready before taking any ticket, defining guidelines for the projects, etc. are all good signs of an effective communication. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Processes:&lt;/strong&gt; The value of retrospectives are underestimated sometimes but they are the key to improve the process in each iteration and are a good space to reflect and recognize the accomplishments of previous sprints. yet it seems like the first ceremony of scrum to be sacrificed in projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Business vs Tech:&lt;/strong&gt; At the end of the day we are doing software for people to help them but also to get some revenue in most cases. As software developers, we need to know in what situations.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Talk to buy time and do a better implementation if is a big important feature for the business&lt;/li&gt;
&lt;li&gt;The latest is not better, the best is what gets the job done&lt;/li&gt;
&lt;li&gt;When a business expectation is not realistic and needs to be broken.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Have an opinion but be realistic&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;At the beginning of my career, I used to dislike &lt;strong&gt;code challenges that weren’t a reflection of the day-to-day Job tasks,&lt;/strong&gt; I still kind of dislike them but I am more open and in fact, prefer live coding rather than project assignments (because the latest requires more time and on top of that you have to explain while in the former you can explain and interact with an interviewer right there). I know it is not ideal but is the only tool they have to make sure they are going for the person they will pay.&lt;/p&gt;

&lt;p&gt;I still need to do some improvements in the complex code, and &lt;strong&gt;FAANG-like coding challenges&lt;/strong&gt; as I know I am not in a position of changing a standard you got to play by the rules of the game&lt;/p&gt;

&lt;h3&gt;
  
  
  Keeping feet on the ground
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Under-pressure:&lt;/strong&gt; Software is a demanding field, as we are a support field working with information and giving service to users or working in the next big startups there are always deadlines, sometimes bugs on production, and changing markets. That means that pressure is something that we’ll be dealing with (hopefully not in extreme cases so much) even though the pressure is on the environment to understand the urgency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;100%, not 110%, 150%:&lt;/strong&gt; Time is an asset that we don't recover.  Rest is important, family is important so is important to set healthy limits and enjoy life the way you like. Don’t give your time and effort for free to people that just take but never give&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On trust (everything on paper) &amp;amp; stability:&lt;/strong&gt; In Information security, there’s a say that the most vulnerable point of a system is people because we tend to trust people. In software having things jot down can save you a lot of time and effort. having the client requirements written, on email because words are easy to forget.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The best stability is to be prepared because everything can change and opportunities always come for those who are prepared.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>devjournal</category>
      <category>writing</category>
    </item>
    <item>
      <title>Best stacks to build vue applications</title>
      <dc:creator>Jesus Guerrero</dc:creator>
      <pubDate>Thu, 30 Jun 2022 10:04:32 +0000</pubDate>
      <link>https://dev.to/jesusantguerrero/best-stacks-to-build-vue-applications-2man</link>
      <guid>https://dev.to/jesusantguerrero/best-stacks-to-build-vue-applications-2man</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Vue is one of the most popular frontend frameworks for its easy of use, powerful reactivity and it modular nature what I mean by this is that you can start really small just the core or add router, state management, etc.&lt;/p&gt;

&lt;p&gt;Here will discuss about 4 interesting stacks to build Vue applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Laravel + Inertia.js + Vue.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://laravel.com/"&gt;Laravel&lt;/a&gt; is one of the most complete backend frameworks to ever exist and the ecosystem is very dynamic and rich in terms of packages; from ORM to queues, notification systems, payments with integrations whatever thing you need to build a successful project Laravel has a official support or the community has build a package for it. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://inertiajs.com/"&gt;Inertia.js&lt;/a&gt; allows us to keep our controllers, validators on backend and send props and data to the frontend without the need of initial API calls, manage forms state in with a beautiful and clean API and even a SSR mode to improve the speed of your pages. Inertia serves as a glue between backend and frontend combining the best of Laravel apps and the best of SPA.&lt;/p&gt;

&lt;p&gt;The Laravel team has make our job easier preparing &lt;a href="https://laravel.com/docs/9.x/frontend#inertia-starter-kits"&gt;starter kits&lt;/a&gt; and guess what, there is &lt;a href="https://vitejs.dev/"&gt;vite&lt;/a&gt;⚡support.&lt;/p&gt;

&lt;p&gt;Pros&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mature and battle-tested backend framework&lt;/li&gt;
&lt;li&gt;Let backend manage routing, validations and things like that&lt;/li&gt;
&lt;li&gt;Get the best of SPA and traditional MPA&lt;/li&gt;
&lt;li&gt;Top documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Good hosting/deploy options cost more money than (JAM Stack for example).&lt;/li&gt;
&lt;li&gt;Needs to know two programming languages&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Astro
&lt;/h2&gt;

&lt;p&gt;When I first read about &lt;a href="https://astro.build/"&gt;Astro&lt;/a&gt; I was amazed by the concepts and motivation of the project the concept of island was implemented nicely and ship just the JavaScript that is needed (or none at all) was a good contrast with the trend going on at that point and has inspired other frameworks to go in that direction.&lt;/p&gt;

&lt;p&gt;Astro let you use any frontend framework among Vue, React, Svelte, Preact, Solid, Lit, Alpine to build components and build SSG it is a good option for documentations and personal sites, digital gardens and with great performance out of the box.&lt;/p&gt;

&lt;p&gt;The framework is relatively new reaching the milestone of &lt;a href="https://twitter.com/astrodotbuild/status/1512505545210707973"&gt;v1.0.0 beta&lt;/a&gt; in April  new but its community is growing &lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Great performance out of the box.&lt;/li&gt;
&lt;li&gt;Support for the top frontend frameworks.&lt;/li&gt;
&lt;li&gt;Easy to deploy and free hosting options.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;It is new.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://v3.nuxtjs.org/"&gt;Nuxt&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Single Page Applications are good but some projects by their nature require a SEO-friendly approach and additional improvements and app performance and developer experience. &lt;a href="https://v3.nuxtjs.org/"&gt;Nuxt&lt;/a&gt; comes to fill that GAP in the Vue ecosystem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The hybrid Vue framework&lt;/strong&gt; allow us to build production ready apps faster giving us abstractions on things like routing, state management, SSR on top of Vue. The version 3 add support for Vue 3, vite and a better server engine nitro&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provide SSR, SSG perfect for SEO-friendly apps.&lt;/li&gt;
&lt;li&gt;Easy to deploy and free hosting options.&lt;/li&gt;
&lt;li&gt;Vue abstractions like Components auto-import, routing, store.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;By the time of this post Nuxt 3 is in RC.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Vue + BaaS (firebase, Supabase, Amplify, etc)
&lt;/h2&gt;

&lt;p&gt;Something that I really like about this approach is that you need fewer dependencies and that means that when a big upgrade like Vue 3 happens you wouldn't have to wait compatibility from meta-frameworks to migrate, you’ll have more opinions and control of your code this a good option if you don't need SSR, you're app idea is not too complex.&lt;/p&gt;

&lt;p&gt;There are good options for backend as a service like &lt;a href="https://firebase.google.com/"&gt;Firebase&lt;/a&gt;, &lt;a href="https://supabase.com/"&gt;Supabase&lt;/a&gt;, and others that can provide authentication, database, real-time, storage etc. with little code compared to the traditional approach. It is good for proof of concepts, small apps.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;You can have functional apps with less backend code &lt;/li&gt;
&lt;li&gt;Easy to deploy good hosting options&lt;/li&gt;
&lt;li&gt;Good support for different auth providers.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Vendor Locking (unless is opensource like Supabase).&lt;/li&gt;
&lt;li&gt;Maybe not the best option for complex data, apps.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;When it comes to development there is no silver bullet as every case is different and its own world the Vue ecosystem is not an exception, it is in our hands evaluate the trade offs of every case. If we set these stacks where the shine the most I am sure that any project will go in good direction.&lt;/p&gt;

&lt;p&gt;Than you for reading, I hope the article can save you some time if you have any questions or want to share a stack the comments are open, as well as my &lt;a href="https://twitter.com/JesusntGuerrero"&gt;Twitter&lt;/a&gt; and &lt;a href="https://github.com/jesusantguerrero"&gt;Github&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>You shouldn't worry that much about your first programming language</title>
      <dc:creator>Jesus Guerrero</dc:creator>
      <pubDate>Tue, 17 May 2022 13:44:55 +0000</pubDate>
      <link>https://dev.to/jesusantguerrero/you-shouldnt-worry-that-much-about-your-first-programming-language-2o9k</link>
      <guid>https://dev.to/jesusantguerrero/you-shouldnt-worry-that-much-about-your-first-programming-language-2o9k</guid>
      <description>&lt;p&gt;One of the first questions or doubts that comes to mind once you set the goal of becoming a developer is what programming language is good to start.&lt;/p&gt;

&lt;p&gt;In this post I want to cover two points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why you shouldn't care that much about it.&lt;/li&gt;
&lt;li&gt;Tips to identify what can be a good fit for you.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why you shouldn't care that much about it?
&lt;/h3&gt;

&lt;p&gt;The main purpose of developers is to deliver solutions, The nature is to &lt;strong&gt;find and build solutions for problems and make tasks easier for others&lt;/strong&gt;, just look how many apps and software you are using in day to day basis. Because of that one of the main characteristics a developer have to have is good problem solving skills, curiosity and hungry to learn, and then the other part is defining instructions for the computer in a way they can understand to build the solution. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The purpose of developer is to find and build solutions for problems and make tasks easier for others&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To strength the first aspect most universities start with algorithms, and I am not talking about those complex mathematical ones, is sequence of steps to solve a problem using pseudocode in a way to focus in the main concepts: Declare variables and functions, loops, etc.&lt;/p&gt;

&lt;p&gt;Good problem solving skills, the main concepts of programming, use of best practices, design patterns are the key that will help you to understand any language.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pseudocode is a style of algorithm writing that should be adaptable to any programming language. There are no rules to write pseudocode but it should be readable by a programmer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And you might think: "ok, I get it. Anyways I need to learn my first language". Bear with me, let's see some tips to discover that language that you'll fall in love with.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tips to identify what can be a good fit for you
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;All of us had a reason of why we fell in love with programming It could be a game we played, an application we used and wanted extra features, an event we attended whatever. Been aware of that software that attracted you in the first place will give you what field of programming is the one that call your attention: Games, Desktop, Mobile, Web Applications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Look for the top languages used in those categories and research about its strengths, use cases, applications that use them, syntax.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are apps that gamify learning basic concepts of programing languages, one of them is &lt;a href="https://www.sololearn.com/learning"&gt;sololearn&lt;/a&gt; it is a good option to explore, code and get help about certain languages when you are starting and feel like you are playing after that you can go deeper in other platforms.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&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%2Fml1xrku277in597drhj8.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%2Fml1xrku277in597drhj8.png" alt="Image description" width="800" height="655"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you want to learn to start a job, lets say within 6 months or a year a good options is identifying what programming languages are the most requested in Jobs in your country.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Wrapping up
&lt;/h3&gt;

&lt;p&gt;Whatever your first programming language I can tell you &lt;strong&gt;the most important thing is that you learn how to code, best practices, and try to build and build more things&lt;/strong&gt;, because in that way you'll discover more use cases than following tutorials always and bear in mind that after that first language you will be able to pick up a second or third language faster in case you needed.&lt;/p&gt;

&lt;p&gt;I hope this post had been helpful for you, thanks for reading and have a great day.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Firebase: The good, the bad, the awesome.</title>
      <dc:creator>Jesus Guerrero</dc:creator>
      <pubDate>Sat, 09 Apr 2022 21:13:15 +0000</pubDate>
      <link>https://dev.to/jesusantguerrero/firebase-the-good-the-bad-the-awesome-bb1</link>
      <guid>https://dev.to/jesusantguerrero/firebase-the-good-the-bad-the-awesome-bb1</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;One of my dev colleagues said this is the best era to be a frontend developer and this is true. There are technologies out there that empower us to make great applications of any kind; a couple of clicks and we are ready to use them from our front end.&lt;/p&gt;

&lt;p&gt;Today we are going to cover one of these technologies, Firebase.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is firebase?
&lt;/h3&gt;

&lt;p&gt;Firebase is a backend as a service platform backed by Google that provides a set of tools to help developers build, release and monitor web, Android, and IOS apps as well as engage with your users.&lt;/p&gt;

&lt;p&gt;We are talking about Authentication, Database, Storage, Real-Time Database, hosting, and others.&lt;/p&gt;

&lt;h2&gt;
  
  
  My background with firebase
&lt;/h2&gt;

&lt;p&gt;I have built some with applications with firebase but not at its full strength until February when I built &lt;a href="https://freesgen.hashnode.dev/introduction-to-zen" rel="noopener noreferrer"&gt;zen&lt;/a&gt; a productivity app to help myself to focus on my tasks primarily and to participate in the Vercel &amp;amp; Hasnode hackathon. From the launch of Zen to the date of this post I've used like 80/90% of the tools of firebase and here are my pains, the things that have made me fall in love with firebase and the ones that have been a little bit more difficult to digest.&lt;/p&gt;

&lt;p&gt;At the end of this post you will gain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An overview of the most important tools provided by firebase.&lt;/li&gt;
&lt;li&gt;Know scenarios where firebase shines the most.&lt;/li&gt;
&lt;li&gt;Limitations you could find when building apps with firebase.&lt;/li&gt;
&lt;li&gt;Resources that served me to improve my firebase skills.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The good parts.
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Auth
&lt;/h3&gt;

&lt;p&gt;I think almost every developer starts an application with the authentication flow. With firebase, this process is joyful and fast. we have 12 options for sign-in providers from email, google, FB, GitHub to anonymous sessions.&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1621631906917%2FWj_7jGBRF.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1621631906917%2FWj_7jGBRF.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And to enable is just set the credentials and click to enable:&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1621632020472%2FzjCxFdo9V.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1621632020472%2FzjCxFdo9V.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the project, we have access to the methods of auth like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;register&lt;/span&gt; &lt;span class="o"&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;email&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="o"&gt;=&amp;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;firebase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;createUserWithEmailAndPassword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&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="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reason&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;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;login&lt;/span&gt; &lt;span class="o"&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;email&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="o"&gt;=&amp;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;firebase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;signInWithEmailAndPassword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&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="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;reason&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;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&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;And the last step is listen when the state change to set/unset the authenticated user.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

    &lt;span class="nx"&gt;firebase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;onAuthStateChanged&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="p"&gt;...&lt;/span&gt;
            &lt;span class="nx"&gt;firebaseState&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;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;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629727402198%2FBdvkZullj.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629727402198%2FBdvkZullj.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Database.
&lt;/h3&gt;

&lt;p&gt;We have two database options &lt;strong&gt;Firestore&lt;/strong&gt; and &lt;strong&gt;Realtime Database&lt;/strong&gt;; both of which provide built-in real-time features. coming from a MySQL background where you had to implement that functionality with other tools this is mind-blowing and a killer feature by firebase and makes it a go-to option for applications like chats, and collaboration tools.&lt;/p&gt;

&lt;p&gt;Both are No-SQL document-based databases. Firestore is the more powerful providing advanced queries and rules. You can create a collection that contains documents and every document can have subcollections&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629727399796%2Fonorj4ZAu.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629727399796%2Fonorj4ZAu.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It allows setting rules, which are conditions to allow access for collections and documents in your database. Here, for example, we are telling to allow users to create tasks for them and allow delete and update if the user is the owner of the task.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;taskId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;allow&lt;/span&gt; &lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;request&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="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resource&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;user_uid&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;request&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;uid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;allow&lt;/span&gt; &lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;request&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="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;resource&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;user_uid&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;request&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;uid&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;But you can set more advanced rules for example, with Zen I will need a sharing option in version 2.0 where users can let other users see their boards. We saved the collection in &lt;code&gt;documents/shared/$(userUid)/accounts/${taskOwnerId}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The rules below would translate into "If I am authenticated and the task is mine or belongs to a user sharing board with me let me read the task".&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;taskId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;allow&lt;/span&gt; &lt;span class="na"&gt;read&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&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="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;resource&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;user_uid&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;request&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;uid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/databases/&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;documents&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;shared&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&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;uid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;accounts&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resource&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;user_uid&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;
  
  
  Functions
&lt;/h3&gt;

&lt;p&gt;Not everything can run in the frontend, there is sensitive data that requires being managed from a server.&lt;/p&gt;

&lt;p&gt;Cloud Functions are the firebase way to run stuff on the server without the pain of maintaining your own server (A.K.A serverless) they are flexible and complement very well with the other firebase tools. You can trigger a function on user sign-ups with &lt;strong&gt;Auth&lt;/strong&gt;, after write, update, delete a document in &lt;strong&gt;Firestore&lt;/strong&gt;, run scheduled functions in the background, the sky is the limit.&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629805971512%2F6PZhCMyz-.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629805971512%2F6PZhCMyz-.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;They even have *&lt;em&gt;callables *&lt;/em&gt; that are functions you define in your backend and can invoke them from the front end just with the name. no need to install Axios and make a call to an endpoint.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shareMatrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;functions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onCall&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;data&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="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;context&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="c1"&gt;// do stuff with data&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;OK&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;blockquote&gt;
&lt;p&gt;Defining the cloud function in the backend&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="p"&gt;...&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shareMatrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;functions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;httpsCallable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;shareMatrix&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;shareMatrix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;clearForm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;saved&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;formData&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;blockquote&gt;
&lt;p&gt;Invoking the function in the frontend&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Other tools.
&lt;/h3&gt;

&lt;p&gt;Other tools worth mentioning are Hosting, Storage and analytics&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;** Hosting:** Allow to deploy multiple sites in a firebase project with SSL by default. you can set custom domains and restore deployments to previous versions&lt;/li&gt;
&lt;/ul&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630245627318%2FSIclgUcUg.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630245627318%2FSIclgUcUg.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Storage:&lt;/strong&gt; Allow saving files images, videos, audios etc. in the cloud for your firebase projects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;*&lt;em&gt;Analytics: *&lt;/em&gt; Free analytics to track most used features, users retention.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The bad.
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Database:&lt;/strong&gt; 
Working with &lt;strong&gt;relationships in Firestore is a pain&lt;/strong&gt;, if you are working with relational data you can do two things &lt;a href="https://firebase.google.com/docs/database/web/structure-data" rel="noopener noreferrer"&gt;denormalize your data&lt;/a&gt;, in other words, is okay to repeat in order to deliver a document with all the information you need in a single query the recommended way or do multiple queries to obtain your data, which is not recommended for the way Firestore is priced they count reads, writes, and deletes the free limit is good enough but if you app success you can be charged more if you applied a bad structure in your data. &lt;/li&gt;
&lt;/ul&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629808102209%2FsO_9pJ1SC.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1629808102209%2FsO_9pJ1SC.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Vendor lock-in&lt;/strong&gt;: Remember the part &lt;em&gt;Backed by google&lt;/em&gt;? well, firebase has many tools and the most you use the harder is to migrate parts to other platforms you become dependent on Google if they decide to raise their prices tomorrow you don't have an easy path to save your data and restore in another service.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;There's not fixed pricing&lt;/strong&gt;. It is not totally bad because many services work like that today but the fact that you can't predict the cost of your next invoices from an accounting point of view is bad for planning.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When to use firebase
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;When you need fast development it could be a plus, because firebase takes care of the harder parts on Auth, Storage, Hosting, Server, Real-Time, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You need real-time features and your app doesn't need many relations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When you also need a mobile version of your app with android, React Native, for example, I can say from my experience is a smooth transition.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prototype MVP with low-cost solutions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When firebase might not be the best alternative
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Working with complex database relations&lt;/li&gt;
&lt;li&gt;You don't want to be dependant on one vendor&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Firebase can help us develop apps faster with a low cost even in their paid option - needed to use functions-. It's a good option for validating ideas, build small side projects, and if you are like me, having fun trying interesting technologies.&lt;/p&gt;

&lt;p&gt;If you like these features and you can check other alternatives like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://supabase.io/" rel="noopener noreferrer"&gt;Supabase&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/amplify/" rel="noopener noreferrer"&gt;Amplify&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope you find it useful, let me know about any questions you have here or on &lt;a href="https://twitter.com/JesusntGuerrero" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;. thanks for reading and have a nice day.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>firebase</category>
      <category>vue</category>
      <category>webdev</category>
    </item>
    <item>
      <title>From my point of Vue: State management</title>
      <dc:creator>Jesus Guerrero</dc:creator>
      <pubDate>Mon, 07 Mar 2022 14:34:29 +0000</pubDate>
      <link>https://dev.to/jesusantguerrero/from-my-point-of-vue-state-management-apj</link>
      <guid>https://dev.to/jesusantguerrero/from-my-point-of-vue-state-management-apj</guid>
      <description>&lt;p&gt;While working with medium/large sized apps you will find the need to have some data, functionality or logic available globally in a single source of truth because you need them in different components and pages across the app, it could be: user data, settings, permissions, etc. Sounds familiar? We refer to the solutions to address this problem as State Management.&lt;/p&gt;

&lt;p&gt;In this post we are going to review some use cases when we might need a state management solution and the options we have in Vue to work with them.&lt;/p&gt;

&lt;p&gt;Some use cases are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sharing data that are used deeply in components&lt;/li&gt;
&lt;li&gt;Sharing global state&lt;/li&gt;
&lt;li&gt;Working with SSR&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Sharing data that are used deeply in components
&lt;/h3&gt;

&lt;p&gt;Since vue 2 the framework provide an alternative to props to pass down data to a deep child without the need of a state manager library. This is the &lt;strong&gt;provide/inject&lt;/strong&gt; in the composition API those functions are available and ready to share reactivity too.&lt;/p&gt;

&lt;p&gt;We can find an Illustration for the idea in this picture from Vue documentation: &lt;/p&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%2Fjon2uub0102d7ahuijvs.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%2Fjon2uub0102d7ahuijvs.png" alt="provide/inject idea" width="755" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's see how the code will look like for the following use case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We have a &lt;code&gt;main layout&lt;/code&gt; that have a selectedDate and a component &lt;code&gt;WeekContainer&lt;/code&gt; that have the last 7 days rendered as an individual component &lt;code&gt;WeekDay&lt;/code&gt; component, we need the selectedDate data from the parent to see if one of the WeekDays is the selected one.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Components Schema:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  -- Parent [selectedDate]
  --- WeekContainer
  ---- WeekDay [needs selected day]
&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;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="cm"&gt;/** Parent **/&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;provide&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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;selectedDate&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
 &lt;span class="c"&gt;&amp;lt;!--...--&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="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="cm"&gt;/** WeekContainer **/&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;div&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"day in week"&lt;/span&gt; &lt;span class="na"&gt;:day=&lt;/span&gt;&lt;span class="s"&gt;"day"&lt;/span&gt;&lt;span class="nt"&gt;&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="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="cm"&gt;/** WeekDay Component **/&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;computed&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="s2"&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;props&lt;/span&gt; &lt;span class="o"&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;date&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;Date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;required&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selectedDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;selectedDate&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;isSelectedDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;selectedDate&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="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
 &lt;span class="c"&gt;&amp;lt;!--...--&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;&lt;a href="https://freesgen-vue-provide-inject.stackblitz.io//"&gt;Live example&lt;/a&gt;&lt;br&gt;
&lt;a href="https://stackblitz.com/edit/freesgen-vue-provide?file=src/utils.js"&gt;live code&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Sharing global state
&lt;/h3&gt;

&lt;p&gt;The second case is maybe one of the most common, In general if our application requires authentication, permissions and settings eventually we are going to need to have access to these data without the need to make an API call each time we need them.  &lt;/p&gt;

&lt;p&gt;Here we can combine some techniques to avoid an external library with vue 3 and the &lt;a href="https://dev.to/jesusantguerrero/from-my-point-of-vue-composition-api-18de"&gt;Composition Api&lt;/a&gt; we can use an &lt;code&gt;reactive&lt;/code&gt; object to store the data an access to them when we need it. I wrote about this concept previously in &lt;a href="https://dev.to/jesusantguerrero/build-an-authentication-flow-with-auth0-and-vue3-1f3h"&gt;build and auth flow with auth0 and Vue 3&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's see some code:&lt;/p&gt;

&lt;p&gt;Here we are exporting a reactive object with Auth Information&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/** AuthState.js **/&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;reactive&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="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;AuthState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;reactive&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="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;loading&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;isAuthenticated&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;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// settings?&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we can build a function that interacts with our AuthState to set the user in case of login/registration an unset in case of logout.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useAuth&lt;/span&gt; &lt;span class="o"&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
 &lt;span class="c1"&gt;// The implementation will go here&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;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;init&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;Then in the main App.vue we can import our functions to setup the initial state. Then we an import the AuthState anywhere.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="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;useAuth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AuthState&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="s2"&gt;./utils/useAuth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;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;init&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useAuth0&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AuthState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;init&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;div&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;!AuthState.loading&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="nx"&gt;img&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Vue logo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./assets/logo.png&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="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;!AuthState.isAuthenticated&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="nx"&gt;button&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;login()&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;btn btn-primary&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;Login&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;/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;div&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;else&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;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Welcome&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;VueAuth&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;strong&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;AuthState&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;name&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;/strong&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nx"&gt;p&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="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;logout()&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;btn btn-secondary&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;Logout&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;/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="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;div&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;Loading&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="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;p&gt;You can check a complete code applying this technique &lt;a href="https://github.com/jesusantguerrero/vue-auth0"&gt;here&lt;/a&gt; and applied to an app running in the wild &lt;a href="https://github.com/jesusantguerrero/zen/blob/master/src/utils/useFirebase.js"&gt;zen&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Working with SSR
&lt;/h3&gt;

&lt;p&gt;We are heading to our last but not least use case, with Server Side Rendering our app have some special needs so far At this point the minimal requirement is sharing state between the server side generated content and the frontend once is hydrated.&lt;/p&gt;

&lt;p&gt;In that case we can go with a library like &lt;a href="https://pinia.vuejs.org/"&gt;pinia&lt;/a&gt; (the spiritual successor of Vuex🙏🏽). It gives us a SSR compatibility, modular and intuitive design in a light package with devtool support.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Usage:&lt;/strong&gt; Declaring the store&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// stores/counter.js&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="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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useCounterStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&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;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;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="k"&gt;return&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="p"&gt;},&lt;/span&gt;
  &lt;span class="c1"&gt;// could also be defined as&lt;/span&gt;
  &lt;span class="c1"&gt;// state: () =&amp;gt; ({ count: 0 })&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="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&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="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once it is declared you can use it in your components:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useCounterStore&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;@/stores/counter&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="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCounterStore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nx"&gt;counter&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="c1"&gt;// with autocompletion ✨&lt;/span&gt;
    &lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;$patch&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="nx"&gt;counter&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;1&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="c1"&gt;// or using an action instead&lt;/span&gt;
    &lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Wrapping up
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You can handle state management in Vue 3 with &lt;code&gt;provide/inject&lt;/code&gt;, composables or store libraries like &lt;a href="https://pinia.vuejs.org/"&gt;pinia&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;They might help you with these use case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sharing data that are used deeply in components&lt;/li&gt;
&lt;li&gt;Sharing global state&lt;/li&gt;
&lt;li&gt;Working with SSR&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;I hope you find it useful, let me know about any questions you opinions you have &lt;a href="https://twitter.com/JesusntGuerrero"&gt;Twitter&lt;/a&gt; or even share how you handle those use cases in the comment section.&lt;/p&gt;

&lt;p&gt;Thanks for reading and have a nice day.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://vuejs.org/api/composition-api-dependency-injection.html#provide"&gt;docs provide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://vuejs.org/api/composition-api-dependency-injection.html#inject"&gt;docs inject&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackblitz.com/edit/freesgen-vue-provide?file=src/utils.js"&gt;provide/inject example code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>vue</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>From my point of Vue: Vue 3 Ecosystem</title>
      <dc:creator>Jesus Guerrero</dc:creator>
      <pubDate>Mon, 24 Jan 2022 14:52:55 +0000</pubDate>
      <link>https://dev.to/jesusantguerrero/from-my-point-of-vue-vue-3-ecosystem-4ikj</link>
      <guid>https://dev.to/jesusantguerrero/from-my-point-of-vue-vue-3-ecosystem-4ikj</guid>
      <description>&lt;p&gt;Since the release of Vue3 on Sep 18, 2020 the ecosystem of the framework have been in a transition period because even when the core library was ready for production the ecosystem was behind.&lt;/p&gt;

&lt;p&gt;I build a production ready project back in february 2021 with Vue3 and the change to the &lt;a href="https://dev.to/jesusantguerrero/from-my-point-of-vue-composition-api-18de"&gt;composition API&lt;/a&gt; was kind of smooth and you can build strong components abstractions like &lt;a href="https://dev.to/jesusantguerrero/from-my-point-of-vue-headless-components-2403"&gt;headless components&lt;/a&gt;. The libraries, plugins components available were minimal and those available weren't stable which was normal at this point.&lt;/p&gt;

&lt;p&gt;In 2022 the future looks bright and looks like we'll reach the stability, there's a lot of good reactivity libraries, components and ui frameworks that are production ready.&lt;/p&gt;

&lt;p&gt;In this post we are going to take a look at &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The recommendations&lt;/li&gt;
&lt;li&gt;How the ecosystem looks like right now&lt;/li&gt;
&lt;li&gt;What are we missing for stability.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Recommendations
&lt;/h3&gt;

&lt;p&gt;It is good to have multiple options to do tasks but sometimes when we got many options it can get chaotic and spent too much time selecting tools to start a new project, that's why official recommendations are good to set a standard, reduce cognitive load and spent less time in trivial things.&lt;/p&gt;

&lt;p&gt;Here are some recommendations made by the Vue Core Team:&lt;/p&gt;

&lt;h4&gt;
  
  
  Toolchain
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://vitejs.dev/guide/"&gt;Vite&lt;/a&gt;&lt;/strong&gt;. You are probably familiar with this one, Vite (pronounced &lt;code&gt;/vit/&lt;/code&gt;) is a build tool that provides a fast developer experience to build apps, libraries, etc. The community has embrace it very well and has built awesome plugins, boilerplates and templates and has crossed the horizons of Vue itself and can work with react, svelte, preact and others with typescript support out of the box. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar"&gt;Volar&lt;/a&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;a href=""&gt;vue-tsc&lt;/a&gt;&lt;/strong&gt; improves the experience of working with typescrypt and vue3. the first one is an editor extension built for Vue 3 and the latest is a wrapper to type-check Vue Single File coomponents and typescript and also generate definitions. &lt;/p&gt;

&lt;h4&gt;
  
  
  State Management:
&lt;/h4&gt;

&lt;p&gt;One of the advantages of the composition API is that is reactivity works outside of components life cycle, and you can build what we know like stores just by wrapping an object in &lt;code&gt;reactive&lt;/code&gt; over a year this is the approach I have followed personally; but for more advanced use cases &lt;a href="https://pinia.vuejs.org/"&gt;Pinia&lt;/a&gt; is the recommended way to go.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://pinia.vuejs.org/"&gt;Pinia&lt;/a&gt;&lt;/strong&gt; is a state management library designed with the ideas of vuex-next so it is the spiritual succesor of Vuex  some of the highlights of pinia are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Devtool integration&lt;/li&gt;
&lt;li&gt;SSR support&lt;/li&gt;
&lt;li&gt;type-safe stores &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Others
&lt;/h4&gt;

&lt;p&gt;Tooling cli: &lt;a href="https://github.com/vuejs/create-vue"&gt;create-vue&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Playgounds&lt;/strong&gt; Are an important option to share code with others and very useful when reporting bugs as reproduction links now the recommended playgrounds by the Vue team are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://sfc.vuejs.org/"&gt;Vue SFC Playground&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackblitz.com/"&gt;stackBlitz&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What we have
&lt;/h3&gt;

&lt;p&gt;Here is a short selection of libraries that might be useful for common cases when building new apps with Vue3&lt;/p&gt;

&lt;h4&gt;
  
  
  UI Libraries.
&lt;/h4&gt;

&lt;p&gt;UI libraries are a good way to speed up development and just focus in business logic.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.naiveui.com/en-US/os-theme"&gt;naive ui&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://element-plus.org/en-US/component/button.html"&gt;element plus&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Vueuse
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://vueuse.org/"&gt;Vueuse&lt;/a&gt; is a set of composables(hooks) for vue 3 that wrap many Browser API's, animation and other utilities to provide an easier and reactive way of use to us.&lt;/p&gt;

&lt;h4&gt;
  
  
  Vitesse
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://github.com/antfu/vitesse"&gt;Vitesse&lt;/a&gt; is a template strongly opinionated built by &lt;a href="https://github.com/antfu"&gt;Anthony Fu&lt;/a&gt; it provides the best SSR boilerplate we have currently in the ecosystem, you can fork and customize it as you like for your next app.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is coming
&lt;/h3&gt;

&lt;h4&gt;
  
  
  New docs:
&lt;/h4&gt;

&lt;p&gt;The official documentation has been rewritten more beautiful than ever, with best practices, extra topics and the detailed and comprehensive technical writing to teach you how to use Vue&lt;/p&gt;

&lt;p&gt;You can take a look of what is coming &lt;a href="https://staging.vuejs.org/"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Nuxt 3:
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://v3.nuxtjs.org/"&gt;Nuxt&lt;/a&gt; is coming powered by Vue3 that means by default will be faster, lighter and with great support for typescript but in addition vite support, webpack 5, a Nuxt CLI and a Nuxt Kit for module development are part of the new Nuxt 3 currently it is in beta so if we use it and report bugs if we find them or even help to solve them with a PR would be awesome.&lt;/p&gt;

&lt;h4&gt;
  
  
  Make Vue 3 default
&lt;/h4&gt;

&lt;p&gt;Currently Vue 3 is kind of hidden one could say, because if we run &lt;code&gt;npm install vue&lt;/code&gt; or search for Vue in google Vue 2 is the one that is coming, this is by design of course, so the event that officially will mark the new era is the Final switch when Vue 3 will be the default Vue. And this is coming soon.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wrapping up
&lt;/h3&gt;

&lt;p&gt;I hope you find this walk around the current Vue ecosystem useful, if you have seen any other cool project or have information that I missed to mention here share it with us on the comment section and as always let me know about any questions you have here or on &lt;a href="https://twitter.com/JesusntGuerrero"&gt;Twitter&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Thanks for reading and have a nice day.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/vuesomedev/awesome-vue-3"&gt;awesome vue&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=2KBHvaAWJOA&amp;amp;lc=z22ytvcgsky5fxlh104t1aokgcotea4j2rz3m5ovxbqvrk0h00410.1642823773254725"&gt;The New Vue by Evan You&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>My roadmap in web 3</title>
      <dc:creator>Jesus Guerrero</dc:creator>
      <pubDate>Thu, 23 Dec 2021 04:30:45 +0000</pubDate>
      <link>https://dev.to/jesusantguerrero/my-roadmap-in-web-3-1hgo</link>
      <guid>https://dev.to/jesusantguerrero/my-roadmap-in-web-3-1hgo</guid>
      <description>&lt;p&gt;I decided to investigate and learn about blockchain, crypto, smart contracts and decentralized apps (dapps) A.K.A Web 3.0 from september 24, of 2021. I got curious about the term from the hype on twitter but it was more hype than truly helpful information with some valuable exceptions.&lt;/p&gt;

&lt;p&gt;I am kind of documenting the journey and sharing my learning process hoping that can be useful for someone else but also expressing my own opinions.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The following lists express the order of my learning process but I didn't have to finish one to start the other. for example I was learning concepts yet, and doing the cryptozombies course.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1 - Learn the concepts.
&lt;/h2&gt;

&lt;p&gt;It is kind of hard to assimilate and embrace an idea that challenge the status quo in so many ways. We tend to be cautious, skeptic and critic about it, specially when we heard just good things and anything negative.&lt;/p&gt;

&lt;p&gt;By reading about the idea, the goals, the key concepts, how it works and the things web3 need to improve to materialize its final goal; we emphasize more with it.&lt;/p&gt;

&lt;p&gt;These are a good places to start:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://ethereum.org/en/developers/docs/"&gt;Ethereum Docs&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://ethereum.org/en/developers/docs/web2-vs-web3/"&gt;Web2 vs Web3&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I wrote about this in my article &lt;a href="https://dev.to/jesusantguerrero/web-3-0-for-mortals-3h04"&gt;an honest look at web3&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=JPGNvKy6DTA"&gt;Web3, Blockchain, cryptocurrency: a threat or an opportunity? by Shermin Voshmgir&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2 - Consume
&lt;/h2&gt;

&lt;p&gt;By looking for and using some implementations of web3 applications OR Descentralized Apps(Dapps), we can understand what kind of applications we can build, the use cases and real world examples.&lt;/p&gt;

&lt;p&gt;In my particular case I downloaded Brave browser as the implemented a nice use case to gain tokens for view to the adds, installed my metamask wallet, and started to follow people on twitter that provide useful content and resources.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/dabit3"&gt;dabit3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/oliverjumpertz/status/1396394220299169793"&gt;Oliver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/VittoStack"&gt;vitto&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3 - Get your hands dirty.
&lt;/h2&gt;

&lt;p&gt;The primary blockchain to build smart-contracts and dapps is Ethereum in addition its platform Ethereum Virtual Machine (EVM) is compatible with other platforms like Polygon(Matic) for example, so by learning solidity, one of the language of EVM you can make smart-contracts for multiple blockchains.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cryptozombies.io/"&gt;cryptozombies&lt;/a&gt; is an excelent resource that cover all the things you need to know to build your first contracts and dapps. since the basics of the language, libraries, ERC721 how to use other contracts with yours, how to handle security, how to connect with oracles to how to connect your frontend with a smart contract. All this in an interactive gamified tutorial.&lt;/p&gt;

&lt;h2&gt;
  
  
  4 - Build, build and build.
&lt;/h2&gt;

&lt;p&gt;After the cryptozombies course, I thought the right direction was to get my local environment to build my repos and code my contracts with the learnings of the course.&lt;/p&gt;

&lt;p&gt;After some research My stack was like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://hardhat.org/"&gt;Hardhat&lt;/a&gt; - Flexible, extensible and fast Ethereum development environment for professionals.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://v3.vuejs.org/"&gt;Vue 3&lt;/a&gt; - The Progressive JavaScript Framework&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.ethers.io/v5/"&gt;ethers.js&lt;/a&gt; - JS library for interacting with the Ethereum Blockchain and its ecosystem&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Brave Browser/Google Chrome with &lt;a href="https://metamask.io/"&gt;metamask&lt;/a&gt; extension&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;I choose to use Vue because I feel comfortable with it and it is my favorite framework but you can use whatever framework you like react, svelte, etc.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  5 - Deploying to the world.
&lt;/h2&gt;

&lt;p&gt;The next step after creating a smart contract and having a working frontend that interact with the smart contract, is deploying to let other use it and why not show case the working example in your portfolio.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=GKJBEEXUha0&amp;amp;t=342s"&gt;This tutorial by Nader Dabit&lt;/a&gt; helped me with this and in addition, learned how to build a marketplace and about &lt;a href="https://docs.polygon.technology/docs/develop/network-details/network/"&gt;Polygon&lt;/a&gt; and &lt;a href="https://infura.io/"&gt;Infura&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  6 - Learning about cryptocurrencies
&lt;/h2&gt;

&lt;p&gt;Cryptocurrencies are the fuel of Web3 they move the economy, they move the smart contracts and transactions that happens in the platforms. if you take a look at them you will see that most of these tokens have a platform behind Ether has Ethereum ecosystem, Links has Chainlink which is a set of oracles that you can use in your dapps, Solana is also an ecosystem that have its own a blockchain that allows you to build smart-contracts and so on.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://binance.com/"&gt;Binance&lt;/a&gt; - App to buy/sell crypto&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://coinmarketcap.com/currencies"&gt;CoinMarketCap&lt;/a&gt; - App to keep track of your portfolio and market prices.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/channel/UCsYYksPHiGqXHPoHI-fm5sg"&gt;Whiteboard Crypto&lt;/a&gt; channel that explain different platforms, tokens and concepts of web3&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;In this step watch out with the scammers, don't take anything as financial advice and do your research before invest in a token. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  7 - Iterate and get stronger.
&lt;/h2&gt;

&lt;p&gt;With every step you get better and better in the next iteration you can build a more robust environment setup with an advanced hardhat setup I am planning to share the setup I did &lt;a href="https://github.com/jesusantguerrero/chainlink-hackathon"&gt;here&lt;/a&gt;. this will be another article&lt;/p&gt;

&lt;p&gt;Complement your dapps with services like &lt;a href="https://moralis.io/"&gt;moralis&lt;/a&gt;, &lt;a href="https://www.pinata.cloud/"&gt;pinata&lt;/a&gt; for IPFS storage, etc.&lt;/p&gt;

&lt;p&gt;In my case at this point I learned how to generate assets for my NFT's with &lt;a href="https://www.youtube.com/watch?v=vFY_E3IP6OU"&gt;hashlips&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  8 - Going out of the comfort zone.
&lt;/h2&gt;

&lt;p&gt;Participating in hackathons at least once in life is a good way to inspire you and put you in the zone. In this state you can apply all the things you are learning, brainstorm ideas, see a lot of use cases for new technologies, interact with other developers and find communities with the same interest as you.&lt;/p&gt;

&lt;p&gt;I participated in the chainlink hackathon I don't know if I am going to win anything yet, but the things I learned and applied are very valuable.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=p36tXHX1JD8&amp;amp;t=4424s"&gt;Patrick Collins&lt;/a&gt;: Aside from beginner make advanced topics well explained.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://chain.link/"&gt;Chainlink oracles&lt;/a&gt;: Allow communicate smart contracts with off-chain data.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion.
&lt;/h2&gt;

&lt;p&gt;After going through this steps and resources I gained some knowledge and built kind of fun things I hope this post help you to start building some smart contracts and have fun learning something new.&lt;/p&gt;

&lt;p&gt;The post is unfinished because I will be adding more things as I go farther.&lt;/p&gt;

&lt;p&gt;Thanks for reading. If you have any questions the comments are open, or if you like &lt;a href="https://twitter.com/JesusntGuerrero"&gt;Twitter&lt;/a&gt; as well as my &lt;a href="https://github.com/jesusantguerrero"&gt;Github&lt;/a&gt; where I do some experiments and projects.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>web3</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>From my point of Vue: Headless components in vue</title>
      <dc:creator>Jesus Guerrero</dc:creator>
      <pubDate>Thu, 18 Nov 2021 12:40:59 +0000</pubDate>
      <link>https://dev.to/jesusantguerrero/from-my-point-of-vue-headless-components-2403</link>
      <guid>https://dev.to/jesusantguerrero/from-my-point-of-vue-headless-components-2403</guid>
      <description>&lt;p&gt;Hello there. This is the second article of the series "From my point of Vue", where we are going to discuss, explore, learn about some interesting topics from a Vue.js perspective.&lt;/p&gt;

&lt;p&gt;Today we are going to explore Headless components I would consider this a middle/advanced topic, so previous knowledge of Vue.js will be required to better grasp the examples, the concept though, is global and you can take advantage of this on any other framework.&lt;/p&gt;

&lt;p&gt;Without more delay, let's start.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;While creating applications you will find yourself either doing the same components with the same logic many times with different User Interface(UI) or installing packages with an opinionated design that have a very different look from the design of your app. It shouldn't be so hard to customize simple components like inputs, labels, buttons but when it comes to complex components like Selects, Tabs, Step Wizards things might be a little harder if the component wasn't created with UI flexibility in mind, and here is where &lt;strong&gt;Headless components&lt;/strong&gt; come to the rescue.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are headless components?
&lt;/h2&gt;

&lt;p&gt;In plain words, headless components are the ones that handle the logic and behavior separated from the UI, giving the responsibility of how the component looks to the developer.&lt;/p&gt;

&lt;p&gt;The headless component can expose values and functions (state and controls) that will allow a child component to control certain parts of it and make UI decisions based on a state value. In other words, they are not attached to the UI but serves as support. &lt;/p&gt;

&lt;p&gt;This gives a huge advantage to share components across projects where their design are very different or to add variations of the same component: an upload component that the upload files as a list or carousel of images for example.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;The concept is not new, it's been discussed and implemented for a couple of years, I first heard of it when &lt;a href="https://twitter.com/adamwathan" rel="noopener noreferrer"&gt;Adam Watham&lt;/a&gt;, creator of Tailwind CSS, and its team launched  &lt;a href="https://headlessui.dev/" rel="noopener noreferrer"&gt;Headless UI&lt;/a&gt; libraries like &lt;a href="https://github.com/downshift-js/downshift" rel="noopener noreferrer"&gt;downshift&lt;/a&gt; by &lt;a href="https://kentcdodds.com/" rel="noopener noreferrer"&gt;Kent Dodds&lt;/a&gt; also used this pattern, just to mention a couple of cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a headless component
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Requirements and approach
&lt;/h3&gt;

&lt;p&gt;To illustrate let's build a headless Rate component with the following requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The user can specify the &lt;code&gt;count&lt;/code&gt; of how many stars should display.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Should expose the selected state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Should expose the covered state.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To build this component we are going to use Tailwind CSS for styling, Vue 3 (&lt;a href="https://dev.to/jesusantguerrero/from-my-point-of-vue-composition-api-18de"&gt;the composition API&lt;/a&gt;) and codepen as a online editor.&lt;/p&gt;

&lt;h3&gt;
  
  
  The code
&lt;/h3&gt;

&lt;p&gt;Here is how we defined our main component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&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;defineComponent&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;computed&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Vue&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;Rate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defineComponent&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;rate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;div&amp;gt;
        &amp;lt;slot 
            v-for="current in range" 
            :key="current" 
            :current="current+1"
            :selected="isSelected(current+1)"
            :covered="isCovered(current+1)"
            :set-hovered="setHovered"
        &amp;gt;
            {{ current }}
        &amp;lt;/slot&amp;gt;
    &amp;lt;/div&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;modelValue&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;count&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// state&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hoveredIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="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="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&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;count&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;keys&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;isCovered&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&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;return&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;modelValue&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;hoveredIndex&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;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;current&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;isSelected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&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;return&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;modelValue&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// state functions&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setHovered&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&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;hoveredIndex&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="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;isSelected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;isCovered&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;setHovered&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;Let's explain what is happening here we have three main blocks&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The state&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;range&lt;/code&gt;: which is an array from 0 to the value we pass count for this case &lt;code&gt;[0, 1, 2, 3, 4]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;hoveredIndex&lt;/code&gt;: to store the last star we set the mouse over.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;isSelected&lt;/code&gt;: will return true if the value passed is the current rate.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;isCovered&lt;/code&gt;: will return true if the value passed is less than the current rate&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The controls&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;setHovered&lt;/code&gt;: will set the index of the start we put the mouse on.&lt;/p&gt;

&lt;p&gt;And &lt;strong&gt;the template&lt;/strong&gt;&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;slot&lt;/span&gt; 
          &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"current in range"&lt;/span&gt; 
          &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"current"&lt;/span&gt; 
          &lt;span class="na"&gt;:current=&lt;/span&gt;&lt;span class="s"&gt;"current+1"&lt;/span&gt;
          &lt;span class="na"&gt;:selected=&lt;/span&gt;&lt;span class="s"&gt;"isSelected(current+1)"&lt;/span&gt;
          &lt;span class="na"&gt;:covered=&lt;/span&gt;&lt;span class="s"&gt;"isCovered(current+1)"&lt;/span&gt;
          &lt;span class="na"&gt;:set-hovered=&lt;/span&gt;&lt;span class="s"&gt;"setHovered"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          {{ current }}
      &lt;span class="nt"&gt;&amp;lt;/slot&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 we are telling to this component: hey, render &lt;code&gt;n&lt;/code&gt; times whatever element I pass to you as a child and expose the current value, if is selected, if is covered and the function to set the hover.&lt;/p&gt;

&lt;p&gt;And this is exactly what we are going to do next.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using our component
&lt;/h3&gt;

&lt;p&gt;Now we'll use our component to render 5 stars and gives some style with Tailwind gray text for the color of the stars but yellow when is covered or selected and changing the value when we click and the hoverIndex with the mouseover and mouseout.&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;h4&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mt-4 mb-1 font-bold text-blue-900"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;How useful was the post?&lt;span class="nt"&gt;&amp;lt;/h4&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;Rate&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"rating"&lt;/span&gt; &lt;span class="na"&gt;:count=&lt;/span&gt;&lt;span class="s"&gt;"5"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"space-x-2 cursor-pointer"&lt;/span&gt; &lt;span class="na"&gt;v-slot:default=&lt;/span&gt;&lt;span class="s"&gt;"{ selected, covered, current, setHovered }"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; 
          &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"rating=current"&lt;/span&gt; 
          &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;mouseover=&lt;/span&gt;&lt;span class="s"&gt;"setHovered(current)"&lt;/span&gt;
          &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;mouseout=&lt;/span&gt;&lt;span class="s"&gt;"setHovered(0)"&lt;/span&gt;
          &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"font-bold text-gray-400 transition transform cursor-pointer hover:text-yellow-400 hover:scale-110"&lt;/span&gt; 
          &lt;span class="na"&gt;:class=&lt;/span&gt;&lt;span class="s"&gt;"[(selected || covered) ? 'text-yellow-500': 'text-gray-400']"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; 
       &lt;span class="nt"&gt;&amp;lt;i&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fa fa-star"&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;/i&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/Rate&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1628779541636%2Ftfi2G5RmG.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1628779541636%2Ftfi2G5RmG.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Changing the UI
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Scale rate
&lt;/h4&gt;

&lt;p&gt;To change to a scale rate for example we just need to change the UI without touching the logic anymore.&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;!-- Scale Rate --&amp;gt;&lt;/span&gt;
...
  &lt;span class="nt"&gt;&amp;lt;Rate&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"scale"&lt;/span&gt; &lt;span class="na"&gt;:count=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"space-x-2 cursor-pointer"&lt;/span&gt; &lt;span class="na"&gt;v-slot:default=&lt;/span&gt;&lt;span class="s"&gt;"{ current, selected }"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; 
        &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"scale=current"&lt;/span&gt; 
         &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"px-3 py-0.5 font-bold border border-gray-400 transition transform rounded-lg cursor-pointer hover:text-blue-400"&lt;/span&gt; 
         &lt;span class="na"&gt;:class=&lt;/span&gt;&lt;span class="s"&gt;"{'text-blue-500 border-blue-500 shadow-md ring ring-blue-200': selected}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; 
      {{ current }}
     &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/Rate&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1628779699348%2FGbS-fP1KVX.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1628779699348%2FGbS-fP1KVX.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Single choice list
&lt;/h4&gt;

&lt;p&gt;Another change this time with a vertical 3 choice list.&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;!-- Single Choice List --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h4&lt;/span&gt;  &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mt-4 mb-1 font-bold text-blue-900 mt-5"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;How often do this case happens to you?&lt;span class="nt"&gt;&amp;lt;/h4&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;Rate&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"choice"&lt;/span&gt; &lt;span class="na"&gt;:count=&lt;/span&gt;&lt;span class="s"&gt;"3"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex flex-col space-y-2 cursor-pointer w-full"&lt;/span&gt; &lt;span class="na"&gt;v-slot:default=&lt;/span&gt;&lt;span class="s"&gt;"{ current, selected }"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; 
        &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"choice=current"&lt;/span&gt; 
         &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"block w-44 text-left px-3 py-0.5 font-bold border border-gray-400 transition transform rounded-lg cursor-pointer hover:text-gray-400"&lt;/span&gt; 
         &lt;span class="na"&gt;:class=&lt;/span&gt;&lt;span class="s"&gt;"{'text-gray-500 border-gray-500 shadow-md ring ring-gray-200': selected}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; 
          &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-gray-900 text-white px-1.5 rounded-md py-0.5"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            {{ letters[current - 1] }}
          &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
          {{ choices[current - 1] }}
     &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/Rate&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1628779808838%2FULqpRxD-d.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1628779808838%2FULqpRxD-d.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's what I call maximum flexibility 👌✨. As a last improvement, we could add a wrapper component to support those three use cases and pass a prop like &lt;code&gt;mode&lt;/code&gt; that accepts &lt;code&gt;rate&lt;/code&gt;, &lt;code&gt;scale&lt;/code&gt;, and &lt;code&gt;choices&lt;/code&gt; once we have our look defined and write less code in the actual pages. I will let it to you, for practice.&lt;/p&gt;

&lt;p&gt;You can see the example code running in &lt;a href="https://codepen.io/freesgen/full/BaRGmYa" rel="noopener noreferrer"&gt;Codepen&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Headless components provide a way to reuse the logic of components but with the flexibility of customizing the UI.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;They are good for sharing complex components across projects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It probably requires wrapper components to use your customized UI across the app in contrast to a traditional component. That will be the cost of flexibility&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope you find it useful, let me know about any questions you have here or on &lt;a href="https://twitter.com/JesusntGuerrero" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;. thanks for reading and have a nice day.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://headlessui.dev/" rel="noopener noreferrer"&gt;Headlessui&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://codesandbox.io/s/headless-rate-1erzy?file=/src/App.vue" rel="noopener noreferrer"&gt;A more advanced implementation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Build an authentication flow with Auth0 and Vue3</title>
      <dc:creator>Jesus Guerrero</dc:creator>
      <pubDate>Sun, 24 Oct 2021 17:34:22 +0000</pubDate>
      <link>https://dev.to/jesusantguerrero/build-an-authentication-flow-with-auth0-and-vue3-1f3h</link>
      <guid>https://dev.to/jesusantguerrero/build-an-authentication-flow-with-auth0-and-vue3-1f3h</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;In every project, you'll probably start building the login, registration, reset password functionality, well, Auth0 provides a set of tools that are going to help you to complete that kind of task faster than the traditional way.&lt;/p&gt;

&lt;p&gt;In this guide, you'll create an entire authentication flow with Auth0 and Vue3.&lt;/p&gt;

&lt;p&gt;By the end of this post, you'll have a vue app that allows users to register, login &lt;br&gt;
and logout and be able to use that knowledge to build your next project.&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; installed in your machine at least version 12.20&lt;/li&gt;
&lt;li&gt;Knowledge of CSS.&lt;/li&gt;
&lt;li&gt;Previous experience with Vue.&lt;/li&gt;
&lt;li&gt;Basic understanding of &lt;a href="https://dev.to/jesusantguerrero/from-my-point-of-vue-composition-api-18de"&gt;the composition API&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Step 1: Creating a new vue3 project
&lt;/h2&gt;

&lt;p&gt;To create a new Vue3 project we use &lt;a href="https://vitejs.dev/guide/" rel="noopener noreferrer"&gt;vite&lt;/a&gt; (pronounced 'vit') which is going to scaffold the structure with the latest version of vue and set the dependencies and provide a fast developer experience. &lt;/p&gt;

&lt;p&gt;Running the following code in your terminal will ask you for the name of the new project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init vite@latest &lt;span class="nt"&gt;--template&lt;/span&gt; vue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next go to the project dir in the terminal and install the dependencies with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;project-dir &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One last install, this time is the SDK of Auth0 for single-page applications&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @auth0/auth0-spa-js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a new file &lt;code&gt;.env.local&lt;/code&gt; and type &lt;code&gt;VITE_AUTH0_DOMAIN&lt;/code&gt; and &lt;code&gt;VITE_AUTH0_DOMAIN&lt;/code&gt; let it there and you'll be back later to this file to place those values from Auth0.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VITE_AUTH0_DOMAIN=
VITE_AUTH0_CLIENT_ID=
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Create an Auth0 project
&lt;/h2&gt;

&lt;p&gt;Before drop your first lines of code you'll need to create a new auth project for that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://auth0.com/signup?place=header&amp;amp;type=button&amp;amp;text=sign%20up" rel="noopener noreferrer"&gt;Auth0&lt;/a&gt; and create an account&lt;/li&gt;
&lt;li&gt;In the left side menu click on &lt;strong&gt;Applications&lt;/strong&gt; dropdown then &lt;strong&gt;Applications&lt;/strong&gt; option and then &lt;strong&gt;Create Application&lt;/strong&gt;. This will open a modal to type the name and select an application type. &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1632185164677%2F-a5ROZu6Q.png" alt="Application Setup"&gt; &lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Single page web applications&lt;/strong&gt; and give &lt;strong&gt;VueAuth&lt;/strong&gt; as the application name, you can come back and change it later.&lt;/li&gt;
&lt;li&gt;Go to settings tab in the newly created project and copy &lt;code&gt;Domain&lt;/code&gt; and &lt;code&gt;Client ID&lt;/code&gt; to &lt;code&gt;VITE_AUTH0_DOMAIN&lt;/code&gt; and &lt;code&gt;VITE_AUTH0_CLIENT_ID&lt;/code&gt; respectively in &lt;code&gt;.env.local&lt;/code&gt; file
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1632185381832%2FKa6unG0Ks.png" alt="image.png"&gt;
&lt;/li&gt;
&lt;li&gt;Go down a little more until the &lt;strong&gt;Application URIs&lt;/strong&gt; section and you need to set some routes to let Auth0 know where to go after certain events in this case our URL is &lt;code&gt;http://localhost:3000&lt;/code&gt; and you need to type in  &lt;strong&gt;Allowed Callback URLs&lt;/strong&gt; and &lt;strong&gt;Allowed Logout URLs&lt;/strong&gt; and &lt;strong&gt;Allowed Web Origins&lt;/strong&gt; like is showed in the picture below&lt;/li&gt;
&lt;/ol&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1632224890619%2FXAqRlRRy2.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1632224890619%2FXAqRlRRy2.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Creating useAuth0 composable.
&lt;/h2&gt;

&lt;p&gt;It's time to drop some lines of code, as Vue3 gives us the power of reactivity even outside a component you are going to use that to wrap the Auth0 flow into its own file&lt;br&gt;
create a new folder in &lt;code&gt;/src&lt;/code&gt; called &lt;code&gt;utils/&lt;/code&gt; and inside create a new file named &lt;code&gt;useAuth0.js&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;/src/utils/useAuth0.js&lt;/code&gt; you need to create a new reactive object to save the AuthState and it will be exported.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// utils/useAuth0.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;createAuth0Client&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;@auth0/auth0-spa-js&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;reactive&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="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;AuthState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;reactive&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="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;loading&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;isAuthenticated&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;auth0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, in order to simplify the configuration management lets add a &lt;code&gt;config&lt;/code&gt; constant and set the domain and client_id from our &lt;code&gt;.env.local&lt;/code&gt; those are available using the keywords &lt;code&gt;import.meta.env.NAME_OF_VARIABLE&lt;/code&gt; as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// utils/useAuth0.js&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;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;domain&lt;/span&gt;&lt;span class="p"&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;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;VITE_AUTH0_DOMAIN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;client_id&lt;/span&gt;&lt;span class="p"&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;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;VITE_AUTH0_CLIENT_ID&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the most important part, to wrap the authentication flow we are going to export an arrow function that takes the state as param, which will be the AuthState you made at the top of this file. And it's going to return three functions &lt;strong&gt;login&lt;/strong&gt;, &lt;strong&gt;logout&lt;/strong&gt; and &lt;strong&gt;initAuth&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useAuth0&lt;/span&gt; &lt;span class="o"&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
 &lt;span class="c1"&gt;// The implementation will go here&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;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;initAuth&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 write a utility function it is not going to be returned but it will be called after &lt;strong&gt;login&lt;/strong&gt;, &lt;strong&gt;logout&lt;/strong&gt;, and &lt;strong&gt;initAuth&lt;/strong&gt; it will be called &lt;code&gt;handleStateChange&lt;/code&gt; and is going to pass the &lt;strong&gt;authentication status&lt;/strong&gt; from Auth0 to you &lt;code&gt;AuthState&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useAuth0&lt;/span&gt; &lt;span class="o"&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="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;handleStateChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isAuthenticated&lt;/span&gt; &lt;span class="o"&gt;=&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="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isAuthenticated&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="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&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;auth0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getUser&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;loading&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;p&gt;In the next function &lt;strong&gt;initAuth&lt;/strong&gt; you'll create a new instance of &lt;code&gt;Auth0Client&lt;/code&gt; and for that you need the configuration you saved before &lt;strong&gt;domain&lt;/strong&gt;, &lt;strong&gt;client_id&lt;/strong&gt;, cacheLocation and redirect_uri&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;domain **and **client_id&lt;/strong&gt;: are the tokens you saved in &lt;code&gt;.env.local&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cacheLocation&lt;/strong&gt;: Is where Auth0 stores the token, by default the value is 'memory' that is not going to persist after you reload the page, since we don't want this use &lt;code&gt;localstarage&lt;/code&gt; that keeps the token even after refreshing the page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;redirect_uri&lt;/strong&gt;: Remember the routes you set before in the settings of your application in Auth0, well, you need it here with &lt;code&gt;window.location.origin&lt;/code&gt; you get the current location of the browser that will be '&lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;' the same you saved there.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After the &lt;code&gt;Auth0Client&lt;/code&gt; is created, call the &lt;code&gt;handleStateChange&lt;/code&gt; function to get the current authentication state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initAuth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loading&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="nf"&gt;createAuth0Client&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;client_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;cacheLocation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;localstorage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;redirect_uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;
      &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;then&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;auth&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;auth0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;auth&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;handleStateChange&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;Next, the login, auth0 has a loginWithPopup that is going to open a popup and ask the user for the credentials to login or register after.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;login&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loginWithPopup&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;handleStateChange&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;Next, the logout, auth0 has a logout function that accepts an object as an argument and a &lt;strong&gt;returnTo&lt;/strong&gt; property is required. Here you can type your current location with &lt;code&gt;window.location.origin&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;logout&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;returnTo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;origin&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;By now your &lt;code&gt;src/utils/useAuth0.js&lt;/code&gt; file should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// utils/useAuth0.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;createAuth0Client&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;@auth0/auth0-spa-js&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;reactive&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="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;AuthState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;reactive&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="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;loading&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;isAuthenticated&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;auth0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;domain&lt;/span&gt;&lt;span class="p"&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;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;VITE_AUTH0_DOMAIN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;client_id&lt;/span&gt;&lt;span class="p"&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;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;VITE_AUTH0_CLIENT_ID&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;useAuth0&lt;/span&gt; &lt;span class="o"&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="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;handleStateChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isAuthenticated&lt;/span&gt; &lt;span class="o"&gt;=&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="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isAuthenticated&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="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&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;auth0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getUser&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;loading&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initAuth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loading&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="nf"&gt;createAuth0Client&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;client_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;cacheLocation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;localstorage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;redirect_uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;
        &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;then&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;auth&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;auth0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;auth&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;handleStateChange&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;login&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loginWithPopup&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;handleStateChange&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;logout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;logout&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;returnTo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;origin&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="k"&gt;return&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;initAuth&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;
  
  
  Step 4: Setup App.vue
&lt;/h2&gt;

&lt;p&gt;Let's modify the &lt;code&gt;src/App.vue&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Take a look at the final code of the &lt;code&gt;App.vue&lt;/code&gt; I'll explain bellow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useAuth0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AuthState&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="s2"&gt;./utils/useAuth0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;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;initAuth&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useAuth0&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AuthState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;initAuth&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"!AuthState.loading"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Vue logo"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./assets/logo.png"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"!AuthState.isAuthenticated"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"login()"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn btn-primary"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Login&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;div&lt;/span&gt; &lt;span class="na"&gt;v-else&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; Welcome to VueAuth &lt;span class="nt"&gt;&amp;lt;strong&amp;gt;&lt;/span&gt;{{ AuthState.user.name }}&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"logout()"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn btn-secondary"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Logout&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;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-else&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Loading ...
  &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;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
&lt;span class="nf"&gt;#app&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Avenir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Helvetica&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Arial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;-webkit-font-smoothing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;antialiased&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;-moz-osx-font-smoothing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grayscale&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#2c3e50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;60px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;14px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;400&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.btn-primary&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#41B883&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.btn-secondary&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#aaa&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the top of the file in the script section &lt;strong&gt;AuthState&lt;/strong&gt; and &lt;strong&gt;useAuth0&lt;/strong&gt; are imported from the wrapper you created.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;AuthState&lt;/strong&gt; is used to call &lt;strong&gt;useAuth0&lt;/strong&gt; and get the &lt;strong&gt;login&lt;/strong&gt;, &lt;strong&gt;logout&lt;/strong&gt; and &lt;strong&gt;initAuth&lt;/strong&gt; functions.&lt;/p&gt;

&lt;p&gt;And at the end of the script &lt;strong&gt;initAuth()&lt;/strong&gt; is called to create the instance and get the current authentication state of the user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useAuth0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AuthState&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="s2"&gt;./utils/useAuth0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;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;initAuth&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useAuth0&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AuthState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;initAuth&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the template section we check if the app is loading and if the user is not authenticated show the &lt;code&gt;login&lt;/code&gt; button that calls the &lt;strong&gt;login&lt;/strong&gt; function in the &lt;strong&gt;script&lt;/strong&gt; but if it is authenticated show the user name and a logout button calling the &lt;strong&gt;logout&lt;/strong&gt; function from the &lt;strong&gt;script&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If the app is loading it shows the &lt;code&gt;loading...&lt;/code&gt; text.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"!AuthState.loading"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Vue logo"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./assets/logo.png"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"!AuthState.isAuthenticated"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"login()"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn btn-primary"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Login&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;div&lt;/span&gt; &lt;span class="na"&gt;v-else&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; Welcome to VueAuth &lt;span class="nt"&gt;&amp;lt;strong&amp;gt;&lt;/span&gt;{{ AuthState.user.name }}&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"logout()"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn btn-secondary"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Logout&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;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-else&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Loading ...
  &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;h3&gt;
  
  
  Final result
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.loom.com/share/e1ab06e093bb407c990f2fbd23cc64d5" rel="noopener noreferrer"&gt;&lt;br&gt;
    &lt;p&gt;VueAuth - Watch Video&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
    &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.loom.com%2Fsessions%2Fthumbnails%2Fe1ab06e093bb407c990f2fbd23cc64d5-with-play.gif" 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%2Fcdn.loom.com%2Fsessions%2Fthumbnails%2Fe1ab06e093bb407c990f2fbd23cc64d5-with-play.gif"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
  &lt;/p&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;You built an authentication flow with Vue3 and Auth0, congrats! Now that you are familiar with &lt;strong&gt;Auth0&lt;/strong&gt; and its benefits you are able to implement it in your next project.&lt;/p&gt;

&lt;p&gt;Thanks for reading. If you have any questions the comments are open, or if you like &lt;a href="https://twitter.com/JesusntGuerrero" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; as well as my &lt;a href="https://github.com/jesusantguerrero" rel="noopener noreferrer"&gt;Github&lt;/a&gt; where I do some experiments and projects.&lt;/p&gt;

&lt;p&gt;Have a good day.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/jesusantguerrero/vue-auth0" rel="noopener noreferrer"&gt;Repo of this guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://auth0.com/docs/libraries/auth0-single-page-app-sdk" rel="noopener noreferrer"&gt;Auth0 SDK Docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>vue</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
