<?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: Menilek Techane</title>
    <description>The latest articles on DEV Community by Menilek Techane (@menilek).</description>
    <link>https://dev.to/menilek</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%2F124906%2F127a0dcb-e42b-4a30-9172-41031ba832b1.jpeg</url>
      <title>DEV Community: Menilek Techane</title>
      <link>https://dev.to/menilek</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/menilek"/>
    <language>en</language>
    <item>
      <title>The Refactoring Dilemma: Tidy Now, After… or Never?</title>
      <dc:creator>Menilek Techane</dc:creator>
      <pubDate>Fri, 28 Nov 2025 17:13:30 +0000</pubDate>
      <link>https://dev.to/menilek/when-it-comes-to-refactoring-code-should-we-tidy-first-5df8</link>
      <guid>https://dev.to/menilek/when-it-comes-to-refactoring-code-should-we-tidy-first-5df8</guid>
      <description>&lt;p&gt;At work in my team we didn’t have an agreed upon approach to refactoring. Therefore, the question of how, when and why we refactor was left up to us which can lead to inconsistency and large Merge Requests (MRs) at a minimum and &lt;del&gt;utter despair and destruction&lt;/del&gt; bigger issues that I’ll leave you to imagine😉&lt;/p&gt;

&lt;p&gt;I recently read an informative book on the subject of refactoring called Tidy First by Kent Beck. Kent refers to a range of refactoring techniques which he calls ‘tidyings’ and argues that we adopt them as a form of ‘geek self care’ over the 122 pages of the book. The most pertinent part of the book concerning us, questions when should we refactor?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqjwwzo5tpstlfnxbeily.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqjwwzo5tpstlfnxbeily.png" alt="Tidy First? By Kent Beck" width="756" height="1359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before we discuss when and why, it is important to understand what kinds of changes we can make regarding refactoring aka tidying. Changes to a codebase can largely be split into either behavioural changes or structural changes. Behavioural changes are your feature requests and fixes which extend a system. Structural changes however, seek to maintain the existing behaviour within a system but augment the structure oftentimes for our own benefit.&lt;/p&gt;

&lt;p&gt;For example, we may reorganise the order (aka flow) of code within a class/component/file to better aid our understanding. It is these structural changes that we are concerned with when we talk about refactoring. With this distinction in mind, let’s now address the when and why.&lt;/p&gt;

&lt;p&gt;Consider the scenario where we are faced with introducing a feature request to an existing Platform system (remember this is a behavioural change). Let’s say we see some issues with the codebase whilst attempting to introduce this new behaviour. Maybe we notice that the functions we plan to extend lack types. Should we tidy first? In this scenario, the payoff is immediate and you know exactly what to do and how. Changes of this nature are like keeping the kitchen clean as we cook. This example is a no-brainer, of course we should tidy first - notice the change is small and can be completed immediately, unlike introducing typing across all functions in the repo (I’m guilty of this😅). Essentially, it is advisable to tidy first if it will make the behavioural change easier.&lt;/p&gt;

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

&lt;p&gt;Tidying after making a behaviour change is a good option when tidying first doesn’t make sense. This may be because the code is quite tangled or complex so by making our change first, we’d gain a better grasp of how we could improve the structure. This is all dependent on the scale of the change(s). Kent Beck advises that we can tidy after, if the refactoring's are proportionate to the behavioural changes. For example, a 30 minute behavioural change would solicit a 30 minute structural change at a maximum. This seems very generous to me (especially when we consider bigger behavioural changes spanning days) but as a rule of thumb I’d advise that refactoring’s are smaller than the time taken to implement behaviour.&lt;/p&gt;

&lt;p&gt;Kent goes on to argue that we should seek to tidy after a behavioural change when coming back later would be too expensive or if you wouldn’t feel a sense of completion submitting the work without this tidying. This would produce an MR combining a behavioural change with a moderately sized (at best) structural change.&lt;/p&gt;

&lt;p&gt;The third option is to tidy later. This case is fitting when there is a big batch of changes required that offer no immediate payoff and would be better suited to a separate Merge Request. To phrase this another way, you can tidy/refactor in small batches and there is eventual payoff. Once I pushed a change to introduce types to functions across the board which added additional complexity to an MR I had raised. This was a big batch of changes with no immediate payoff. I was encouraged to instead document similar issues in a ticket to come back and make such a change later which prompted me to write this!&lt;/p&gt;

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

&lt;p&gt;The final option is to tidy.. never! This is only appropriate when you’re never going to change the code again - for instance, we have some retired repositories that are unlikely to change. This option is reserved for the smallest number of cases as the majority of code we work with is living and changing which leads us to consider how we will agree to approach and apply the three former methods of tidying.&lt;/p&gt;

&lt;p&gt;After reflecting on the above, I created the following proposal for my team:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An MR can include small ‘tidyings’ that offer immediate benefit. These may be introduced before or after the behavioural change of a feature/fix ticket.&lt;/li&gt;
&lt;li&gt;If the structure change does not offer immediate benefit or is not related to the current behavioural change it can be documented in a ticket to be addressed later.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’d love to hear your thoughts on this! How do you (and your team) handle refactoring code? Thanks for taking the time to read this🤓&lt;/p&gt;

</description>
      <category>refactoring</category>
      <category>books</category>
      <category>methodology</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>TIL (Today I Learned): Tactical Vs Strategic Programming</title>
      <dc:creator>Menilek Techane</dc:creator>
      <pubDate>Mon, 21 Oct 2024 16:42:42 +0000</pubDate>
      <link>https://dev.to/menilek/til-today-i-learned-tactical-vs-strategic-programming-14ae</link>
      <guid>https://dev.to/menilek/til-today-i-learned-tactical-vs-strategic-programming-14ae</guid>
      <description>&lt;p&gt;I've recently splurged on some software development books and came across an interesting concept in &lt;a href="https://www.google.com/search?q=A+Philosophy+of+Software+Design+by+John+Ousterhout&amp;amp;oq=A+Philosophy+of+Software+Design+by+John+Ousterhout&amp;amp;gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIGCAEQLhhAMgYIAhBFGDnSAQc1OTRqMGoxqAIAsAIA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8" rel="noopener noreferrer"&gt;A Philosophy of Software Design by John Ousterhout&lt;/a&gt;. Have a read and consider which approach you and your team members practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Tactical Programming?
&lt;/h2&gt;

&lt;p&gt;As a developer one of your primary goals is to implement and release working code. The Tactical developer works fast and can oftentimes produce more features/bug fixes than their Strategic counterparts. However, the Tactical developer encounters issues within the codebase and takes the short-sighted view to patch over the issues instead of addressing them. In this approach, issues aren't resolved or refactored and instead additional complexity is introduced by extending poorly designed code to introduce their code. We call this complexity: technical debt. They then kick the can down the road when it comes to refactoring 'the big ball of mud' that the codebase has become.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Strategic Programming?
&lt;/h2&gt;

&lt;p&gt;The tenet that 'working code is not enough' sufficiently distinguishes Strategic developers' approach from the Tactical developer. Here, the goal is a great design. Taking a long term view of the codebase considers how to introduce the change whilst also resolving issues along the way. You can think of a Strategic developer as a Steward of your codebase, ensuring the long term health of the code and thereby reducing complexity and technical debt where possible. This might be through proactive investment such as planning the design and weighing up the options before beginning implementation. Alternatively, this could be the result of reactive investment by refactoring an issue encountered during a change.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contrasting Strategic and Tactical approaches
&lt;/h2&gt;

&lt;p&gt;Tactical programming is faster in the short term and has a time and place for instance, producing a proof of concept to validate a concept. However, the shortcuts taken to produce software using this approach will eventually work against yourself and your team resulting in incremental degradations in productivity.&lt;br&gt;
Strategic programming will prove to be slower initially. This can be down to proactive planning prior to implementation of a feature or due to the improvement of poor design encountered whilst attempting to introduce a feature. Yet, it is these investments of time that will add up over the course of time to benefit developer productivity and gradually reduce technical debt.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdw6uc68t5f6zym1ntv8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdw6uc68t5f6zym1ntv8.png" alt="Tactical and Strategic code contrasted by time and progress" width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tactical programming in the Wild
&lt;/h2&gt;

&lt;p&gt;John Ousterhout coined the term 'Tactical Tornado' for the individual that takes tactical programming to the extreme. This takes the old Facebook motto, 'Move fast and break things' to its limit. Even Facebook realised, with time that this motto was not serving their best interests as the quality of their codebases degraded. The motto then changed to 'Move fast with stable infrastructure', then simply 'Move fast' and now 'Move fast together'. Tactical Tornadoes might be praised by management for their high output, but those that work alongside them will oftentimes have to pick up the slack by addressing their poorly designed code. This, then makes the team members look slow in contrast and exacerbates the relationships within the team and management.&lt;/p&gt;

&lt;h2&gt;
  
  
  My experience
&lt;/h2&gt;

&lt;p&gt;I have experienced both approaches whilst working as a developer. Occasionally, the needs of the business pressure folks to prioritise speed, this is especially true within Startups, unfortunately leading to new technical debt. A good code/peer review process will push back against some changes with a preference for a more strategic approach e.g: Why is it designed like this? Can we try such and such approach instead please.&lt;/p&gt;

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

&lt;p&gt;After reading this, I hope you gained some value. I have been guilty of programming tactically in the past and appreciated the examples within the book. I would love to hear how you mitigate tactical programming within your place of work. My personal favourite is a great peer review process however, sharing this concept with my team could reduce complexity and tactical programming prior to it reaching the peer review stage.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>learning</category>
      <category>career</category>
    </item>
    <item>
      <title>Transform your Flashcard Carousel into a Progressive Web App (PWA) in an evening</title>
      <dc:creator>Menilek Techane</dc:creator>
      <pubDate>Mon, 30 Oct 2023 19:34:25 +0000</pubDate>
      <link>https://dev.to/menilek/transform-your-flashcard-carousel-into-a-progressive-web-app-pwa-in-an-evening-10bp</link>
      <guid>https://dev.to/menilek/transform-your-flashcard-carousel-into-a-progressive-web-app-pwa-in-an-evening-10bp</guid>
      <description>&lt;p&gt;Good evening internet! This is my second blog post in what has surprisingly become a series. In the first post (read it &lt;a href="https://dev.to/menilek/create-a-french-flashcard-carousel-in-an-evening-3hc7"&gt;here&lt;/a&gt;), we created this flashcard application (try it &lt;a href="https://flashcard-tutorial.vercel.app/" rel="noopener noreferrer"&gt;here&lt;/a&gt;) with the intention of helping language learners learn words of interest using &lt;a href="https://v3.vuejs.org/" rel="noopener noreferrer"&gt;Vue&lt;/a&gt;, &lt;a href="https://vitejs.dev/" rel="noopener noreferrer"&gt;Vite&lt;/a&gt; and &lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt;. In this post we will extend the application by turning it into a Progressive Web App (PWA) all in a single evening!&lt;/p&gt;

&lt;h3&gt;
  
  
  What exactly is a PWA?
&lt;/h3&gt;

&lt;p&gt;PWAs bring the best of both worlds from platform specific apps (IOS &amp;amp; Android) and web apps into one solution. PWAs can be downloaded and installed directly from the browser or via the App/Play Store and appear on the device like any other app. My favourite benefit of PWAs is that they can be used without network connectivity. This is mighty helpful for this app and many others when I'm travelling and want to cram in some last minute revision but don't have access to the internet. For example, you might be on a plane or bored on a train and can't access your mobile data/a WiFi network.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting started
&lt;/h3&gt;

&lt;p&gt;You can find the respository &lt;a href="https://github.com/Menilek/flashcard-tutorial" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Before we dive in, please note that the &lt;code&gt;main&lt;/code&gt; branch runs the flashcard app and the &lt;code&gt;PWA&lt;/code&gt; branch offers the complete flashcard PWA. Our goal in this tutorial is to learn what a PWA is and the steps we must take to transform our web app into a progressive web app.&lt;br&gt;
If you are following along from the first tutorial great, though, we will spend less time focussing on deploying the app in this tutorial. For the sake of simplicity, complete your work on the &lt;code&gt;main&lt;/code&gt; branch as this will make deployments smooth (unless you're a wizz with Vercel and know how to configure builds from other branches).&lt;/p&gt;

&lt;p&gt;Clone the repository then let's get started! 🤓&lt;/p&gt;
&lt;h3&gt;
  
  
  Installing &lt;a href="https://www.npmjs.com/package/vite-plugin-pwa" rel="noopener noreferrer"&gt;vite-plugin-pwa&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Vite has a plugin that converts a Single Page App (SPA) into a PWA. This is awesome and very versatile as it isn't restricted to working with Vue (the JavaScript (JS) framework used in this tutorial), &lt;a href="https://react.dev/" rel="noopener noreferrer"&gt;React&lt;/a&gt; or any other JS library/framework supported by Vite.&lt;/p&gt;

&lt;p&gt;Issue the following command within your terminal/command windows within the repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i vite-plugin-pwa --save-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that vite-plugin-pwa is installed we can add it into our vite.config.js file like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { VitePWA } from "vite-plugin-pwa";

export default defineConfig({
  plugins: [
    vue(),
    VitePWA()
  ]
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Transforming our application
&lt;/h3&gt;

&lt;p&gt;Now we can begin the serious work of turning our app into something that we can install on our devices. PWAs have a number of requirements that we must meet to enable us to install our app locally.&lt;/p&gt;

&lt;p&gt;We will now take the steps to figure out the necessary requirements for our PWA. Let's build our app using the &lt;code&gt;npm run build&lt;/code&gt; command in the terminal. Once this is complete inspect the output in your terminal; you will see the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;building for production...
✓ 15 modules transformed.
dist/registerSW.js               0.13 kB
dist/manifest.webmanifest        0.17 kB
dist/index.html                  0.57 kB │ gzip:  0.34 kB
dist/assets/index-200d626d.css   3.29 kB │ gzip:  1.05 kB
dist/assets/index-27c61d9b.js   64.32 kB │ gzip: 25.25 kB

PWA v0.16.5
mode      generateSW
precache  5 entries (66.72 KiB)
files generated
  dist\sw.js
  dist\workbox-27b29e6f.js
✓ built in 3.07s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that the built application has been generated, issue the &lt;code&gt;npm run serve&lt;/code&gt; command to view the app in your browser. It is typical for web apps that can be installed as PWAs to indicate this with an install icon within your browser's search bar like so:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fighinjm3mzmjud4panyz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fighinjm3mzmjud4panyz.png" alt="Install PWA icon" width="575" height="79"&gt;&lt;/a&gt;&lt;br&gt;
As this is not yet available to us we must investigate why. We can use the Developer Tools to view the Application tab for insights and errors like so:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzs13jnsfob65mhenhv0c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzs13jnsfob65mhenhv0c.png" alt="App Manifest errors" width="800" height="426"&gt;&lt;/a&gt;&lt;br&gt;
We have a number of errors that we must first resolve before we can attempt to rebuild our app and check if it can be installed again. The errors we have received concern our web app manifest (this was one of our build outputs: manifest.webmanifest). VitePWA enables us to provide a manifest object to the VitePWA plugin in the vite.config.js file, feel free to explore the VitePWA docs to learn more &lt;a href="https://vite-pwa-org.netlify.app/guide/pwa-minimal-requirements.html#web-app-manifest" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Web App Manifest
&lt;/h3&gt;

&lt;p&gt;This is a set of criteria that informs the browser that the app can be installed and information about said app. This includes but is not limited to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt;, &lt;code&gt;short_name&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;theme_color&lt;/code&gt;, &lt;code&gt;background_color&lt;/code&gt; and &lt;code&gt;display&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;icons&lt;/code&gt; and optionally &lt;code&gt;screenshots&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To learn more about potential members of the manifest file check &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Manifest" rel="noopener noreferrer"&gt;this&lt;/a&gt; out.&lt;/p&gt;

&lt;p&gt;We must now populate the aforementioned fields. Within the public directory some icons and screenshots have been provided. We can reference these within our manifest. You may want to include your own icons and screenshots. You can generate your own icons for your PWA &lt;a href="https://favicon.io/favicon-converter/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Within the VitePWA plugin in the &lt;code&gt;vite.config.js&lt;/code&gt; file add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default defineConfig({
  plugins: [
    vue(),
    VitePWA({
    manifest: {
        name: "French Flashcards",
        short_name: "Français Flashcards",
        description: "Install this flashcard app for quick reference on the go! \nAvoid loading this again and again; train your mind whenever you feel like it, even when you don't have an internet connection!",
        theme_color: "#ffffff",
        background_color: "#ffffff",
        display: "standalone",
        icons: [
        {
            src: "/192x192.png",
            sizes: "192x192",
            type: "image/png",
            purpose: ""
          },
          {
            src: "/512x512.png",
            sizes: "512x512",
            type: "image/png",
            purpose: ""
          }
        ],
        screenshots:[
          {
            src: "/narrow-screenshot.jpg",
            sizes: "438x841",
            type: "image/jpg",
            form_factor: "narrow"
          },
          {
            src: "/wide-screenshot.png",
            sizes: "1280x668",
            type: "image/png",
            form_factor: "wide"
          },
        ]
      }
    })
  ]
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, you may wish to update the manifest with screenshots of your own. Please ensure that the sizes and file formats accurately reflect those of your screenshots. The Applications tab in the Dev Tools might inform if they do not meet the necessary criteria.&lt;/p&gt;

&lt;p&gt;With the manifest object populated, let's build the app again using &lt;code&gt;npm run build&lt;/code&gt; followed by &lt;code&gt;npm run serve&lt;/code&gt; to preview the newly generated build. There should be no errors, if there are you will need to follow the suggestions in your Dev Tools then repeat this build and serve process until they are all resolved.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing our application
&lt;/h3&gt;

&lt;p&gt;Now that the code is complete the next step is to install the app. Click the install icon within the browser's search bar (if you are on a desktop/laptop) and you will be presented with the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk6ftd7hkyvpnse4pryny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk6ftd7hkyvpnse4pryny.png" alt="Install PWA on Desktop" width="800" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alternatively, on a mobile this will be your view!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjqbz1pi2a9bf7fkj80x3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjqbz1pi2a9bf7fkj80x3.jpg" alt="Install PWA on mobile" width="800" height="1683"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you are happy with your code, commit it and push your changes. If you are following along from the first tutorial, Vercel will pick up these changes and deploy your new PWA!🎉&lt;/p&gt;

&lt;p&gt;This concludes the tutorial! Thanks for reading and following along. As always, I'd love to hear how you got on and any ideas you have to take this app to the next level!🚀&lt;/p&gt;

</description>
      <category>pwa</category>
      <category>vue</category>
      <category>vite</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Create a French Flashcard Carousel in an evening</title>
      <dc:creator>Menilek Techane</dc:creator>
      <pubDate>Sun, 22 Oct 2023 22:01:05 +0000</pubDate>
      <link>https://dev.to/menilek/create-a-french-flashcard-carousel-in-an-evening-3hc7</link>
      <guid>https://dev.to/menilek/create-a-french-flashcard-carousel-in-an-evening-3hc7</guid>
      <description>&lt;p&gt;Hello internet! This is my first blog post and we will be building a mobile friendly French Flashcard application &lt;a href="https://flashcard-tutorial.vercel.app/" rel="noopener noreferrer"&gt;(try it here)&lt;/a&gt;. If you are learning a language or gearing up for travel this simple tool is for you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introduction to Vue, Vite &amp;amp; Vercel
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://v3.vuejs.org/" rel="noopener noreferrer"&gt;Vue 3&lt;/a&gt;, in it's own words: &lt;em&gt;is a progressive framework for building user interfaces&lt;/em&gt;. Vue enables developers to create dynamic Single-page Applications (SPA) that rewrite the current web page with new data from the application's web server. This approach to web development sees us advance from creating many HTML pages and loading them with our web server ultimately producing an increasingly seamless process more akin to a native app.&lt;/p&gt;

&lt;p&gt;What is &lt;a href="https://vitejs.dev/" rel="noopener noreferrer"&gt;Vite&lt;/a&gt; I hear you ask, Vite is french for 'quick' and is a build tool we will use to bundle and serve our application. If you are familiar with Webpack, the Vue-CLI or even Create-React-App this will feel like a Concorde amongst Pigeons!&lt;/p&gt;

&lt;p&gt;Last but not least, &lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt; is a platform that boasts the ability to provide a frictionless developer experience when deploying and serving our application's content. This is what we will use to host our application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequesites
&lt;/h3&gt;

&lt;p&gt;Before we get started it is important to note that this article assumes a good grasp of JavaScript. You will need both &lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Node version &amp;gt;=12.0.0.&lt;/a&gt; and &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;NPM&lt;/a&gt; installed. A familiarity with Vue is helpful but not essential though worry not, we'll have code samples galore and an accompanying repo available &lt;a href="https://github.com/Menilek/flashcard-tutorial" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Now let's get started!&lt;/p&gt;

&lt;h3&gt;
  
  
  Scaffolding our App
&lt;/h3&gt;

&lt;p&gt;First we need to scaffold our Vue app with Vite. Use the following command and select Vue.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init vite@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will go ahead and use Vue without TypeScript for now.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fai961v84phcv0c73avos.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fai961v84phcv0c73avos.png" alt="Vite CLI steps to create a Vue application" width="800" height="289"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once we've completed the above we can navigate into our application's directory, run &lt;code&gt;npm install&lt;/code&gt; and top it off with &lt;code&gt;npm run dev&lt;/code&gt;. Your browser should popup displaying boilerplate output like so:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh8bgq0twk44vrb3ko257.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh8bgq0twk44vrb3ko257.png" alt="Boilerplate Vue 3 application generated using Vite" width="800" height="569"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Installing Vue3-Carousel
&lt;/h3&gt;

&lt;p&gt;We will use the awesome &lt;a href="https://ismail9k.github.io/vue3-carousel/" rel="noopener noreferrer"&gt;Vue3-Carousel&lt;/a&gt; to create our flashcard Carousel. First, we need to install it using:&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 vue3-carousel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next up we want to create a &lt;code&gt;carousel.css&lt;/code&gt; file in the assets folder within the src directory. This will style all of our carousels, go ahead and paste the following inside it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.carousel__slide&amp;gt;.carousel__item {
  transform: scale(1);
  opacity: 0.5;
  transition: 0.5s;
}
.carousel__slide--visible&amp;gt;.carousel__item {
  opacity: 1;
  transform: rotateY(0);
}
.carousel__slide--next&amp;gt;.carousel__item {
  transform: scale(0.9) translate(-10px);
}
.carousel__slide--prev&amp;gt;.carousel__item {
  transform: scale(0.9) translate(10px);
}
.carousel__slide--active&amp;gt;.carousel__item {
  transform: scale(1.1);
}
.carousel__item {
  min-height: 200px;
  width: 100%;
  background-color: var(--vc-clr-primary);
  color: var(--vc-clr-white);
  font-size: 20px;
  border-radius: 8px;
  display: flex;
  justify-content: center;
  align-items: center;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creating our Carousel
&lt;/h3&gt;

&lt;p&gt;Vue 3 components allow us to define JavaScript functions, templates for rendering our page and styles all in one place! Go ahead and create a &lt;code&gt;Days.vue&lt;/code&gt; component within the components directory like so:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flsas7ay9nn6tap5m5yup.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flsas7ay9nn6tap5m5yup.png" alt="Days Vue component" width="800" height="527"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This component will be responsible for rendering the French words for Monday through to Sunday. We need to import the newly created &lt;code&gt;carousel.css&lt;/code&gt; file as well as some Components from Vue3-carousel using the below snippets then we can begin defining our functions and rendering the Carousel. We will need to add the following to our &lt;code&gt;Days.vue&lt;/code&gt; component within the script tags:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Carousel, Slide, Pagination, Navigation } from 'vue3-carousel';
import 'vue3-carousel/dist/carousel.css';
import '../assets/carousel.css';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Within Vue components we can use the content defined within the Script tags to help us render output within our Template tags.&lt;/p&gt;

&lt;p&gt;Now, our application requires some French content (feel free to deviate and put a Spanish/Mandarin/Amharic spin on this)! We shall begin by creating an object that will hold the day in English as a key and the day in French as the corresponding value. Let's call it FrenchDays and define it using the sample below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const FrenchDays = {
    Monday: "Lundi",
    Tuesday: "Mardi",
    Wednesday: "Mercredi",
    Thursday: "Jeudi",
    Friday: "Vendredi",
    Saturday: "Samedi",
    Sunday: "Dimanche"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congrats! You've made it to the fun part where we get into the cool parts of Vue.js and render our Carousel. We've got our FrenchDays object (or whichever language you've chosen you cheeky polyglot!) and we want to loop through these and create a &lt;em&gt;slide&lt;/em&gt; for each word aka value in our object.&lt;/p&gt;

&lt;p&gt;Vue has a special &lt;em&gt;directive&lt;/em&gt; just for this called &lt;code&gt;v-for&lt;/code&gt;, see more &lt;a href="https://v3.vuejs.org/guide/list.html#v-for-with-an-object" rel="noopener noreferrer"&gt;here&lt;/a&gt;. This directive allows us to iterate through the properties of an object. There is a lot going on in the code below so we shall dissect it step by step:&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;h2&amp;gt;Days&amp;lt;/h2&amp;gt;
    &amp;lt;Carousel :itemsToShow="2" :wrapAround="true"&amp;gt;
        &amp;lt;Slide v-for="day in FrenchDays" :key="day"&amp;gt;
            &amp;lt;div class="carousel__item"&amp;gt;{{ day }}&amp;lt;/div&amp;gt;
        &amp;lt;/Slide&amp;gt;
        &amp;lt;template #addons&amp;gt;
            &amp;lt;Navigation /&amp;gt;
            &amp;lt;Pagination /&amp;gt;
        &amp;lt;/template&amp;gt;
    &amp;lt;/Carousel&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's examine the Slide component. This is using the &lt;code&gt;v-for&lt;/code&gt; directive to iteratively create Slides for each property in our &lt;code&gt;FrenchDays&lt;/code&gt; object. You might also notice this: &lt;code&gt;:key="day"&lt;/code&gt; what this does is give each Slide a unique key. This key helps Vue determine what has changed within the virtual Document Object Model (DOM) and what hasn't.&lt;/p&gt;

&lt;p&gt;If you are interested in learning what the Navigation and Pagination components are or what the itemsToShow and wrapAround props are feel free to play with their values or refer to the Vue3-Carousel docs &lt;a href="https://ismail9k.github.io/vue3-carousel/getting-started.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ok, we've done a lot of work, what do we have to show for it so far? We'll need to render our Days component to see what all the fuss is about first! In the &lt;code&gt;App.vue&lt;/code&gt; file within the root of our /src directory we want to make some changes as this currently renders the boilerplate HelloWorld.vue component generated by Vite. Instead we want to import and render the Days component and we will do this with the following:&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;script setup&amp;gt;
  import Days from './components/Days.vue'
&amp;lt;/script&amp;gt;

&amp;lt;template&amp;gt;
  &amp;lt;Days /&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;style&amp;gt;
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
&amp;lt;/style&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After we save, Vite will quickly pull in our changes and our browser should show us:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F60yazl1n46ncctm1tn0f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F60yazl1n46ncctm1tn0f.png" alt="Carousel showing Days of the week in French" width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Toggling the Language
&lt;/h3&gt;

&lt;p&gt;We are nearing the final hurdle. How do we toggle between French and English? There are many ways in which this can be implemented (and I am curious how you might have done it; please do share in the comments 🤓) but we will always require a user clicking/tapping on a Slide within our Carousel to kick off the change. As always, Vue has a &lt;a href="https://v3.vuejs.org/guide/events.html" rel="noopener noreferrer"&gt;directive for that&lt;/a&gt; named &lt;code&gt;v-on:click&lt;/code&gt; or better yet &lt;code&gt;@click&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Essentially, we require a &lt;em&gt;click&lt;/em&gt; event that will trigger a function that toggles our French word into English and vice-versa. We also need a way of knowing which word is being shown so that we know which word to show when clicked. Let's update our Slide component within &lt;code&gt;Days.vue&lt;/code&gt; by adding the click directive and a function we want to trigger.&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;Slide v-for="day in FrenchDays" :key="day"&amp;gt;
    &amp;lt;div class="carousel__item" @click="toggle(day)"&amp;gt;{{ day }}&amp;lt;/div&amp;gt;
&amp;lt;/Slide&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We also need a way to determine whether a flash card shows English or French. This will allow a single flashcard to toggle without toggling all of the flashcards - this will ensure we don't spoil our language learning fun!&lt;/p&gt;

&lt;p&gt;We will track the &lt;em&gt;state&lt;/em&gt; of a flashcard using a Ref. Refs let us create variables enriched with the power of &lt;em&gt;reactive and mutable reference objects&lt;/em&gt;, what that means is that if there is a change to the value of such a variable it will be detected and trickle down to anywhere else that uses that variable, notifying it of the new value. One thing we need to note is that with the introduction of reactive variables in Vue3 using ref, we must use &lt;code&gt;.value&lt;/code&gt; to access their values inside our script block, though this is not the case inside our template (we'll see this in action later).&lt;/p&gt;

&lt;p&gt;First we need to import &lt;code&gt;ref&lt;/code&gt; from Vue like so: &lt;code&gt;import { ref } from 'vue';&lt;/code&gt; within the script tags in our &lt;code&gt;Days.vue&lt;/code&gt; file. &lt;/p&gt;

&lt;p&gt;To make use of &lt;code&gt;ref&lt;/code&gt; we can define the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const MondayRevealed = ref(false);
const TuesdayRevealed = ref(false);
const WednesdayRevealed = ref(false);
const ThursdayRevealed = ref(false);
const FridayRevealed = ref(false);
const SaturdayRevealed = ref(false);
const SundayRevealed = ref(false);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So far so good, time to begin defining the toggle function. The purpose of the toggle function is to invert or toggle the boolean value of a flashcard. Currently, these have all been set to false by default.&lt;/p&gt;

&lt;p&gt;This could be implemented in a number of ways. Using if/else statements or a switch statement are viable options but I recently stumbled upon a way to achieve this succinctly using object literals! I will link to a very handy article &lt;a href="https://dev.to/lukyhenson/replace-your-switch-statement-and-multiple-if-and-else-using-object-literals-en-us-1dec"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Depending on which day/card a user clicks determines which day/card we want to toggle; thereby toggling the boolean value for that day e.g MondayRevealed now equals true.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const toggle = (day) =&amp;gt; {
    const dayMap = {
        Lundi: () =&amp;gt; MondayRevealed.value = MondayRevealed.value ? false : true,
        Mardi: () =&amp;gt; TuesdayRevealed.value = TuesdayRevealed.value ? false : true,
        Mercredi: () =&amp;gt; WednesdayRevealed.value = WednesdayRevealed.value ? false : true,
        Jeudi: () =&amp;gt; ThursdayRevealed.value = ThursdayRevealed.value ? false : true,
        Vendredi: () =&amp;gt; FridayRevealed.value = FridayRevealed.value ? false : true,
        Samedi: () =&amp;gt; SaturdayRevealed.value = SaturdayRevealed.value ? false : true,
        Dimanche: () =&amp;gt; SundayRevealed.value = SundayRevealed.value ? false : true
    }
    dayMap[day]()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break down some of these lines:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Lundi: () =&amp;gt; MondayRevealed.value = MondayRevealed.value ? false : true&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This lines run if the day clicked on is Lundi (French for Monday) then the value for MondayRevealed is updated with the use of a &lt;a href="https://www.freecodecamp.org/news/how-the-question-mark-works-in-javascript/" rel="noopener noreferrer"&gt;ternary operator&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;dayMap[day]()&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On the line above we are invoking the function that corresponds to the value of the key equal to the day passed as an argument. E.g if we were to pass in Jeudi this would match the following&lt;br&gt;
&lt;code&gt;() =&amp;gt; ThursdayRevealed.value = ThursdayRevealed.value ? false : true&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We now have our Carousel and a toggle function; the only thing that remains is a way to show the translated word. This will involve retrieving the English day for a given French day and rendering this within our template.&lt;br&gt;
Luckily enough we have an object named FrenchDays consisting of the days in French and English and must now create a function that will return the English word for a given French day.&lt;/p&gt;

&lt;p&gt;To retrieve the corresponding English key for a French value within the FrenchDays object we have to...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const findKey = (obj, value) =&amp;gt; {
    return Object.keys(obj).find(key =&amp;gt; obj[key] === value);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we can find the English word for a French word in our FrenchDays object we can move onto figuring out how we can render this in our template. This is where the use of our boolean variables comes in handy. To illustrate, imagine we click on Mardi (Tuesday in French), this will toggle the value of TuesdayRevealed to true and if this value is true we want to show the English for that word.&lt;br&gt;
To implement this we can use an object literal again. This time we can accept the day value and map it to the corresponding boolean value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const isWordRevealed = (day) =&amp;gt; {
    const revealMap = {
        Lundi: MondayRevealed.value,
        Mardi: TuesdayRevealed.value,
        Mercredi: WednesdayRevealed.value,
        Jeudi: ThursdayRevealed.value,
        Vendredi: FridayRevealed.value,
        Samedi: SaturdayRevealed.value,
        Dimanche: SundayRevealed.value
    }
    return revealMap[day];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now use &lt;code&gt;isWordRevealed&lt;/code&gt; to render the correct word within our Carousel like so:&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;Slide v-for="day in FrenchDays" :key="day"&amp;gt;
    &amp;lt;div class="carousel__item" @click="toggle(day)"&amp;gt;{{ !isWordRevealed(day) ? day : findKey(FrenchDays, day); }}&amp;lt;/div&amp;gt;
&amp;lt;/Slide&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can go one step further to tidy up our template expression as there is a lot going on within the curly braces. Instead we can store the value within a variable and render that variable within our template like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const dayToShow = (day) =&amp;gt; !isWordRevealed(day) ? day : findKey(FrenchDays, day);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Slide v-for="day in FrenchDays" :key="day"&amp;gt;
    &amp;lt;div class="carousel__item red" @click="toggle(day)"&amp;gt;{{ dayToShow(day) }}&amp;lt;/div&amp;gt;
&amp;lt;/Slide&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should now be able to toggle each flash card independent of the others! 🎉&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb90igvpzvdxsr8nzikwj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb90igvpzvdxsr8nzikwj.gif" alt="A working French flashcard deck" width="600" height="300"&gt;&lt;/a&gt;&lt;br&gt;
A little challenge would be to add flashcards for months, numbers and the seasons! In the gif above you can see I've gone ahead and added months in already.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploying our Flashcard application
&lt;/h3&gt;

&lt;p&gt;The final piece of the puzzle is to deploy the application. We will do this using &lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt;. Before we do this, ensure that you've committed and pushed all your changes to a repository in your Source Control Management provider of choice (Github, Gitlab, Bitbucket etc).&lt;/p&gt;

&lt;p&gt;If you don't already have a Vercel account sign up using the link &lt;a href="https://vercel.com/signup" rel="noopener noreferrer"&gt;here&lt;/a&gt; and then select your Git provider. By connecting to your git provider instead of using your email you can smoothly deploy your project in a couple of clicks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7fgx5g5rtymu8tg3cnhf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7fgx5g5rtymu8tg3cnhf.png" alt="Import your app in Vercel" width="800" height="683"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After selecting your git provider, you will be prompted to select your project to deploy. Select your flashcard application then you'll be prompted by a screen to configure the application. There is no special configuration required for this simple app so we will be good to go with the default options. Click the Deploy button and behold the magic!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjqwmecrzgdgr5bhp9uff.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjqwmecrzgdgr5bhp9uff.png" alt="App deployment configuration screen" width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! You have now deployed your flashcard application. Continue to the Dashboard and click the Visit button to see your work in all it's glory.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8co135mbnken8xwkw13r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8co135mbnken8xwkw13r.png" alt="Successful deployment of the flashcard app" width="800" height="634"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This concludes the tutorial! Thanks for reading and following along. I would love to hear your thoughts, how you used this project and any potential changes you added in the comments. Merci beaucoup 😁&lt;/p&gt;

&lt;p&gt;Stay tuned for the next post in the flashcard series where we will turn this app into a Progressive Web App (PWA)! Suggestions on further extensions to the app are more than welcome. Au revoir😊&lt;/p&gt;

</description>
      <category>vue</category>
      <category>vite</category>
      <category>vercel</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
