<?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: vuewebdev</title>
    <description>The latest articles on DEV Community by vuewebdev (@divewitholeg).</description>
    <link>https://dev.to/divewitholeg</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%2F1032904%2F52447540-7a99-4b31-87af-be4199e2fae0.jpeg</url>
      <title>DEV Community: vuewebdev</title>
      <link>https://dev.to/divewitholeg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/divewitholeg"/>
    <language>en</language>
    <item>
      <title>Deploying a Laravel 10.7 and Vue 3 project from GitHub to Hostinger</title>
      <dc:creator>vuewebdev</dc:creator>
      <pubDate>Tue, 18 Apr 2023 18:42:30 +0000</pubDate>
      <link>https://dev.to/divewitholeg/deploying-a-laravel-107-and-vue-3-project-from-github-to-hostinger-4lko</link>
      <guid>https://dev.to/divewitholeg/deploying-a-laravel-107-and-vue-3-project-from-github-to-hostinger-4lko</guid>
      <description>&lt;p&gt;Shared hosting is kind of overlooked these days in favor of platforms like Vercel and Netlify that do a courtesy of building and instant deployment of your project. Just push the ok button and watch your website being published online.&lt;/p&gt;

&lt;p&gt;I decided to check how fast is a Git deployment with Hostinger and was astonished with the speed and convenience of deployment of my freshly started Laravel 10.7 / Vue 3 blog project.&lt;/p&gt;

&lt;p&gt;Upon purchase of &lt;a href="https://oleg-blog.tech"&gt;https://oleg-blog.tech&lt;/a&gt; domain name for a ridiculous price of 1.41 EUR, installing SSL certificate, establishing an e-mail account &lt;a href="mailto:me@oleg-blog.tech"&gt;me@oleg-blog.tech&lt;/a&gt; and MySQL database (all complimentary with my Premium Hosting plan), I have started bash terminal on my Linux Ubuntu 22.04 machine to initiate a new Laravel project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer create-project laravel/laravel larablog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I will not go through the whole procedure here since it’s not a Laravel tutorial. However, I would like to point out that the documentation at &lt;a href="https://bootcamp.laravel.com/inertia/installation"&gt;https://bootcamp.laravel.com/inertia/installation&lt;/a&gt; is profound and so easy to read that it doesn’t take more than 20 minutes before you insert &lt;code&gt;php artisan serve&lt;/code&gt; in your terminal and see the starter page looking at you from localhost:8000.&lt;/p&gt;

&lt;p&gt;Since we are using Vue 3 in this project there is still a few moments I would like to drive your attention to. First, you will need to install Laravel Breeze to use the framework. There is also a Breeze installation for React available from the same source. You can enter into your terminal the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require laravel/breeze &lt;span class="nt"&gt;--dev&lt;/span&gt;

php artisan breeze:install vue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, you need to start your local development environment for the node files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Last, you will need to create a MySQL database in your local environment and enter all the details for the database, the e-mail SMTP server and other information you might need into &lt;code&gt;.env&lt;/code&gt; file. After that you can run the following command from your bash terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you have made sure that your project is now working in the local environment and you can register in your database and log in, it’s time to create a private repository on GitHub and commit your code into it. Please note, that it is crucial for your code to work later on Hostinger platform to remove all the &lt;code&gt;.env&lt;/code&gt;, &lt;code&gt;/public/*&lt;/code&gt;, &lt;code&gt;/storage/*&lt;/code&gt;, &lt;code&gt;vendor&lt;/code&gt; files from &lt;code&gt;.gitignore&lt;/code&gt; before you make a commit.&lt;/p&gt;

&lt;p&gt;Also, since your Laravel project will serve all the files from &lt;code&gt;/public&lt;/code&gt; folder per se, you will need to create an additional &lt;code&gt;.htaccess&lt;/code&gt; file in the root folder with the following code inside:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RewriteEngine On
RewriteBase /

# Serve files from the root directory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ public/$1 [L]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After making a Git commit and performing file synchronization it was time to get back to the Hostinger  account, find Git from the Advanced menu and follow the instruction steps from the provided tutorial &lt;a href="https://support.hostinger.com/en/articles/1583302-how-to-deploy-a-git-repository"&gt;https://support.hostinger.com/en/articles/1583302-how-to-deploy-a-git-repository&lt;/a&gt; to deploy the repo from under the intended domain.&lt;/p&gt;

&lt;p&gt;Before the actual deployment you will need to copy the RSA key and paste it in your GitHub settings in order for the hosting provider to be able to access private repository on GitHub. I also chose to add a webhook directly to my project so that I don’t need to manually update Hostinger every time I add new features to my project. Now, with the webhook added and the project being successfully published, there is still one last step to be taken.&lt;/p&gt;

&lt;p&gt;Database migration, that I already initially did in my project locally before committing it to GitHub will not work on a database on Hostinger. I needed to use SSH to go on the Hostinger server and run &lt;code&gt;php artisan migrate&lt;/code&gt; command from the terminal there. In order to access the server, you need to copy the code from the menu on the dashboard under &lt;code&gt;Advanced&lt;/code&gt; → &lt;code&gt;SSH Access&lt;/code&gt; and post it into your terminal. Voi la now I am free to develop my blog with instant deployment using a shared hosting service with a convenience of edge computing.&lt;/p&gt;

&lt;p&gt;In conclusion, with a few extra minutes invested in setting up the project, it is possible to have a domain, hosting, database and an e-mail service ready almost at the speed that cloud computing services offer. For a startup, a blogger or a small company this might be an ideal solution to bring out their ideas, products and services directly to their customer and save some money on the way.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>vue</category>
      <category>php</category>
    </item>
    <item>
      <title>Tailwind 3.3 - more colors, TypeScript friendly</title>
      <dc:creator>vuewebdev</dc:creator>
      <pubDate>Wed, 29 Mar 2023 13:07:04 +0000</pubDate>
      <link>https://dev.to/divewitholeg/tailwind-33-more-colors-typescript-friendly-5276</link>
      <guid>https://dev.to/divewitholeg/tailwind-33-more-colors-typescript-friendly-5276</guid>
      <description>&lt;p&gt;Get ready to spice up your web development game with the latest release of Tailwind CSS v3.3! This update brings a deliciously extended color palette to satisfy even the most discerning designer's cravings. But that's not all - feast your eyes on the new ESM/TS support that'll make your workflow smoother than butter. And, as if that weren't enough, you can now indulge in the savory goodness of logical properties and other mouth-watering features that'll take your website to the next level. Don't miss out on this delectable upgrade - your taste buds (and clients) will thank you!&lt;/p&gt;

&lt;p&gt;First thing let's upgrade the existing version of Tailwind for the latest one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -D tailwindcss@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Darker -950 shades are now added for every color:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;span class="font-bold text-slate-950"&amp;gt;-950 shades&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the new version you can generate a TS (or ESM) config file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx tailwindcss init --ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For those using RTL and LTR language options life becomes easier with &lt;code&gt;ms-3&lt;/code&gt; (margin start) and &lt;code&gt;me-3&lt;/code&gt; (margin end) tags. Same properties were added to start-&lt;em&gt;, end-&lt;/em&gt;, padding, rounded, border and scroll.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="group flex items-center"&amp;gt;
    &amp;lt;div class="me-3"&amp;gt;
      &amp;lt;p class="text-sm font-medium text-slate-700"&amp;gt;أوليج ريبنيكوف&amp;lt;/p&amp;gt;
      &amp;lt;p class="text-sm font-medium text-slate-500"&amp;gt;مطور ويب&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;img
      class="shrink-0 h-12 w-12 rounded-full"
      src="@/assets/Oleg.jpg"
      alt="Oleg Rõbnikov Web Development logo"
    /&amp;gt;

    &amp;lt;div class="ms-3"&amp;gt;
      &amp;lt;p class="text-sm font-medium text-slate-700"&amp;gt;Oleg Rõbnikov&amp;lt;/p&amp;gt;
      &amp;lt;p class="text-sm font-medium text-slate-500"&amp;gt;Web developer&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;New controls were added to make gradient stop positions more precise with &lt;code&gt;from-10%&lt;/code&gt;, &lt;code&gt;via-35%&lt;/code&gt;, etc. You can find more information about new features of color gradient stops in documentation&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class="bg-gradient-to-r from-rose-400 from-30% via-fuchsia-500 via-60% to-indigo-500 to-90% h-10 w-300" 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Line-clamp isn't used as a plugin anymore. You can just use it as, e.g. &lt;code&gt;line-clamp-2&lt;/code&gt; class! &lt;/p&gt;

&lt;p&gt;Line-height and font-size have been combined into a single class, e.g. 'font-lg/7' and also supports arbitrary values like 'font-xl/[17]'&lt;/p&gt;

&lt;p&gt;Color variables are now supported in the class arguments without &lt;code&gt;var&lt;/code&gt; prefix. Try to hover over me!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;style="--brandColor: #e500ff; --hoverBrandColor: #000000"
class="text-[--brandColor] hover:text-[--hoverBrandColor]"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Extended options for the font family include &lt;code&gt;fontVariationSettings&lt;/code&gt; besides &lt;code&gt;fontFeatureSettings&lt;/code&gt; that used to be there already. Both of them are accessible in &lt;code&gt;tailwind.config.ts&lt;/code&gt;. Please don't forget to upgrade your TS to v.5 and PostCSS to v.8.4. As I was impatient to try out all new features of new Tailwind version, I haven't done it and voila, couple of new features weren't performing well. So, please, don't forget to upgrade your dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
module.exports = {
  theme: {
    fontFamily: {
      sans: [
        'Inter var, sans-serif',
        {
          fontFeatureSettings: '"cv11", "ss01"',
          fontVariationSettings: '"opsz" 32',
        },
      ],
    },
  },
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another nifty feature is ability to customize your list bullet immages as &lt;code&gt;list-image-*&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ul class="ms-14 list-image-[url('/logo.png')]"&amp;gt;
  &amp;lt;li&amp;gt;First item&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Second item&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Third item&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;hyphens-manual&lt;/code&gt; allows you to add a custom breaking point for long words like pneumonoultramicroscopicsilicovolcanoconiosis. It's done with the help of &lt;code&gt;&amp;amp;shy;&lt;/code&gt; tag&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;p class="ms-10 w-20 hyphens-manual"&amp;gt;
  pneumo&amp;amp;shy;noultra&amp;amp;shy;microscopic&amp;amp;shy;silico&amp;amp;shy;volcanoco&amp;amp;shy;niosis
&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Table caption can now be aligned to top or bottom of the table using a single class &lt;code&gt;caption-*&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6gn1dn453bqlbuc94hp3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6gn1dn453bqlbuc94hp3.png" alt="Table caption can now be aligned to top or bottom"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In conclusion, Tailwind CSS version 3.3 has numerous new features like a redesigned docs site, CSS Grid support, and the ability to customize the font families used in your project. The update also includes numerous bug fixes and performance improvements. If you're a web developer looking to streamline your workflow and build beautiful, responsive websites faster than ever, give Tailwind CSS a try and experiment with these new features today! &lt;br&gt;
Feel free to download my &lt;br&gt;
&lt;a href="https://github.com/Divewitholeg/Tailwind-3.3.git" rel="noopener noreferrer"&gt;GitHub project&lt;/a&gt; and experiment by yourself.&lt;/p&gt;

</description>
      <category>tailwindcss</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>vue</category>
    </item>
    <item>
      <title>A Responsive and Language-Aware Footer Component for Vue 3</title>
      <dc:creator>vuewebdev</dc:creator>
      <pubDate>Thu, 23 Mar 2023 16:21:03 +0000</pubDate>
      <link>https://dev.to/divewitholeg/a-responsive-and-language-aware-footer-component-for-vue-3-3c5c</link>
      <guid>https://dev.to/divewitholeg/a-responsive-and-language-aware-footer-component-for-vue-3-3c5c</guid>
      <description>&lt;p&gt;Are you a blogger or content creator who operates in several languages? Do you have a multitude of social media accounts you need to share? Then you'll appreciate this responsive and language-aware footer component for Vue 3!&lt;/p&gt;

&lt;p&gt;This footer component is designed to be user-friendly, responsive, and customizable, displaying the appropriate social links and icons based on the language and device type. The footer layout is minimalistic to keep the user's focus on the main content. It is straightforward and easy to use, and the responsiveness of the footer ensures that it looks good on any device and screen size.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data
&lt;/h2&gt;

&lt;p&gt;The languages and social links data for this footer component are stored in JSON files in the data folder. The language.json file contains an array of objects, each representing a language. The value property of each language object represents the first two letters of a language code, and the text property stores the name of the language in its native script. The flag property stores the flag emoji of the corresponding country.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"en"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"English"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"flag"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"🇬🇧"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"et"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Eesti"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"flag"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"🇪🇪"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;........&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Below you will find the &lt;code&gt;social.json&lt;/code&gt; file, which is home to an array of objects. Each object serves as a representation of a social link. The &lt;code&gt;icon&lt;/code&gt; property holds the name of the corresponding SVG file in the assets folder, while the &lt;code&gt;name&lt;/code&gt; property contains the name of the social platform itself. The &lt;code&gt;url&lt;/code&gt; property, on the other hand, keeps track of the link to the social platform. Lastly, the &lt;code&gt;tags&lt;/code&gt; property is an array of strings that showcase the languages the link is displayed for. If the string is &lt;code&gt;all&lt;/code&gt;, then the link is visible for all languages. If the string is &lt;code&gt;desktop&lt;/code&gt;, then the link will only show on desktop devices. Similarly, if the string is &lt;code&gt;mobile&lt;/code&gt;, then the link will only display on mobile devices.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"icon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"facebook.svg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Facebook"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.facebook.com/vuewebdev"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"en"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"de"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"et"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"desktop"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"icon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"twitter.svg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Twitter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://twitter.com/DiveWithOleg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"en"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"de"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"et"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"desktop"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"icon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"github.svg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GitHub"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/Divewitholeg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"all"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"desktop"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;........&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Language Select Component
&lt;/h2&gt;

&lt;p&gt;Let me walk you through the language select component. It's a straightforward select element that is linked to the lang.json file, which holds an array of languages assigned to the langs variable. By default, the lang variable is set to en. This lang variable is then bound to the v-model of the select element, allowing users to switch between available language options easily.&lt;/p&gt;

&lt;p&gt;When a user selects a language from the dropdown, the lang event is triggered, and the selected language value is passed on to the parent component via the language.value variable. This way, the chosen language setting can be used throughout the entire application.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;langSelection&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;../data/lang.json&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;ref&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&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;langs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;langSelection&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;lang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;defineEmits&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lang&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;select&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"lang"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"p-1 text-sm rounded-lg text-gray-700"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"block px-4 py-2 hover:bg-gray-100"&lt;/span&gt;
        &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"language in langs"&lt;/span&gt;
        &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"language.text"&lt;/span&gt;
        &lt;span class="na"&gt;:value=&lt;/span&gt;&lt;span class="s"&gt;"language.value"&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;"() =&amp;gt; $emit('lang', language.value)"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;language&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;flag&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt; &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;language&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/select&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;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Footer Component
&lt;/h2&gt;

&lt;p&gt;Let's delve into the Footer Component, which comprises two components - &lt;code&gt;FooterMobile.vue&lt;/code&gt; and &lt;code&gt;FooterDesktop.vue&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  FooterMobile.vue
&lt;/h3&gt;

&lt;p&gt;Starting with &lt;code&gt;FooterMobile.vue&lt;/code&gt;, it's a simple div element styled using TailwindCSS. The component receives the &lt;code&gt;social&lt;/code&gt; array as a prop, which is iterated using the &lt;code&gt;v-for&lt;/code&gt; directive. Each object in the &lt;code&gt;social&lt;/code&gt; array is defined as &lt;code&gt;link&lt;/code&gt;. To display the social media links based on the user's language settings, the &lt;code&gt;v-if&lt;/code&gt; directive checks whether the &lt;code&gt;link.tags&lt;/code&gt; array includes the string &lt;code&gt;mobile&lt;/code&gt;, and if it includes the string &lt;code&gt;all&lt;/code&gt; (for all languages) or the &lt;code&gt;lang&lt;/code&gt; variable (for each specific language). If the v-if directive evaluates to &lt;code&gt;true&lt;/code&gt;, the &lt;code&gt;div&lt;/code&gt; element with the corresponding social media icon and reference is displayed. The &lt;code&gt;a&lt;/code&gt; element has an &lt;code&gt;href&lt;/code&gt; attribute with the value of the &lt;code&gt;link.url&lt;/code&gt; variable, and the &lt;code&gt;img&lt;/code&gt; element has a &lt;code&gt;src&lt;/code&gt; attribute with the value of the &lt;code&gt;link.icon&lt;/code&gt; variable. The &lt;code&gt;alt&lt;/code&gt; attribute has the value of the &lt;code&gt;link.name&lt;/code&gt; variable, which is essential for web accessibility.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;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;lang&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;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="na"&gt;social&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;Array&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="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex justify-center my-2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"link in social"&lt;/span&gt; &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"link.url"&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;"
          link.tags.includes('mobile') &amp;amp;&amp;amp;
          (link.tags.includes('all') || link.tags.includes(lang))
        "&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mx-3"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;:href=&lt;/span&gt;&lt;span class="s"&gt;"link.url"&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;:src=&lt;/span&gt;&lt;span class="s"&gt;"`/social/$&lt;/span&gt;{link.icon}`"
            :alt="link.name"
            width="25"
            height="25"
        /&amp;gt;&lt;span class="nt"&gt;&amp;lt;/a&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&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  FooterDesktop.vue
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;FooterDesktop.vue&lt;/code&gt; component is only different from the &lt;code&gt;FooterMobile.vue&lt;/code&gt; component in that the &lt;code&gt;v-if&lt;/code&gt; directive checks if the &lt;code&gt;link.tags&lt;/code&gt; array includes the string &lt;code&gt;desktop&lt;/code&gt; instead of the string &lt;code&gt;mobile&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&amp;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;lang&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;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="na"&gt;social&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;Array&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="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex justify-center my-2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"link in social"&lt;/span&gt; &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"link.url"&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;"
          link.tags.includes('desktop') &amp;amp;&amp;amp;
          (link.tags.includes('all') || link.tags.includes(lang))
        "&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mx-3"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;:href=&lt;/span&gt;&lt;span class="s"&gt;"link.url"&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;:src=&lt;/span&gt;&lt;span class="s"&gt;"`/social/$&lt;/span&gt;{link.icon}`"
            :alt="link.name"
            width="25"
            height="25"
        /&amp;gt;&lt;span class="nt"&gt;&amp;lt;/a&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&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  App.vue
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;App.vue&lt;/code&gt; component is the parent component. It imports the &lt;code&gt;social.json&lt;/code&gt; file and assigns it to the &lt;code&gt;social&lt;/code&gt; variable. The &lt;code&gt;lang&lt;/code&gt; variable is initialized with the value &lt;code&gt;en&lt;/code&gt;. The &lt;code&gt;lang&lt;/code&gt; variable is passed to the &lt;code&gt;FooterMobile.vue&lt;/code&gt; and &lt;code&gt;FooterDesktop.vue&lt;/code&gt; components as a prop. The &lt;code&gt;lang&lt;/code&gt; variable is passed to the &lt;code&gt;FooterMobile.vue&lt;/code&gt; and &lt;code&gt;FooterDesktop.vue&lt;/code&gt; components via the &lt;code&gt;lang&lt;/code&gt; event emitted by the &lt;code&gt;LanguageSelect.vue&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;useWindowSize&lt;/code&gt; is a composition function from the &lt;code&gt;@vueuse/core&lt;/code&gt; package. It returns the &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; of the browser window. The &lt;code&gt;width&lt;/code&gt; variable is used to determine if the &lt;code&gt;FooterMobile.vue&lt;/code&gt; or &lt;code&gt;FooterDesktop.vue&lt;/code&gt; component should be displayed.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;defineAsyncComponent&lt;/code&gt; is a function from the &lt;code&gt;vue&lt;/code&gt; package. It is used to define an asynchronous component. The &lt;code&gt;FooterMobile.vue&lt;/code&gt; and &lt;code&gt;FooterDesktop.vue&lt;/code&gt; components are imported asynchronously.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;:lang&lt;/code&gt; is a shorthand for &lt;code&gt;:lang="lang"&lt;/code&gt;. &lt;code&gt;@lang&lt;/code&gt; is a shorthand for &lt;code&gt;@lang="changeLang"&lt;/code&gt;. The &lt;code&gt;changeLang&lt;/code&gt; function is called when the &lt;code&gt;lang&lt;/code&gt; event is emitted by the &lt;code&gt;LanguageSelect.vue&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;:social&lt;/code&gt; is a shorthand for &lt;code&gt;:social="social"&lt;/code&gt;. The &lt;code&gt;social&lt;/code&gt; variable is passed to the &lt;code&gt;FooterMobile.vue&lt;/code&gt; and &lt;code&gt;FooterDesktop.vue&lt;/code&gt; components as a prop.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;NavigationLanguageSelect&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;./components/NavigationLanguageSelect.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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useWindowSize&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;@vueuse/core&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;ref&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineAsyncComponent&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="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;socialMedia&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;./data/social.json&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;social&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;socialMedia&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;FooterMobile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defineAsyncComponent&lt;/span&gt;&lt;span class="p"&gt;(()&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./components/FooterMobile.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;FooterDesktop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defineAsyncComponent&lt;/span&gt;&lt;span class="p"&gt;(()&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./components/FooterDesktop.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useWindowSize&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;lang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;changeLang&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newLang&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;lang&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;newLang&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-pink-300"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;nav&lt;/span&gt;
      &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fixed top-0 h-12 w-screen flex items-center justify-between z-10 bg-pink-300"&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"ml-3"&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;src=&lt;/span&gt;&lt;span class="s"&gt;"./assets/logo200black.svg"&lt;/span&gt;
          &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"logo of Oleg Rõbnikov Web Development"&lt;/span&gt;
          &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"150"&lt;/span&gt;
          &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"70"&lt;/span&gt;
        &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mr-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;NavigationLanguageSelect&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"changeLang"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;main&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"h-screen mt-12 mb-10 [&amp;amp;&amp;gt;p]:m-6 [&amp;amp;&amp;gt;p]:p-2 [&amp;amp;&amp;gt;p]:leading-6"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-xl text-center m-6"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Oleg Rõbnikov Web Development&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-lg text-center m-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        Responsive and Language Sensitive Footer
      &lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
        Current language is changed to &lt;span class="nt"&gt;&amp;lt;strong&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/strong&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;. Please note that language select doesn't change the language of this
        text. It is there to demonstrate how the footer changes based on the
        language selected.
      &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
        Width of the window is &lt;span class="nt"&gt;&amp;lt;strong&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;px&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt;. Try to resize the
        window. The footer will change based on the width of the window.
      &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
        Footer is the usual place for all your social media links like Facebook,
        Twitter, etc. As your website becomes more diverse and you add languages
        and media, the footer becomes overcrowded with all the icons. Most of
        these icons are not used by one part of your audience, while others are
        a mere distraction for another part of the website's visitors
      &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
        Let's show our visitors links to social media that they are more likely
        to use based on their language and the type of device they are using!
      &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;footer&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"fixed bottom-0 h-10 z-10 w-full"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;FooterMobile&lt;/span&gt;
        &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"width &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt; &lt;span class="err"&gt;769"&lt;/span&gt;
        &lt;span class="na"&gt;:lang=&lt;/span&gt;&lt;span class="s"&gt;"lang"&lt;/span&gt;
        &lt;span class="na"&gt;:social=&lt;/span&gt;&lt;span class="s"&gt;"social"&lt;/span&gt;
      &lt;span class="nt"&gt;/&amp;gt;&amp;lt;FooterDesktop&lt;/span&gt; &lt;span class="na"&gt;v-else&lt;/span&gt; &lt;span class="na"&gt;:lang=&lt;/span&gt;&lt;span class="s"&gt;"lang"&lt;/span&gt; &lt;span class="na"&gt;:social=&lt;/span&gt;&lt;span class="s"&gt;"social"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/footer&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;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

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

&lt;p&gt;Hope you will find this way of creating responsive and language sensitive footer useful. If you have any questions or suggestions, please leave a comment below. Also, would be nice to know what solution you are using for displaying social media links in your footer. Thanks for reading!&lt;/p&gt;

&lt;p&gt;This repository is available on [GitHub]: &lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Divewitholeg" rel="noopener noreferrer"&gt;
        Divewitholeg
      &lt;/a&gt; / &lt;a href="https://github.com/Divewitholeg/footer-social" rel="noopener noreferrer"&gt;
        footer-social
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Responsive and Language Aware Vue 3 Footer&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;This is a responsive and language aware footer component for Vue 3. Blogging in several languages inevitably brings you to the point where you have a lot of accounts and links to share. Many of these social platforms are language specific or target either a mobile or desktop only audience. This footer component is designed to be responsive and language aware. It will display the appropriate social links and icons based on the language and device type (by screen width).&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Details&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;The process of creation of this component is described in DETAILS.md.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Vue 3 + Vite&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 &lt;code&gt;&amp;lt;script setup&amp;gt;&lt;/code&gt; SFCs, check out the &lt;a href="https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup" rel="nofollow noopener noreferrer"&gt;script setup docs&lt;/a&gt; to learn more.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Recommended IDE Setup&lt;/h2&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://code.visualstudio.com/" rel="nofollow noopener noreferrer"&gt;VS Code&lt;/a&gt; + &lt;a href="https://marketplace.visualstudio.com/items?itemName=Vue.volar" rel="nofollow noopener noreferrer"&gt;Volar&lt;/a&gt; (and disable Vetur) + &lt;a href="https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin" rel="nofollow noopener noreferrer"&gt;TypeScript Vue Plugin (Volar)&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Project&lt;/h2&gt;…&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Divewitholeg/footer-social" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



</description>
      <category>beginners</category>
      <category>vue</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
