<?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: Kieran Roberts</title>
    <description>The latest articles on DEV Community by Kieran Roberts (@kieran6roberts).</description>
    <link>https://dev.to/kieran6roberts</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%2F561722%2Fd2f134e4-eae6-4c69-afa1-f5910e91fc18.png</url>
      <title>DEV Community: Kieran Roberts</title>
      <link>https://dev.to/kieran6roberts</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kieran6roberts"/>
    <language>en</language>
    <item>
      <title>cvrsnap.com: Blog post cover image creator to help you publish quicker</title>
      <dc:creator>Kieran Roberts</dc:creator>
      <pubDate>Fri, 31 Jan 2025 08:04:26 +0000</pubDate>
      <link>https://dev.to/kieran6roberts/cvrsnapcom-blog-post-cover-image-creator-to-help-you-publish-quicker-4ecc</link>
      <guid>https://dev.to/kieran6roberts/cvrsnapcom-blog-post-cover-image-creator-to-help-you-publish-quicker-4ecc</guid>
      <description>&lt;p&gt;Introducing &lt;a href="https://cvrsnap.com/" rel="noopener noreferrer"&gt;cvrsnap.com&lt;/a&gt; 🫰.&lt;/p&gt;

&lt;p&gt;CvrSnap is a free tool I recently built as a small side project and it lets you quickly create blog post cover images that you can download as a PNG. Its designed to help you build something that looks good quickly so you can spend less time designing, and more time publishing. You can customise foreground text and its layout, customise the background, choose provided download dimensions, and more. The editor persists your progress if you need take a pause. Behind the scenes CvrSnap is a 1 page client-side React app built using React Router v7, TypeScript, MantineUI, Zustand, IndexedDB, and SST to provision the services Amazon CloudFront, Amazon S3, and Amazon Route 53.&lt;/p&gt;

&lt;p&gt;I wanted to share the tool with all of you in case it can be of use to you, and also write a little case study for the project. If you are in need of a nice cover image for your next blog post, please do try it out and let me know if theres anything else you would want to make your ideal cover image as quickly as possible. You can reach out to me &lt;a href="https://x.com/Kieran6dev" rel="noopener noreferrer"&gt;@Kieran6Dev&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/kieran6roberts/" rel="noopener noreferrer"&gt;on LinkedIn&lt;/a&gt;, or through the comments here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why did I build this tool?
&lt;/h2&gt;

&lt;p&gt;A blog post cover image is something I need every time I write a new post. I dont have a current template designed (somewhere like Figma) for me to re-use across my posts and I dont want to spend the time designing one because I always find it difficult to settle on something when starting from nothing. I just want to visit some domain, click a few buttons and be done with it. You might ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;But wouldnt it take longer to build the app than to design a new cover template in Figma&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yes. But I am a developer and I thought this would be more fun. Plus it might be useful to someone else.&lt;/p&gt;

&lt;p&gt;I dont care about elaborate blog cover images for my own posts. As long as the title is in the image, and maybe my name as the author. Generic cover images from the internet (Unsplash as an example) are also something I dont care for. With that in mind I set out to build a simple, clean editing user interface where I could go anytime I needed a new blog cover image.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who is the tool for?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Someone who needs a good looking blog cover image with text as the primary foreground, usually for the blog title and author (you can remove the text if you so choose).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You don't want a generic cover image from an internet image platform.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You don't want to spend hours starting from scratch using a design tool. You just want to pick some preset templates, maybe change some font settings etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You want to do all of this in a modern and user-friendly editor.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CvrSnap is also &lt;strong&gt;free&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The live site
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://cvrsnap.com/" rel="noopener noreferrer"&gt;cvrsnap.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kieran6roberts/cvrsnap" rel="noopener noreferrer"&gt;codebase&lt;/a&gt; - (If you like and use the app, take a second to give it a star on GitHub)&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%2Ft0r3hxnzwwbrdoljgfdj.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%2Ft0r3hxnzwwbrdoljgfdj.png" alt="Screenshot of the CvrSnap editor in light mode" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  CvrSnap example covers
&lt;/h2&gt;

&lt;p&gt;Here are some example covers images I quickly built using CvrSnap:&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%2Fp3ctzii3nsnuackvxelw.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%2Fp3ctzii3nsnuackvxelw.png" alt="CvrSnap example image 1" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsgf6dj5w92xmm70u3336.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%2Fsgf6dj5w92xmm70u3336.png" alt="CvrSnap example image 2" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstwf8qndh4fo133uek8a.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%2Fstwf8qndh4fo133uek8a.png" alt="CvrSnap example image 3" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwajk0cb9ryslcj62uzpb.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%2Fwajk0cb9ryslcj62uzpb.png" alt="CvrSnap example image 4" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A very simple landing page&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Editing interface&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Minimum set of customisation options to start with.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;1 click image download in PNG format that accurately resembles the preview.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An editor that would persist the selected design options.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Different download size options.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Light/dark theme toggle.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://reactrouter.com/home" rel="noopener noreferrer"&gt;React Router v7&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.typescriptlang.org/" rel="noopener noreferrer"&gt;TypeScript&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.npmjs.com/package/html-to-image" rel="noopener noreferrer"&gt;&lt;code&gt;html-to-image&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://mantine.dev/" rel="noopener noreferrer"&gt;MantineUI&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://sst.dev/" rel="noopener noreferrer"&gt;SST&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Build Specifics
&lt;/h2&gt;

&lt;h3&gt;
  
  
  React Router v7 &amp;amp; the rendering approach
&lt;/h3&gt;

&lt;p&gt;The backbone of the app is built using React Router v7. I started out development in an SSR approach using React Router as a framework. But during development I realised it would be better served as a single page client side application. There would be no sever side data fetching requirements from external APIs or databases. The key for a dashboard type app is to optimise for snappy UI and quick transitions. SSR has been pushed as a default for a little while now but I dont believe its necessary in all cases, and overkill (possibly a little detrimental) here.&lt;/p&gt;

&lt;p&gt;The new version of React Router was a little confusing to me at first because you can decide to run it as full framework, or as a simple routing library. I think theres work that can be done to better explain this product now its merged with &lt;a href="https://remix.run/" rel="noopener noreferrer"&gt;Remix&lt;/a&gt;. Currently CvrSnap is running using React Router as a framework with &lt;code&gt;SRR: false&lt;/code&gt; in the React Router config to specify we intend to use a single page client rendering strategy. This is primarily due to the fact I started out the app in framework mode without settling on the preferred rendering strategy.&lt;/p&gt;

&lt;p&gt;I will likely refactor to use React Router simply as a routing library instead of the framework option currently in use. I believe this is usually how you would adopt a single page with React Router as described &lt;a href="https://reactrouter.com/home#react-router-as-a-library" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Im currently putting together a small starter kit (not done) for the the tech behind CvrSnap and I have implemented React Router simply for routing there as a trial run which looks good.&lt;/p&gt;

&lt;p&gt;Outside of how the client side rendering is approached here, I am happy with the decision to prefer it to SSR for now.&lt;/p&gt;

&lt;h3&gt;
  
  
  The persistent editor: Zustand + IndexedDB
&lt;/h3&gt;

&lt;p&gt;Before building the app, I knew I wanted to persist the editor state for the user. If the user navigates to a different page, or away from the app, when they come back they should see the same design they left behind.&lt;/p&gt;

&lt;p&gt;Its quite frustrating to use apps in this realm that dont persist your progress. You make some changes, think you are done and finish up, then realise you actually want to adjust something.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🤦 Whoops, now you have to start all over again.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;CvrSnap does not have user authentication, and doesnt need it. Also no external database storage beyond browser based storage. Since no sensitive data needs to be persisted, browser storage becomes a nice solution for the needs of the app. The data that does need to be persisted is simply non-sensitive arbitrary numbers and strings, corresponding to text content, font sizes etc.&lt;/p&gt;

&lt;h4&gt;
  
  
  IndexedDB
&lt;/h4&gt;

&lt;p&gt;The core of the editor state is persisted using IndexedDB. IndexedDB is simply an API for client-side storage of a large amount of structured data. I preferred this option for storing the current cover preview state over &lt;code&gt;Window.localStorage&lt;/code&gt; for a few key reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I would be writing to the storage quite often (as cover settings are updated). Local storage updates are synchronous: blocking the main thread with reads and writes. Therefore performance would likely take a hit.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IndexedDB allows structured data which I would would be working with (objects) without requiring it to be serialised.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IndexedDB can store larger amounts of data, something which might become relevant as the app grows.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;Window.localStorage&lt;/code&gt; is however utilised for a couple of small scale settings like the sidebar open state and sidebar open sections states.&lt;/p&gt;

&lt;p&gt;All the current settings of the active cover image preview are saved using IndexedDB in combination with the state management tool Zustand.&lt;/p&gt;

&lt;p&gt;Note: The only editor state that is not currently persisted are user uploaded images. Users can upload their own image to the background. I didnt want to persist personal images mostly for privacy reasons.&lt;/p&gt;

&lt;p&gt;Zustand is simply a small, fast, barebones state management tool. When you navigate on the client between the &lt;code&gt;/&lt;/code&gt; page and &lt;code&gt;/create&lt;/code&gt; page, that is Zustand persisting your current editor state. I have integrated Zustand with the &lt;code&gt;persist&lt;/code&gt; middleware from &lt;code&gt;zustand/middleware&lt;/code&gt;, allowing you to store the Zustand state in a storage option of your choice. You can see this in effect after you perform the initial page load.&lt;/p&gt;

&lt;p&gt;To demonstrate the approach, here is a simplified solution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;create&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zustand&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="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;del&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;idb-keyval&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;persist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createJSONStorage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;StateStorage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zustand/middleware&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Interact with IndexedDB using the promise based keyval store 'idb-keyval'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;indexDBStorage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;StateStorage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;removeItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;del&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="na"&gt;hasHydrated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="na"&gt;setHasHydrated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;hasHydrated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
   &lt;span class="c1"&gt;// Rest of the state initialisation + update functions&lt;/span&gt;

  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;editor-storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;createJSONStorage&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;indexDBStorage&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="c1"&gt;// Pick the state you want to persist.&lt;/span&gt;
      &lt;span class="na"&gt;partialize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;primaryText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;primaryText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="c1"&gt;// Updating version becomes useful when we have breaking changes&lt;/span&gt;
      &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;onRehydrateStorage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// do something&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHasHydrated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One thing to note about persisting the state in IndexedDB is that the operations are asynchronous. This means the store is hydrated from IndexedDB some time later after store creation (after initial render). Therefore, there is a slight delay in having this data available in the editor. When the storage has been successfully hydrated in the &lt;code&gt;onRehydrateStorage&lt;/code&gt; function, we set the &lt;code&gt;hasHydrated&lt;/code&gt; state to &lt;code&gt;true&lt;/code&gt; and use it wherever its needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dom to image handling
&lt;/h3&gt;

&lt;p&gt;I experimented with several different packages that allow me to capture a DOM node as an image and saw mixed results. I settled on &lt;a href="https://www.npmjs.com/package/html-to-image" rel="noopener noreferrer"&gt;html-to-image&lt;/a&gt; for the time being. So far it seems to be the most accurate representation of the DOM I have, with minimal configuration Crucially I was also able to capture &lt;code&gt;clip-path&lt;/code&gt; elements correctly using html-to-image, an alternative solution I also was experimenting with (&lt;a href="https://html2canvas.hertzen.com/" rel="noopener noreferrer"&gt;html2canvas&lt;/a&gt;) did not support this. The background templates make use of the CSS property &lt;code&gt;clip-path&lt;/code&gt; to create custom backgrounds so this was a dealbreaker. Theres still some optimisation and experimenting I want to do to optimise the final images.&lt;/p&gt;

&lt;p&gt;The logic behind downloading the PNG is pretty simple. The PNG image blob is generated from the DOM with &lt;code&gt;htmlToImage.toBlob&lt;/code&gt;, setting the intended dimensions, quality etc. Then the blob is downloaded on the client with the help of &lt;a href="https://www.npmjs.com/package/file-saver" rel="noopener noreferrer"&gt;file-saver&lt;/a&gt;: &lt;code&gt;fs.saveAs(blob, 'cvrsnap-cover.png')&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  MantineUI
&lt;/h3&gt;

&lt;p&gt;I wasnt looking to spend time writing custom UI elements and design specs for this app. Since there might be some very interactive UI also, I decided to integrate a UI component library. I read good things about the React component library &lt;a href="https://mantine.dev/" rel="noopener noreferrer"&gt;MantineUI&lt;/a&gt; and decided it would be a good fit for the project to get things done quicker. Its open source, TypeScript based, and adaptable to various modern Frameworks. The component list of its core library is extensive and I would need to utilise several different various complex element compositions in the app.&lt;/p&gt;

&lt;p&gt;CSS modules is recommended alongside Mantine and thats what I went for, using CSS variables where helpful. From someone who enjoys TailwindCSS as my primary tool, I was missing it a little here but it was also nice to write regular CSS again. Something which I have not done for a while.&lt;/p&gt;

&lt;h3&gt;
  
  
  Infrastructure
&lt;/h3&gt;

&lt;p&gt;The last piece of the puzzle is the infrastructure. Its been a long time since I had to deploy a client side single page application and I was open to exploring different possibilities.&lt;/p&gt;

&lt;p&gt;Recently I have been diving into learning and building in the cloud using AWS. &lt;a href="https://aws.amazon.com/cloudfront/" rel="noopener noreferrer"&gt;Amazon CloudFront&lt;/a&gt;, &lt;a href="https://aws.amazon.com/s3/" rel="noopener noreferrer"&gt;Amazon S3&lt;/a&gt;, and &lt;a href="https://aws.amazon.com/route53/" rel="noopener noreferrer"&gt;Amazon Route 53&lt;/a&gt; are some of the services I have been exploring and I set on deploying the site this way. What are these services:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CloudFront&lt;/strong&gt; is a web service that speeds up distribution of your static and dynamic web content.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;S3&lt;/strong&gt; is an object storage service where you can store data inside containers called buckets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Route 53&lt;/strong&gt; is a highly available and scalable cloud domain name system (DNS) service.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While I had been experimenting and learning so far mostly using the AWS web interface, for CvrSnap I wanted to define the infrastructure as code (IaC). I briefly thought about using the &lt;a href="https://docs.aws.amazon.com/cdk/v2/guide/home.html" rel="noopener noreferrer"&gt;AWS Cloud Development Kit (AWS CDK)&lt;/a&gt; before coming across the &lt;a href="https://sst.dev/" rel="noopener noreferrer"&gt;Serverless Stack (SST&lt;/a&gt;) and deciding that would be a nice approach. SST is a framework where you define everything your full-stack app needs in code and SST abstracts away a significant amount of the infra configuration and provisioning. Even more so than the AWS CDK. I though this would help me get to production quicker as I am not yet proficient in provisioning resources using the CDK despite working in and around CDK apps a little, then I could explore the CDK at a later date.&lt;/p&gt;

&lt;p&gt;This article on &lt;a href="https://blog.awsfundamentals.com/" rel="noopener noreferrer"&gt;AWSFundamentals&lt;/a&gt; has a great section detailing IaC, AWS CDK, and the benefits of SST if you want more information: &lt;a href="https://blog.awsfundamentals.com/social-stats-dashboard-sst-nextjs#heading-serverless-stack-sst" rel="noopener noreferrer"&gt;blog.awsfundamentals.com/social-stats-dashboard-sst-nextjs#heading-serverless-stack-sst&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Infra provisioning for the static site is taken care of by SST during deployment using a few simple lines of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// infra/web.ts&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;config&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;../config&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;frontend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;sst&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;StaticSite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Frontend&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;packages/frontend&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build/client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pnpm build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;indexPage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;index.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nx"&gt;$app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stage&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;redirects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`www.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have also taken the time to dive into what SST does behind the scenes when calling &lt;code&gt;sst.aws.StaticSite&lt;/code&gt; during my learning sessions, exploring which resources get created and how they interact. For someone who is still relatively new to building in AWS, I found SST to be really neat. I could get to production much faster with infra guaranteed by SST, and spend time digging into the lower level details afterwards.&lt;/p&gt;

&lt;p&gt;Im excited to explore more possibilities if the app ever requires further resources such as functions, storage etc. If you want to explore SST yourself, this resource provided a nice practical walkthrough: &lt;a href="https://guide.sst.dev/" rel="noopener noreferrer"&gt;https://guide.sst.dev/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Getting back to the underlying infra, the static build output built is stored in a general purpose S3 bucket. Public access to the bucket is blocked and only the CloudFront distribution has access to the bucket through origin access control settings. I got to really dive into S3 bucket permissions/policies and origin access control settings when I has having a problem with initial deployments. Turns out my build output path was incorrect 😄, but at least I got to dig down into these topics. Finally after configuring Route 53 DNS service for &lt;code&gt;cvrsnap.com&lt;/code&gt; , traffic could then be routed to the domain using the CloudFront distribution.&lt;/p&gt;

&lt;p&gt;There are multiple guides out there that goes into depth on similar infra step-by-step, search for AWS CloudFront S3 Route 53 and youll find plenty of articles if youre interested.&lt;/p&gt;

&lt;h2&gt;
  
  
  What went well
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Product: Editor
&lt;/h3&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%2F33nbqao50ul0gzb42c28.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%2F33nbqao50ul0gzb42c28.png" alt="A view of the CvrSnap Editor after downloading a cover, with confetti and a success modal" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I believe the app provides what I initially intended. Simple templates and options to get you moving quickly. Early on I was experimenting with a more custom approach, allowing dragging and resizing of text and an overall slightly more interactive editor. But I realised that didnt fit my initial purpose for it not to be complicated and open ended with its options. It has pre-designed layouts and options by design. Data is persisted so the user shouldnt get that feeling of losing something they started. It also feels fast and snappy which is key.&lt;/p&gt;

&lt;p&gt;There is a decent amount of customisation options here, between the text and the backgrounds options and Im happy that you can make covers that dont all look completely identical. Im excited to expand the options here (specifically with more complex templates) while keeping the simplicity of making something look good quickly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Personal: Learning
&lt;/h3&gt;

&lt;p&gt;I took a lot of learning and enjoyment from this project. A first time user of React Router v7, MantineUI, and the whole SST setup, I was able to expand my knowledge significantly. I now have the experience to make decisions between stacks involving these tools in the future. It was a great help in letting me become comfortable working with S3 buckets and CloudFront distributions which fits in nicely with the upskilling Im currently doing.&lt;/p&gt;

&lt;p&gt;There is invaluable knowledge and experience you gain when building your own projects from scratch. From the product development side, infrastructure, backend, continuous integration (CI), analytics, testing etc etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  What can be improved
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Mobile UX
&lt;/h3&gt;

&lt;p&gt;The app is mobile responsive, and while I just released a new update to improve the mobile UX, I think there are still improvements to make here. Things like scroll position when switching sections and adding a scroll top button are two things that come to mind. Previously you would have to scroll to the top to see the preview, but I recently shipped and update so you have access to a preview button wherever you are scrolled which helped the UX significantly there.&lt;/p&gt;

&lt;p&gt;Finally the default cover image text size is a constant. So on mobile it is too large for the preview size. You can manually reduce it to look appropriate but its not ideal. I dont really want to adjust the font size as the screen size changes but I need to do some thinking on this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Customisation options
&lt;/h3&gt;

&lt;p&gt;There can always be more customisation options, as long as they dont add design fatigue to the user since that would defeat the purpose of the app. Im not intending to introduce drag/resizing or anything open ended like that. Things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;More complex background templates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Templates that have a placeholder where you can upload an avatar to the cover.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Background gradients.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Landing page
&lt;/h3&gt;

&lt;p&gt;The current landing is a bare bones one without too much thought. The editor was the primary focus but now thats taking shape, the landing page can get an upgrade.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Improved hero section&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Updated editor image&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;More sections demonstrating the app and cover image details&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  React router: Library or Framework
&lt;/h3&gt;

&lt;p&gt;To run the app as a true client 1 pager, I will probably refactor the app to use React router only for the routing as explained above. This tech debt could have been avoided if I started out this way.&lt;/p&gt;

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

&lt;p&gt;CvrSnap is a free tool designed to help users create custom blog post cover images quickly and easily. Built as a client-side React app, CvrSnap leverages modern technologies like React Router v7, TypeScript, and AWS. The app's editor persistently saves user progress using IndexedDB and Zustand and PNG download is a simple click away.&lt;/p&gt;

&lt;p&gt;If you made it this far, you are my hero. If you use CvrSnap to download an image you use in a blog post, please share the post with me on &lt;a href="https://www.linkedin.com/in/kieran6roberts/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, or &lt;a href="https://bsky.app/profile/kieran6dev.bsky.social" rel="noopener noreferrer"&gt;Bluesky&lt;/a&gt; and Id be happy to read/share.&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%2Fo97tvqazty9oey8lhgko.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%2Fo97tvqazty9oey8lhgko.png" alt="Thanks for reading sign created in CvrSnap" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>generalprogramming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>My process for writing blog articles with actionable steps you can follow</title>
      <dc:creator>Kieran Roberts</dc:creator>
      <pubDate>Fri, 30 Apr 2021 12:25:38 +0000</pubDate>
      <link>https://dev.to/kieran6roberts/my-process-for-writing-blog-articles-with-actionable-steps-you-can-follow-2all</link>
      <guid>https://dev.to/kieran6roberts/my-process-for-writing-blog-articles-with-actionable-steps-you-can-follow-2all</guid>
      <description>&lt;p&gt;If you've ever tried writing blog articles yourself I'm sure you've realized it is not an easy thing. There are difficulties at every stage of the process from planning all the way through to publishing. I want to share my process from beginning to end which so far seems to be working &lt;strong&gt;for me&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Everyone is different. What works for me might not work for you. But in the very least it will give you some idea of how you can go about it. &lt;/p&gt;

&lt;p&gt;Consistency is key and consistency becomes easier if you are able to break down the problem into manageable steps.&lt;/p&gt;

&lt;p&gt;Here are my steps for writing articles 👏.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Blogging Steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Pick a topic

&lt;ul&gt;
&lt;li&gt;What should I write about?&lt;/li&gt;
&lt;li&gt;Use your experiences with the chosen topic&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Plan the the main points

&lt;ul&gt;
&lt;li&gt;Write out the main headings&lt;/li&gt;
&lt;li&gt;Show the reader a preview of the main topics&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Write the introduction

&lt;ul&gt;
&lt;li&gt;Start with what you want the article to achieve&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Start writing 

&lt;ul&gt;
&lt;li&gt;Write/read/check and repeat&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Proof read your work

&lt;ul&gt;
&lt;li&gt;From the heading to the last character&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Publishing

&lt;ul&gt;
&lt;li&gt;Where to publish?&lt;/li&gt;
&lt;li&gt;Create a custom article preview image&lt;/li&gt;
&lt;li&gt;Share it&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1) Pick a Topic
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What should I write about?&lt;/strong&gt; 🤔&lt;/p&gt;

&lt;p&gt;This is usually one of my biggest problems for new writers. It was difficult for me to know what to write about at first. I would think that I didn't know enough about something to write a whole article on it. But I soon realized you don't need to be an expert.&lt;/p&gt;

&lt;p&gt;Just sharing your experience on a topic is enough. More than enough, it's awesome 😉. If you're stuck on ideas I will offer a solution that's worked for me thus far.&lt;/p&gt;

&lt;p&gt;Think about what you're currently learning/ working on or recently worked with. &lt;/p&gt;

&lt;p&gt;Maybe your learning about the CSS Box Model. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write about that!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Or maybe your working on or recently finished a personal project. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write about that!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Or perhaps you've been optimizing your site for performance scores.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write about that!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As developers we're always working on something so why not use that as a focus for your articles.&lt;/p&gt;

&lt;p&gt;I promise that if you keep writing consistently then ideas will start to flow and it will become easier. Now I regularly have multiple drafts on the go which is great because now I can plan ahead. &lt;/p&gt;

&lt;p&gt;If you think of an idea &lt;strong&gt;write a few points inside a draft&lt;/strong&gt; or wherever else you can in case you forget later on!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use your experiences with the chosen topic&lt;/strong&gt; 🙂&lt;/p&gt;

&lt;p&gt;Great! Now you have a topic and you've chosen something you've recently worked with and because you have, you are in a position where you can apply your own experience. It is an awesome thing when you can apply this knowledge to your articles.&lt;/p&gt;

&lt;p&gt;One of my earlier articles was all about the benefits I had personally experienced since taking up a blog. Because it was something I was actively working with I was able to provide tips I knew were real.&lt;/p&gt;

&lt;p&gt;You can check out that article here 👉 &lt;a href="https://blog.kieranroberts.dev/why-its-awesome-for-new-developers-to-blog-as-they-learn" rel="noopener noreferrer"&gt;Why it's awesome for new developers to blog as they learn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It will help your articles to connect with the readers if you apply your own experience to the problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.) Plan the main points
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Write out the main headings&lt;/strong&gt; ✍&lt;/p&gt;

&lt;p&gt;Now that you have a great topic in mind let's start with the article 😃.&lt;/p&gt;

&lt;p&gt;Start by listing the main topics that you expect to cover in the article and format them into headers. This gives you an idea of the structure of your article and also means you won't forget to cover an important point later on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Show the reader a preview of the main topics&lt;/strong&gt; 😃&lt;/p&gt;

&lt;p&gt;This is something I like to do but it's up to you. Unless it's a very short article I like to see a content list near the top that gives me an outline of the main topics covered. You can use the headings you created and turn them into a list.&lt;/p&gt;

&lt;p&gt;It's nice to cater to the reader when possible. Not every reader is going to read the whole article. Listing the main content covered gives them the ability to better find the things they might be looking for.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.) Write the introduction
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Start with what you want the article to achieve&lt;/strong&gt; 👏&lt;/p&gt;

&lt;p&gt;I sometimes write my introduction before I do anything else. Usually I know the problem I want to write about and what I hope to achieve with the article. &lt;/p&gt;

&lt;p&gt;You could also write it at the end when you know exactly what the outcome of the article is. Sometimes the article goes a different direction than you were expecting so this might be a good idea. It's up to you!&lt;/p&gt;

&lt;p&gt;These are my primary tips for writing it 👇&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep it concise. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It doesn't need to be longer than a couple of paragraphs. If it has to be then maybe there is enough content for multiple articles and you should consider splitting things up.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Outline the main topic/problem&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Give the reader a quick summary of the overall topic. This could be explaining what it means or why it is a thing/problem/amazing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What you hope the reader will get from your article&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, explain briefly what the reader should know after reading through your piece.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.) Start writing
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Write/read/check and repeat&lt;/strong&gt; ✍&lt;/p&gt;

&lt;p&gt;I'm not going to get too deep into writing tips in this article but I will offer a few things to look out for. &lt;/p&gt;

&lt;p&gt;Try to keep it concise with simple language. When I look back to my earlier articles I noticed I was not doing this. My sentences were long and I was using far too many breaks. It breaks the reading flow for the reader.&lt;/p&gt;

&lt;p&gt;Another tip is to watch out for what you include in the article. Keep this in mind when your writing 👇.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Work through your headings from top to bottom and write about the things that will help you accomplish the tasks/problem/topic you outlined in the introduction&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If it doesn't help with this then leave it out or link to another article that goes into more depth.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.) Proofread your work
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;From the heading to the last character&lt;/strong&gt; 🧐&lt;/p&gt;

&lt;p&gt;Great! Now you might think you're done? &lt;strong&gt;Guess again&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It's time to read back through the article from top to the bottom. Read every sentence from the heading to the final character. You'd be surprised to see all of the mistakes I've caught in the headings 😅.&lt;/p&gt;

&lt;p&gt;By doing this you'll not only catch spelling mistakes but you'll spot sentences that don't make sense in the flow of the rest of the work. &lt;/p&gt;

&lt;p&gt;Once you get in the flow of writing you become oblivious to spelling and grammar errors so this is a really important step (I make a lot of typing errors 😂).&lt;/p&gt;

&lt;p&gt;But after reading through you can catch them before anyone finds out 😋.&lt;/p&gt;

&lt;h3&gt;
  
  
  6.) Publishing
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Where to publish?&lt;/strong&gt; 🤔&lt;/p&gt;

&lt;p&gt;The final step is to publish your article. &lt;strong&gt;Congrats!! You're nearly there.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are a couple of great platforms that I would recommend. Firstly here on Dev.to. It has a great community and your articles are almost guaranteed to be viewed by lots of people. It's where I started writing and I would be happy to recommend this platform to others.&lt;/p&gt;

&lt;p&gt;Another great option is over on &lt;a href="https://hashnode.com/" rel="noopener noreferrer"&gt;Hashnode&lt;/a&gt;. The great thing about Hashnode is that you can publish your articles to your own domain while still seeing the flow of traffic to your articles that you get from a community blogging site.&lt;/p&gt;

&lt;p&gt;If you like to cross-post your articles to other sites then you should be careful. Don't forget to set the canonical link to the location it was first posted. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a custom article preview image&lt;/strong&gt; 🙂&lt;/p&gt;

&lt;p&gt;Adding a preview image to the top of your article can help it to stand out from the crowd. It's not too difficult to come up with something reasonable. &lt;/p&gt;

&lt;p&gt;If you've read any of my other articles you will have noticed I created a template that I customize each time. Yours doesn't have to be like this but it might be good to create something that is unique to you.&lt;/p&gt;

&lt;p&gt;As a developer you could create one yourself using CSS like I did or you could use a design tool like Figma. An attractive preview image can help attract readers to your content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Share it&lt;/strong&gt; 🤝&lt;/p&gt;

&lt;p&gt;Now you have it deployed it's time to share the article! It's likely that you use social media so share it with friends and other like-minded developers. &lt;/p&gt;

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

&lt;p&gt;I hope this look into my process is able to help or motivate you in some way. It is important to know that you don't have to be an expert to blog. It's given me so much in so little time since I started two months ago. &lt;/p&gt;

&lt;p&gt;Just start and see where you end up!!&lt;/p&gt;

&lt;p&gt;You can find me over &lt;a href="https://twitter.com/Kieran6dev" rel="noopener noreferrer"&gt;@Kieran6dev&lt;/a&gt; so come and say hi! If you liked the article please leave some likes or consider following me for future articles.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/kieran6roberts" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.buymeacoffee.com%2Fbutton-api%2F%3Ftext%3DBuy%2520me%2520a%2520beer%26emoji%3D%25F0%259F%258D%25BA%26slug%3Dkieran6roberts%26button_colour%3DFFDD00%26font_colour%3D000000%26font_family%3DCookie%26outline_colour%3D000000%26coffee_colour%3Dffffff" width="217.0" height="50"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks!! 👋&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>1 year into coding 🎉. Here are the tips I would go back and give myself</title>
      <dc:creator>Kieran Roberts</dc:creator>
      <pubDate>Fri, 23 Apr 2021 17:04:54 +0000</pubDate>
      <link>https://dev.to/kieran6roberts/1-year-into-coding-here-are-the-tips-i-would-go-back-and-give-myself-41d2</link>
      <guid>https://dev.to/kieran6roberts/1-year-into-coding-here-are-the-tips-i-would-go-back-and-give-myself-41d2</guid>
      <description>&lt;p&gt;In March 2020 I began my coding journey which means I have now been learning about web-development for 1 full year 🎈! I've learned a lot along the way but there are a few things I would tell myself if I could travel back in time.&lt;/p&gt;

&lt;p&gt;Let's not waste any more time 👏.&lt;/p&gt;

&lt;h2&gt;
  
  
  Content
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Don't be afraid of joining developer communities&lt;/li&gt;
&lt;li&gt;You can't learn everything so don't try&lt;/li&gt;
&lt;li&gt;Take notes or better yet write a blog&lt;/li&gt;
&lt;li&gt;Become comfortable with Git and command line basics early&lt;/li&gt;
&lt;li&gt;You learn the most when building projects&lt;/li&gt;
&lt;li&gt;Consistency is key&lt;/li&gt;
&lt;li&gt;Have fun&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1.) Don't be afraid of joining developer communities
&lt;/h2&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%2F26rek8hvs76d66ms5mfg.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%2F26rek8hvs76d66ms5mfg.png" alt="illustration of cuommunity" width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is probably &lt;strong&gt;my number 1 tip&lt;/strong&gt;. It took me around 9 months before I had the confidence to branch out of my own bubble and connect with other developers. I was hesitant about putting myself out there. About putting my work into the open. Thinking I wasn't qualified to share ideas or that I didn't have enough knowledge to teach.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I was completely wrong&lt;/strong&gt;😅&lt;/p&gt;

&lt;p&gt;The developer community is extremely supportive and there are loads of aspiring developers openly sharing their progress with each other. Check out the &lt;a href="https://twitter.com/search?q=%23100DaysOfCode&amp;amp;src=typeahead_click" rel="noopener noreferrer"&gt;#100DaysOfCode&lt;/a&gt; on Twitter for some examples.&lt;/p&gt;

&lt;p&gt;Sharing and learning from other developers is a key part of your progression. It can also be a great source of inspiration for your future work or perhaps a source of networking for you. These are a few of the amazing benefits I can think of 👇.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can learn from other devs in similar positions&lt;/li&gt;
&lt;li&gt;You can learn from more experienced devs &lt;/li&gt;
&lt;li&gt;It can be a great confidence builder&lt;/li&gt;
&lt;li&gt;You can get feedback on your work&lt;/li&gt;
&lt;li&gt;You can network with other devs&lt;/li&gt;
&lt;li&gt;You could make some friends&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and so much more. Just make the jump and I promise it is the best thing you can do for yourself as an aspiring developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.) You can't learn everything so don't try
&lt;/h2&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%2Fo1w51pc10bxb0vd49xw4.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%2Fo1w51pc10bxb0vd49xw4.png" alt="illustration of person learning by reading" width="800" height="535"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a front-end developer I realized that there is always going to be some new shiny tech that becomes &lt;em&gt;the thing&lt;/em&gt;. It is impossible to become a master of everything so don't try.&lt;/p&gt;

&lt;p&gt;Do your best to focus on a few key technologies and try to master them. As a learning front-end developer I was jumping into different CSS frameworks, build tools and more. It really wasn't necessary for someone who is leaning front-end development early on. &lt;/p&gt;

&lt;p&gt;If you get good at regular CSS then applying it to different CSS frameworks becomes easy when there is a good use-case for them. Once your comfortable by all means try out a framework but don't expect to become good with all of them.&lt;/p&gt;

&lt;p&gt;Instead I would now tell myself to focus on the key tech and get good with them before moving on to the shiny stuff. For me as a front-end developer I would focus on the following 👇.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTML&lt;/li&gt;
&lt;li&gt;CSS&lt;/li&gt;
&lt;li&gt;Vanilla JavaScript&lt;/li&gt;
&lt;li&gt;1 JavaScript Framework&lt;/li&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;li&gt;Testing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3.) Take notes or better yet write a blog
&lt;/h2&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%2Fzmk0ez9my4gy6rrjz2s5.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%2Fzmk0ez9my4gy6rrjz2s5.png" alt="illustration of typewriter" width="800" height="561"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I didn't really take many notes while I was learning over the past year. I wish I had now. Recently I found myself trying to explain simple topics out loud and found that I struggled to articulate answers.&lt;/p&gt;

&lt;p&gt;Having some of my own notes to quickly reference would have been extremely useful 🙄.&lt;/p&gt;

&lt;p&gt;Keeping notes as you learn has so many incredible benefits. Writing will help you reinforce the knowledge you gain and can give you a reference for the future. You could also take it a step further and turn your notes into a blog for others to read. &lt;/p&gt;

&lt;p&gt;If you would like to know more about the benefits of blogging while learning web-development then check out my article &lt;a href="https://blog.kieranroberts.dev/why-its-awesome-for-new-developers-to-blog-as-they-learn" rel="noopener noreferrer"&gt;Why it's awesome for new developers to blog as they learn&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  4.) Become comfortable with Git &amp;amp; command line basics early
&lt;/h2&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%2Fkwzvgf2uvtqcy921cz41.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%2Fkwzvgf2uvtqcy921cz41.png" alt="illustration of person working with Git" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even as a front-end developer the command line is something we use on a daily basis. It can be intimidating but even learning some basics can drastically improve your workflow. Things like folder navigation and running executables are valuable skills.&lt;/p&gt;

&lt;p&gt;As well as this I would tell myself to &lt;strong&gt;not be intimidated by version control specifically using Git&lt;/strong&gt;. As I prepare to start applying for my first web-development role I have been diving deeper into Git. It has made me realize how little I actually knew about it and what it can do.&lt;/p&gt;

&lt;p&gt;The reality is that it is a very important skill to know if you plan on working as a developer in the industry. When you become comfortable with the code itself and you start building projects I highly recommend you practice with Git. &lt;/p&gt;

&lt;p&gt;Treat it how you would CSS or JavaScript and you will definitely fell the benefits later on.&lt;/p&gt;

&lt;h2&gt;
  
  
  5.) You learn the most when building projects
&lt;/h2&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%2Fois34qsnbeu5zxizxday.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%2Fois34qsnbeu5zxizxday.png" alt="Illustration of person building a brick wall" width="800" height="505"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Building projects is awesome. That feeling when you host a project you built on the web for others to see and use is hard to beat. I have found that is also the thing that will help you learn the most.&lt;/p&gt;

&lt;p&gt;It is easy to follow tutorials and early on it is a great way to become comfortable with the basics. But at some point it is important to break away and attempt to build your own projects. Start small and if you get stuck then of course use all of the amazing resources we have online to help you. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Google is every developers best friend&lt;/strong&gt; 😃.&lt;/p&gt;

&lt;p&gt;The process of running into problems, googling for solutions and implementing fixes is the iteration that will see you solving your own problems. This is key to becoming a confident developer. Even if the project doesn't turn out how you hoped, &lt;strong&gt;it is better than not trying at all&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The important thing is that you try it yourself first. Look up some simple projects and try to personalize it in some way based on your likes or interests. &lt;/p&gt;

&lt;p&gt;Get building!&lt;/p&gt;

&lt;h2&gt;
  
  
  6.) Consistency is key
&lt;/h2&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%2Fh7u8xkfzxqh29e4bbl7h.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%2Fh7u8xkfzxqh29e4bbl7h.png" alt="illustration of person working on computer" width="800" height="663"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Consistency is the key to becoming proficient at most things. If you work at it everyday then you are sure to see some progress. The same is true for coding.&lt;/p&gt;

&lt;p&gt;Unfortunately not everyone can put all of their time into it. We all have commitments. But if you can dedicate a little time everyday then you are on the right track. &lt;/p&gt;

&lt;p&gt;Try to have a specific topic in mind for the session and put all of your focus into it. Could be 30 minutes or it might be a couple of hours. &lt;strong&gt;As long as your focus is on the work for that time the consistency will be key to your development&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  7.) Have fun
&lt;/h2&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%2Fsqj3av1p1fzspnyj408i.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%2Fsqj3av1p1fzspnyj408i.png" alt="illustration of people celebrating" width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sometimes coding can be frustrating. We've all been there. It's easy to get frustrated and feel downbeat when we run into problems. But try to remember why we became developers in the first place. For me at least it is because &lt;strong&gt;It's fun and I love it!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's sometimes easy to lose sight of this. Now that I have a little more experience I'm getting better at controlling my code frustration and find that I can now walk away leaving it for later when I come up with a better solution. There was a time when I would stress over a problem for hours at a time.&lt;/p&gt;

&lt;p&gt;I now realize that I would become frustrated because I'm passionate about coding and wanting to be as good as I possibly can. I love what I do and I try to keep this in mind which is easy to do &lt;em&gt;most of the time&lt;/em&gt; 🙂.&lt;/p&gt;

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

&lt;p&gt;Those were some of my the tips I would go back in time and tell myself and I think they are great tips for any developers learning their trade. I hope you are able to take something with you and if you did then please tell me about it.&lt;/p&gt;

&lt;p&gt;You can do so &lt;a href="https://twitter.com/Kieran6dev" rel="noopener noreferrer"&gt;@Kieran6dev&lt;/a&gt; where I'm always active or in the comments below.&lt;/p&gt;

&lt;p&gt;If you could go back a year(or to the beginning) and give yourself a piece of advice, what would it be?&lt;/p&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>motivation</category>
    </item>
    <item>
      <title>My most frequent React errors and how you fix them</title>
      <dc:creator>Kieran Roberts</dc:creator>
      <pubDate>Thu, 15 Apr 2021 17:29:36 +0000</pubDate>
      <link>https://dev.to/kieran6roberts/my-most-frequent-react-errors-and-how-you-fix-them-3epp</link>
      <guid>https://dev.to/kieran6roberts/my-most-frequent-react-errors-and-how-you-fix-them-3epp</guid>
      <description>&lt;p&gt;When using the popular JavaScript library &lt;strong&gt;React&lt;/strong&gt; there are some errors/problems that seem to pop up time and time again. They can be easily avoided in most situations and I would like to share them with you so you can spend less time debugging and more time writing code.&lt;/p&gt;

&lt;p&gt;So let's not waste any time and take a look at our problems and how we can solve them 👏.&lt;/p&gt;

&lt;h2&gt;
  
  
  Content
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Forgetting to add keys with a list of elements&lt;/li&gt;
&lt;li&gt;Not returning a list correctly&lt;/li&gt;
&lt;li&gt;Not cleaning up certain &lt;code&gt;useEffect&lt;/code&gt; side-effects&lt;/li&gt;
&lt;li&gt;Not wrapping adjacent JSX elements&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1) Forgetting to add keys with a list of elements
&lt;/h2&gt;

&lt;p&gt;In React we often find ourselves with lists of data that we want to map into elements or components. This is often done using the &lt;code&gt;Array.prototype.map&lt;/code&gt; function to pass data from each index of the array to the element or component through props.&lt;/p&gt;

&lt;p&gt;When we do this without adding a &lt;code&gt;key&lt;/code&gt; prop React will complain that each element is missing a &lt;code&gt;key&lt;/code&gt;. Essentially it is just a special attribute to which we pass a string. It should be a unique string which will distinguish it from its siblings that we are also mapping.&lt;/p&gt;

&lt;p&gt;React says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Example Problem
&lt;/h3&gt;

&lt;p&gt;Let's map some data before adding keys to our elements to see the problem in action. Here we will have a simple component that deconstructs &lt;code&gt;foods&lt;/code&gt; from the prop object. &lt;code&gt;foods&lt;/code&gt; is just an array of objects and it looks like 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%2Faynbwk91yr5jlgljin1n.jpeg" 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%2Faynbwk91yr5jlgljin1n.jpeg" alt="Our example data set" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and our component 👇&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%2Fgfnz5f5zb8824bw5jmlr.jpeg" 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%2Fgfnz5f5zb8824bw5jmlr.jpeg" alt="mapped elements without key prop" width="800" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and finally the warning from React 👇.&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%2F7tqdfkx2q257k3e1s8k3.jpeg" 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%2F7tqdfkx2q257k3e1s8k3.jpeg" alt="missing key warning" width="800" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;To fix this all we have to do is pass a unique key to the element we are returning. Often the data we are mapping comes from a fetch request and usually includes an id. Fortunately we have and &lt;code&gt;id&lt;/code&gt; property we can use from our set of data. Let's add our &lt;code&gt;key&lt;/code&gt; property.&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%2F3sgpazxug25q2biw3yyx.jpeg" 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%2F3sgpazxug25q2biw3yyx.jpeg" alt="After adding our key prop" width="800" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we didn't have a unique id we would need to have an alternative solution. Often people use the index of the array as the &lt;code&gt;key&lt;/code&gt; but this is not recommended for any set of data where positions in the list  may change. It can negatively affect the state of the component. See here for more information &lt;a href="https://reactjs.org/docs/reconciliation.html#recursing-on-children" rel="noopener noreferrer"&gt;Reactjs - Reconciliation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Instead we could create our key by combining the &lt;code&gt;name&lt;/code&gt; property with the current date/time using the JavaScript &lt;code&gt;Date&lt;/code&gt; object.&lt;/p&gt;

&lt;h2&gt;
  
  
  2) Not returning a list correctly
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;To return or not to return&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In React as we have already seen we are often iterating over some data . Perhaps we are filtering a data set down to a specific sub-set or mapping to the DOM. Whatever it is there are a few pitfalls we need to watch out for when it comes to returning our data otherwise we might be left scratching our heads.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example Problem
&lt;/h3&gt;

&lt;p&gt;A frustrating example can be seen when we map a data set to some elements or components. We expect to see the or elements on screen with the data we map into them. However we see nothing.&lt;/p&gt;

&lt;p&gt;No error, no warning no data 🤨. In this situation it is likely that you're not returning your result correctly.&lt;/p&gt;

&lt;p&gt;For our example we will be mapping our array of foods to some elements so we can show it to the user. It should look like 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%2F122x3666lk8yq402vlo2.jpeg" 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%2F122x3666lk8yq402vlo2.jpeg" alt="Correct return demonstration" width="800" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Instead our data will appear to be missing 👇.&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%2F0voo88efxeb1517g91hn.jpeg" 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%2F0voo88efxeb1517g91hn.jpeg" alt="Incorrect return demonstration" width="800" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me show you some examples where we won't see the output that we were expecting. We are passing our array to our component and destructuring it from the prop object the same as before.&lt;/p&gt;

&lt;p&gt;Can you spot the problem below.&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%2Fkxxzljj3qbkv7bwb3jai.jpeg" 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%2Fkxxzljj3qbkv7bwb3jai.jpeg" alt="Example of not returning correclty" width="800" height="602"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Correct! Here we are not returning anything either implicitly or explicitly using the &lt;code&gt;return&lt;/code&gt; keyword.&lt;/p&gt;

&lt;p&gt;Let's take a look at another  👇.&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%2Fehudzt3vrnge6vlwe95q.jpeg" 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%2Fehudzt3vrnge6vlwe95q.jpeg" alt="Second example of not returning correctly" width="800" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This time we include the &lt;code&gt;return&lt;/code&gt; keyword but what we are actually doing here is returning &lt;code&gt;undefined&lt;/code&gt;. The code below the return statement never gets read.&lt;/p&gt;

&lt;p&gt;There are other examples you might run into but let's take a look at the different solutions we can use.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;Let's start with the explicit returns. If we move our &lt;code&gt;article&lt;/code&gt; element in line with the return statement all is well. &lt;/p&gt;

&lt;p&gt;See below 👇&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%2Fhoe073skhml4ye3ww5eq.jpeg" 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%2Fhoe073skhml4ye3ww5eq.jpeg" alt="Example of correct explicit return" width="800" height="602"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We could also wrap the return elements with parenthesis like 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%2Fvu8wlvg7hwnbvc05k0m1.jpeg" 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%2Fvu8wlvg7hwnbvc05k0m1.jpeg" alt="Example of correct explicit return" width="800" height="645"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another option is to return the result implicitly which means we can forget the &lt;code&gt;return&lt;/code&gt; statement and the function body curly braces. Check it out 👇.&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%2F4pnma5xsrgt90orpi3uz.jpeg" 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%2F4pnma5xsrgt90orpi3uz.jpeg" alt="Example of correct implicit return" width="800" height="602"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;or inline like 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%2Fvwhyahs7vr1ciae8k9ra.jpeg" 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%2Fvwhyahs7vr1ciae8k9ra.jpeg" alt="Example of correct implicit return" width="800" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The choice is up to you as long as you are aware of the possible pitfalls you encounter. If the data appears to be missing make sure you check your map function carefully and make sure you are actually returning correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  3) Not cleaning up certain &lt;code&gt;useEffect&lt;/code&gt; side-effects
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;useEffect&lt;/code&gt; hook allows us to perform side-effects inside functional components. Certain side-effects that we perform in this hook require cleanup. This means that when the component unmounts we can run a special function. Sometimes this is necessary otherwise we might see an error warning us of memory leaks in our apps.&lt;/p&gt;

&lt;p&gt;Consider a &lt;code&gt;useEffect&lt;/code&gt; that performs some kind of asynchronous api call before setting some component state to the response. If the response is slow and the component unmounts before we receive a response then we might be trying to update the state of a component that is not mounted.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example Problem
&lt;/h3&gt;

&lt;p&gt;Let's take a look at two different situations where we might add some cleanup to our &lt;code&gt;useEffect&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The first is a situation is where we have an asynchronous fetch request inside our &lt;code&gt;useEffect&lt;/code&gt; hook. The user of the application navigates to a different page before we receive the response from the fetch call. This is our component before we add a cleanup function to the&lt;code&gt;useEffect&lt;/code&gt; hook.&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%2F5rj1gd1wierg6gnp0y42.jpeg" 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%2F5rj1gd1wierg6gnp0y42.jpeg" alt="React useEffect before cleanup" width="800" height="894"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we are fetching some data after the component mounts and then using the result to set the components state. Finally we map the state to the DOM. Relatively straight forward 👍.&lt;/p&gt;

&lt;p&gt;The second situation is where we add some &lt;code&gt;eventListeners&lt;/code&gt; to some DOM elements. If the component unmounts we are going to want to remove these listeners.&lt;/p&gt;

&lt;p&gt;Check it out before we clean it up 👇&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%2F499up6s9qrzp1pzu3nxe.jpeg" 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%2F499up6s9qrzp1pzu3nxe.jpeg" alt="Before adding our cleanup function to useEffect" width="800" height="637"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The logic inside our &lt;code&gt;useEffect&lt;/code&gt; is irrelevant for this simple example. All that matters is that we are adding an event listener and that will need to be cleaned up.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;We begin by adding a cleanup function to our &lt;code&gt;useEffect&lt;/code&gt; like 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%2Fzc80vrurjmo1mwn3sku3.jpeg" 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%2Fzc80vrurjmo1mwn3sku3.jpeg" alt="useEffect cleanup function" width="800" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is simply a function that we add to the bottom of our &lt;code&gt;useEffect&lt;/code&gt; hook where we add our cleanup logic.&lt;/p&gt;

&lt;p&gt;Now to cleanup our fetch request we can use the DOM api &lt;code&gt;AbortController&lt;/code&gt; which is available in JavaScript. It allows us to abort web requests which we will use to abort out of the fetch request whenever the component unmounts. Let's see it in action 👇.&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%2F9w8umjpzistkxliewf5f.jpeg" 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%2F9w8umjpzistkxliewf5f.jpeg" alt="React useEffect fetch cleanup function" width="800" height="1134"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First we create a controller by using the constructor with &lt;code&gt;new AbortController()&lt;/code&gt; and then we pass its property signal to the fetch request. This association of controller signal to the request allows us to abort the request by calling &lt;code&gt;abort()&lt;/code&gt; inside the cleanup function.&lt;/p&gt;

&lt;p&gt;Now we are ensuring that we don't have any requests coming back to a component that is not mounted.&lt;/p&gt;

&lt;p&gt;The cleanup function for our &lt;code&gt;eventListener&lt;/code&gt; example is simple which you might have already guessed. All we need to do is remove any listeners we create using &lt;code&gt;removeEventListener&lt;/code&gt; in our cleanup function. Let's see it in action 👇.&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%2Fb1kpyb11qjjglsvfcznv.jpeg" 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%2Fb1kpyb11qjjglsvfcznv.jpeg" alt="React useEffect listener cleanup example" width="800" height="798"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hopefully now like me you won't forget to clean up your effects 😉.&lt;/p&gt;

&lt;h2&gt;
  
  
  4) Not wrapping adjacent JSX elements
&lt;/h2&gt;

&lt;p&gt;This one is simple to debug but I though I would include it because I sometimes forget to do it until React starts shouting at me 😅. &lt;/p&gt;

&lt;p&gt;Adjacent JSX elements must be wrapped with an enclosing tag. There are a few different ways we can do this based on our requirements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example Problem
&lt;/h3&gt;

&lt;p&gt;If we want the wrapper to be part of the DOM for structural purposes then go with some semantic element where possible (&lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt; etc.). I usually wouldn't recommend wrapping elements with a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; although it is fine if you want the wrapper for styling purposes.&lt;/p&gt;

&lt;p&gt;Often we do not want the wrapper to part of the DOM because it serves no purpose there. We would only be adding markup only to shut React up. &lt;/p&gt;

&lt;p&gt;Let's see the problem in action.&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%2Fcqazhx6510ne536nd7sj.jpeg" 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%2Fcqazhx6510ne536nd7sj.jpeg" alt="Example component not wrapping adjacent JSX" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and the error it throws 👇&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%2Fnnsg3wjzehikaz569hpn.jpeg" 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%2Fnnsg3wjzehikaz569hpn.jpeg" alt="Adjacent JSX error" width="800" height="305"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is likely that your code editor gave you a warning about this before the error pops up which is great.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;Fortunately React provides us with a solution. We can use &lt;code&gt;React.Fragment&lt;/code&gt; to wrap our adjacent JSX if we do not require the wrapper to be part of the DOM. Let's say this is the case for the following example.  &lt;/p&gt;

&lt;p&gt;First let's use &lt;code&gt;React.Fragment&lt;/code&gt; before we see how we can simplify it further.&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%2Fheuepu77lynxvhgfdw5o.jpeg" 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%2Fheuepu77lynxvhgfdw5o.jpeg" alt="Wrapping adjacent JSX with React.Fragment" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we don't need any attributes or keys for our fragment we can shorten &lt;code&gt;React.Fragment&lt;/code&gt; to this &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; empty tag. Have a look below.&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%2Fyrpc9gm4sanncl3vx1f4.jpeg" 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%2Fyrpc9gm4sanncl3vx1f4.jpeg" alt="Wrapping adjacent JSX with React.Fragment shortened syntax" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally if we are mapping some data to JSX as we have previously seen then we need to add keys to our wrapping element. If all we have is adjacent JSX then we can wrap our elements with &lt;code&gt;React.Fragment&lt;/code&gt; and add a unique key to the fragment.&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%2F6mblf5y2gjt8p3d6atcg.jpeg" 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%2F6mblf5y2gjt8p3d6atcg.jpeg" alt="Wrapping our mapped adjacent JSX with React.fragment and a unique key" width="800" height="560"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Thanks for getting this far! I hope you learned something from the article and now we can both make sure we avoid these problems in our future code.&lt;/p&gt;

&lt;p&gt;If you enjoyed it feel free to drop a 👍 on the article. It inspires me to continue improving and make more awesome content.&lt;/p&gt;

&lt;p&gt;If you would like to connect with me then come an say hi &lt;a href="https://twitter.com/Kieran6dev" rel="noopener noreferrer"&gt;@Kieran6dev&lt;/a&gt; as I am always active in communicating with other devs over on Twitter.&lt;/p&gt;

&lt;p&gt;Thanks!&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>I built a full stack serverless e-commerce site with Next.js. What I learned and how it might help you</title>
      <dc:creator>Kieran Roberts</dc:creator>
      <pubDate>Mon, 05 Apr 2021 09:47:36 +0000</pubDate>
      <link>https://dev.to/kieran6roberts/i-built-a-full-stack-serverless-e-commerce-site-with-next-js-what-i-learned-and-how-it-might-help-you-449n</link>
      <guid>https://dev.to/kieran6roberts/i-built-a-full-stack-serverless-e-commerce-site-with-next-js-what-i-learned-and-how-it-might-help-you-449n</guid>
      <description>&lt;p&gt;As part of building side projects to fill out my front-end portfolio I recently built a full stack serverless e-commerce site. I have always enjoyed building larger applications and I thought I would build my biggest project yet.&lt;/p&gt;

&lt;p&gt;One of my first personal projects was a small site for a fictional brewery company. It had a home page, products page, contact page and a small product store. The products store was more of a to-do list than a real e-commerce store. You could add and remove items but there was no checkout process or payments.&lt;/p&gt;

&lt;p&gt;Ever since then I was determined to build a full e-commerce site with all the bells and whistles. &lt;strong&gt;And so I did&lt;/strong&gt;. This is the home screen of 'Kieran's Coffee Collection' in the light color theme 👇.&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%2Fd01nqfwqljfxhtt9n034.jpeg" 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%2Fd01nqfwqljfxhtt9n034.jpeg" alt="My coffee e-commerce project home screen" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is far from perfect which you might see if you look at the code 😅. But it is finished and working and I'm proud that I was able to get to the end. A lot of the points I will soon talk about are the struggles I encountered along the way because I think it is important to reflect on what we can improve on.&lt;/p&gt;

&lt;p&gt;Here is the live version of the site 👉 &lt;a href="https://coffee-ecommerce.vercel.app/" rel="noopener noreferrer"&gt;Kieran's Coffee Collection&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and here is the code 👉 &lt;a href="https://github.com/kieran6roberts/Store-ecommerce" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is not a walkthrough of the project. You wont see any code but instead it is an overview of my experiences and failings so that it might help you. &lt;/p&gt;

&lt;p&gt;I am open to writing about the technical side of the project including code and how I built the site. If that is something that interests you then let me know in the comments or alternatively check out the repo.&lt;/p&gt;

&lt;p&gt;I learned a hell of a lot during this project so why not share it you. Let's go!&lt;/p&gt;

&lt;h2&gt;
  
  
  Content
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;So what is Kieran's Coffee Collection?&lt;/li&gt;
&lt;li&gt;What I learned and how it might help you

&lt;ul&gt;
&lt;li&gt;😍 I love Next.js&lt;/li&gt;
&lt;li&gt;😕 Caching is tricky&lt;/li&gt;
&lt;li&gt;😃 The back-end setup of Hasura, Auth0 and GraphCMS was great&lt;/li&gt;
&lt;li&gt;🤔 Take time out to think through problems&lt;/li&gt;
&lt;li&gt;😮 It is easy to forget about testing but we shouldn't&lt;/li&gt;
&lt;li&gt;😉 This is the type of project where a component library like Chakra UI is perfect&lt;/li&gt;
&lt;li&gt;😌 I need to spend more time with TypeScript&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Final thoughts&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  So what is Kieran's Coffee Collection?
&lt;/h2&gt;

&lt;p&gt;First a quick overview of the project. Kieran's Coffee Collection is a serveless e-commerce website built primarily with the React framework &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt;. The rest of the front-end stack includes the component Library &lt;a href="https://chakra-ui.com/" rel="noopener noreferrer"&gt;ChakraUI&lt;/a&gt;, &lt;a href="https://www.typescriptlang.org/" rel="noopener noreferrer"&gt;TypeScript&lt;/a&gt; and &lt;a href="https://www.apollographql.com/docs/react/" rel="noopener noreferrer"&gt;Apollo Client&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since I'm primarily a front-end developer I wanted to simplify the backend as much as possible. User authentication is handled by &lt;a href="https://auth0.com/" rel="noopener noreferrer"&gt;Auth0&lt;/a&gt; as a tried and trusted authenticator while &lt;a href="https://hasura.io/" rel="noopener noreferrer"&gt;Hasura graphql&lt;/a&gt; handles the creation and maintenance of the users database. Finally I have &lt;a href="https://graphcms.com/" rel="noopener noreferrer"&gt;GraphCMS&lt;/a&gt; as a graphql based headless CMS to handle products and everything related to them.&lt;/p&gt;

&lt;p&gt;My store in dark theme 👇&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%2Fcm0l7i9q286olkju33td.jpeg" 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%2Fcm0l7i9q286olkju33td.jpeg" alt="My store page in dark theme" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and the cart page also in the dark theme 👇&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%2Frvmmjx8j96e6tw2clq46.jpeg" 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%2Frvmmjx8j96e6tw2clq46.jpeg" alt="My cart page in dark theme" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The primary features of the app include the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;e-commerce product store&lt;/li&gt;
&lt;li&gt;product sorting / filtering&lt;/li&gt;
&lt;li&gt;persistent cart / saved products&lt;/li&gt;
&lt;li&gt;user authentication / accounts&lt;/li&gt;
&lt;li&gt;checkout process&lt;/li&gt;
&lt;li&gt;payments&lt;/li&gt;
&lt;li&gt;user product reviews&lt;/li&gt;
&lt;li&gt;pagination&lt;/li&gt;
&lt;li&gt;theme toggle&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The shipping page in the checkout process 👇.&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%2Fxsd7k7l9b6hwsr14thsx.jpeg" 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%2Fxsd7k7l9b6hwsr14thsx.jpeg" alt="My project shipping page" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's straight into my main takeaways 👏.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned and how it might help you
&lt;/h2&gt;

&lt;h3&gt;
  
  
  😍 I love Next.js
&lt;/h3&gt;

&lt;p&gt;Next.js is great. I've now used it in a few different projects including my portfolio. &lt;/p&gt;

&lt;p&gt;I love how it simplifies working with images, perfect for an e-commerce site where I'm working with a lot them.&lt;/p&gt;

&lt;p&gt;I love how it makes routing and creating pages and dynamic routes so easy and fluid.&lt;/p&gt;

&lt;p&gt;I love the TypeScript support which I'm starting to pick up.&lt;/p&gt;

&lt;p&gt;I love the api routes that allow you to add some back-end functionality to your app which was perfect in my case. It meant I could easily integrate my authentication redirects, order webhooks and account details updates seamlessly.&lt;/p&gt;

&lt;p&gt;If you have some experience with React and are looking for the next challenge I definitely recommend trying Next.js.&lt;/p&gt;

&lt;h3&gt;
  
  
  😕 Caching is tricky
&lt;/h3&gt;

&lt;p&gt;This is the first project where I really had to manage a cache. I had seen a popular computer science quote by Phil Karlton that says&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There are only two hard things in Computer Science: cache invalidation and naming things.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This was my first project using Apollo Client for data fetching. If you've never used it before all you need to know is that it allows you to store the results of queries in a cache. I wanted to try it in previous projects but decided to go with other lighter weight options due to the limited amount of fetching I was doing in those projects. This time I went for it!&lt;/p&gt;

&lt;p&gt;I found it to be great for client-side data fetching but I struggled at first when it came to managing the cache. As soon as I started to implement graphql mutations where I was forced to update the cache manually I found it tricky. &lt;/p&gt;

&lt;p&gt;This in combination with component state updates and I was having a hard time in understanding why a mutation for a product review was causing 5 new reviews to appear on screen 😂.&lt;/p&gt;

&lt;p&gt;But the more I dug into the documentation and took time out to think about problems the easier it became. So I ended up with two main takeways here.&lt;/p&gt;

&lt;p&gt;First is don't underestimate cache management. Secondly the documentation is there for a reason so just read it!&lt;/p&gt;

&lt;h3&gt;
  
  
  😃 The back-end setup of Hasura, Auth0 &amp;amp; GraphCMS was great
&lt;/h3&gt;

&lt;p&gt;The inspiration for this setup was provided by this article series &lt;a href="https://graphcms.com/blog/hasura-fit-start-here" rel="noopener noreferrer"&gt;Hasura Fit - By Jesse Martin&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Having previously built projects with Next.js and GraphCMS I was looking for a back-end stack that I could implement successfully as a front-end developer while still giving me user accounts and authorization etc.&lt;/p&gt;

&lt;p&gt;I wanted a serveless setup where I could deploy the front-end to a CDN provided by Vercel but I would still have a dynamic app that could update when necessary.&lt;/p&gt;

&lt;p&gt;👉🙂 &lt;strong&gt;Handling Users&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hasura provides us with instant grahql api's and acts as our 'backend as a service'. In minutes you can have a free Postgres database hosted on Heroku with api's to interact with it and I found using it to be a very pleasant developer experience.&lt;/p&gt;

&lt;p&gt;The combination of Hasura and Auth0 was perfect for user authentication and accounts. For user sign-in I could just redirect users using next.js api routes to Auth0 and let them do the heavy lifting. On completion they would be redirected back to my site and by setting up some rules in Auth0, Hasura then handles the creation and maintenance of user accounts.&lt;/p&gt;

&lt;p&gt;☕ &lt;strong&gt;Handling Products&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I liked the separation between users and products included in the article. Having previously used GraphCMS in two separate projects I knew it would be perfect for handling data related to products. Setting up schemas and content is a breeze and I could incorporate mutations and webhooks when required. Similarly to Hasura it also has a free plan available which is great!&lt;/p&gt;

&lt;h3&gt;
  
  
  🤔 Take time out to think through problems
&lt;/h3&gt;

&lt;p&gt;This is more of a general problem but I thought I'd mention it quickly. Before this project I was prone to frustration. Sitting for hours on end staring at the same problem hopelessly trying solutions that were &lt;strong&gt;destined to fail&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now I have learned that stepping away from problems is often the best solution. If your stuck on an issue move on to another task and you'll end up thinking of a solution to your problem that involves a fraction of the code you would otherwise write.&lt;/p&gt;

&lt;p&gt;I had to step away several times because of issues I was having especially when I was dealing with the Apollo cache. I was able to think out different solutions clearly and many of them I realized wouldn't work. &lt;/p&gt;

&lt;p&gt;But some of them did and this saved me a lot of time instead of writing out the solution first and then realizing its no good.&lt;/p&gt;

&lt;h3&gt;
  
  
  😮 It is easy to forget about testing but we shouldn't
&lt;/h3&gt;

&lt;p&gt;I started off the project with the idea of testing as I go. Test Driven Development (&lt;strong&gt;TDD&lt;/strong&gt;) is the process of starting by writing failing tests and then going about writing the code to satisfy the test and rinsing/repeating until satisfied. &lt;/p&gt;

&lt;p&gt;It started off well but I soon got carried away with the building and testing was forgotten. If there is one takeaway that will stay with me into future projects it's that I'm going to try not to rush things and instead stick to the plan. &lt;/p&gt;

&lt;p&gt;No one wants to be left writing tests after the project is done. It's not a great way of doing things and I'm going to be stricter with myself in the future.&lt;/p&gt;

&lt;h3&gt;
  
  
  😉 This is the type of project where a component library like Chakra UI is great
&lt;/h3&gt;

&lt;p&gt;For a large project like this with a lot of moving parts and large components Chakra UI was a life saver! I could build large, complex and accessible components in minutes leaving me more time to work on other parts of the app. This sidebar is one such example 👇.&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%2Fn34o04gr7rjmxda4j6ep.jpeg" 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%2Fn34o04gr7rjmxda4j6ep.jpeg" alt="My projects sidebar using Chakra UI components" width="595" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I could build a sidebar like this with a background modal in no time and they're still extremely customizable. There are so many other examples of this. I've never found it so simple to add a light/dark theme toggle. You can then customize individual elements based on the color theme. It's great 😃.&lt;/p&gt;

&lt;p&gt;Another example are these tabs located on each individual project page 👇.&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%2Fi9tyqs2wmdmuqhwp6w96.jpeg" 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%2Fi9tyqs2wmdmuqhwp6w96.jpeg" alt="Tabs component provided by Ckakra UI in my project" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If your thinking about building a larger project where you might need a lot of interactive components such as menus, drawers, tooltips, modals and much more then consider giving Chakra UI a go.&lt;/p&gt;

&lt;h3&gt;
  
  
  😌 I need to spend more time with TypeScript
&lt;/h3&gt;

&lt;p&gt;I have been learning TypeScript for the last couple of months. I though it would be a good skill to start learning now before I look for a job in the industry where I might need it. I'm comfortable with the basics but I found that I'm still unsure how to best use it when projects start to grow.&lt;/p&gt;

&lt;p&gt;There are still too many times where I use the dreaded &lt;code&gt;any&lt;/code&gt; 😮 type or others that were sub-optimal effectively nullifying the benefits of TypeScript. I was also unsure of where a lot of the types and interfaces should live. &lt;/p&gt;

&lt;p&gt;I would like to spend a little time organizing shared types into their own directory because at the moment it is not organized and it can be a waste of time tracking the origin of the file where the type is.&lt;/p&gt;

&lt;p&gt;One of my focuses for the next month is going to be diving into the TypeScript documentation and do some more reading. I recently did something similar with git and now I'm much more comfortable with the popular version control system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Although there are things I would have liked to have done differently I am very happy with the overall result. I accomplished my goal of building an online store for this fictional company where users can manage accounts, products and checkout out a cart with payments.&lt;/p&gt;

&lt;p&gt;If you would like to see more about the technical side like how I integrated certain features than please let me know.&lt;/p&gt;

&lt;p&gt;I'm always active over on twitter &lt;a href="https://twitter.com/Kieran6dev" rel="noopener noreferrer"&gt;@Kieran6dev&lt;/a&gt; so come and say hi and if you liked the article please let me know. Thanks friends 👋.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/kieran6roberts" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.buymeacoffee.com%2Fbutton-api%2F%3Ftext%3DBuy%2520me%2520a%2520beer%26emoji%3D%25F0%259F%258D%25BA%26slug%3Dkieran6roberts%26button_colour%3DBD5FFF%26font_colour%3Dffffff%26font_family%3DPoppins%26outline_colour%3D000000%26coffee_colour%3DFFDD00" width="217.0" height="50"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>nextjs</category>
      <category>programming</category>
    </item>
    <item>
      <title>An introduction to @testing-library: Part 2</title>
      <dc:creator>Kieran Roberts</dc:creator>
      <pubDate>Wed, 31 Mar 2021 11:47:29 +0000</pubDate>
      <link>https://dev.to/kieran6roberts/an-introduction-to-testing-library-part-2-1ea3</link>
      <guid>https://dev.to/kieran6roberts/an-introduction-to-testing-library-part-2-1ea3</guid>
      <description>&lt;p&gt;In &lt;a href="https://dev.to/kieran6roberts/an-introduction-to-testing-library-part-1-2693"&gt;An introduction to @testing-library: Part 1&lt;/a&gt; we explored why we test, the benefits of using Testing Library as well as some of its features.&lt;/p&gt;

&lt;p&gt;It's about time we started writing some tests so let's get straight into in 👏.&lt;/p&gt;

&lt;h2&gt;
  
  
  Content
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Test setup&lt;/li&gt;
&lt;li&gt;Our starter component&lt;/li&gt;
&lt;li&gt;Testing&lt;/li&gt;
&lt;li&gt;Async component update&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Want to practice some queries - &lt;a href="https://testing-playground.com/" rel="noopener noreferrer"&gt;Testing Playground&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1.) Test setup
&lt;/h2&gt;

&lt;p&gt;For the following example I will be using Testing Library in combination with the testing framework &lt;a href="https://jestjs.io/" rel="noopener noreferrer"&gt;Jest&lt;/a&gt; and we will be unit testing a simple stateful component in React. I will also be using Yarn as my preferred package manager.&lt;/p&gt;

&lt;p&gt;I have begun by creating a new project with &lt;code&gt;create-react-app&lt;/code&gt;. The great thing about this is that the packages that we need to get started with are automatically installed for us in the build. &lt;/p&gt;

&lt;p&gt;If that wasn't enough &lt;code&gt;create-react-app&lt;/code&gt; also comes with support for Jest out of the box meaning we can get straight into writing our component for testing 👏.&lt;/p&gt;

&lt;p&gt;The following are the Testing Library packages that we will be using included with &lt;code&gt;create-react-app&lt;/code&gt;👇.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F80vzy61znqj2xb0pakil.jpeg" 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%2F80vzy61znqj2xb0pakil.jpeg" alt="Our Testing library dependencies" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@testing-library/jest-dom&lt;/code&gt; &lt;em&gt;provides us some custom Jest matchers which we will soon see&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@testing-library/react&lt;/code&gt; &lt;em&gt;gives us api's so we can work with React components&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@testing-library/user-event&lt;/code&gt; &lt;em&gt;allows us to perform user related actions like firing events&lt;/em&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you spin up your own &lt;code&gt;create-react-app&lt;/code&gt; you will see these packages in your dependencies as well as a &lt;code&gt;setupTests.js&lt;/code&gt; file inside the &lt;code&gt;src&lt;/code&gt; folder. Inside &lt;code&gt;setupTests.js&lt;/code&gt; we import &lt;code&gt;@testing-library/jest-dom&lt;/code&gt;. React will run this file before each of our test files meaning it is imported once here and we won't have to keep importing it into every test file.&lt;/p&gt;

&lt;p&gt;I'm going to start by creating two folders to store our components (&lt;code&gt;components&lt;/code&gt;) and our tests (&lt;code&gt;__tests__&lt;/code&gt;). The reason we name the tests file with two underscores on each side is because Jest will recognize this file and run the tests inside for us when we run the script &lt;code&gt;yarn test&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You could also store your tests in the same location as its component counterpart but for this example we'll keep them separate.&lt;/p&gt;

&lt;p&gt;To see this in action I will delete the &lt;code&gt;App.test.js&lt;/code&gt; file provided by React and create a new test file for our component named &lt;code&gt;UserInput.test.js&lt;/code&gt; inside our &lt;code&gt;__tests__&lt;/code&gt; folder and run the test script again. You should see that Jest runs our new test file before giving us a &lt;strong&gt;FAIL&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;We need a component to test. So let's build one!&lt;/p&gt;

&lt;h2&gt;
  
  
  2.) Our starter component
&lt;/h2&gt;

&lt;p&gt;Next I'm going to show you the component we will be working with in our examples. All I have done is created the component and imported it into the default &lt;code&gt;App&lt;/code&gt; component after removing the starting code that &lt;code&gt;create-react-app&lt;/code&gt; provides. &lt;/p&gt;

&lt;p&gt;It is a simple example so that we can focus on Testing Library core features and the flow of testing. This is how it looks 👇.&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%2Fbkcn9svelevacxjp3svb.jpeg" 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%2Fbkcn9svelevacxjp3svb.jpeg" alt="Our example component to test" width="800" height="1135"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me break this down for you. We have a component that has a simple text input that allows users to enter a value into it. We then pass this input value above to a &lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt; element. &lt;/p&gt;

&lt;p&gt;Pointless I know but it makes for a good example 😅. We also have a reset button that will clear the value in the input field on a click.&lt;/p&gt;

&lt;p&gt;We are using a controlled input and therefore we maintain the state of the input value with the &lt;code&gt;useState&lt;/code&gt; hook. When the user types into the input we update our input state value using with &lt;code&gt;event.target.value&lt;/code&gt; and finally pass this state as the value for our input. Here I am deconstructing &lt;code&gt;target&lt;/code&gt; from the &lt;code&gt;event&lt;/code&gt; object in the function properties.&lt;/p&gt;

&lt;p&gt;We also have a prop called &lt;code&gt;inputType&lt;/code&gt; that we pass from the &lt;code&gt;&amp;lt;App /&amp;gt;&lt;/code&gt; component. I have given it the value of &lt;code&gt;name&lt;/code&gt; so we can ask the user for their name or anything else if we chose to change it. I wanted to include some props for our component so that we can test it. &lt;/p&gt;

&lt;p&gt;Below is the &lt;code&gt;&amp;lt;App /&amp;gt;&lt;/code&gt; component where we import our component to be tested.&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%2F9zhc31sky8b5po6mf9ab.jpeg" 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%2F9zhc31sky8b5po6mf9ab.jpeg" alt="app.jpeg" width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have also added some simple styling just for you to help visualize our component. This is how it looks in browser 👇.&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%2F61wll8zh7ncepvfv81al.jpeg" 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%2F61wll8zh7ncepvfv81al.jpeg" alt="Our test component in browser" width="800" height="635"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we type my name "Kieran" and you can see this is mirrored above in the &lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt; element.&lt;/p&gt;

&lt;p&gt;Let's start testing 🙌.&lt;/p&gt;

&lt;h2&gt;
  
  
  3.) Testing
&lt;/h2&gt;

&lt;p&gt;So we want to avoid testing implementation details. This means we should test the results that our users will see and interact with and not necessarily how we do it in case we change how we do it in the future. &lt;/p&gt;

&lt;h3&gt;
  
  
  Test 1
&lt;/h3&gt;

&lt;p&gt;Our component has a prop as a string and this prop is shown to the user. So let's make sure this is coming through as we expect. Here we go 👇.&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%2Fc9zifzu0xh2lz1acdo4y.jpeg" 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%2Fc9zifzu0xh2lz1acdo4y.jpeg" alt="Our example test checking props existence" width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To start we import &lt;code&gt;screen&lt;/code&gt; for our queries and the &lt;code&gt;render&lt;/code&gt; method to render our component. We will use &lt;code&gt;userEvent&lt;/code&gt; a bit later. &lt;/p&gt;

&lt;p&gt;Next up we create our &lt;code&gt;describe&lt;/code&gt; block that will wrap our tests and then create our first test. This first test will check that the input is working as expected. The &lt;code&gt;describe&lt;/code&gt; and &lt;code&gt;test&lt;/code&gt; structure is just part of the Jest testing framework.&lt;/p&gt;

&lt;p&gt;Next we render our component and we create a mock prop to pass in. When we render our components in unit tests we have to create our props ourselves. Here I pass in a prop called &lt;code&gt;name&lt;/code&gt; because we are asking for the users name.&lt;/p&gt;

&lt;p&gt;In order to assert that this prop is indeed visible to the user I need to query for it. I start by seeing if I can query it by role with &lt;code&gt;getByRole&lt;/code&gt; as an accessible query which in this case is not possible. You can use this list of roles to help you &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques#roles" rel="noopener noreferrer"&gt;MDN - Using ARIA: Roles, states, and properties&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Querying for elements is an important part of using Testing Library. If you would like some practice with this there is a great tool called &lt;a href="https://testing-playground.com/" rel="noopener noreferrer"&gt;Testing Playground&lt;/a&gt; where you can quickly write some elements and queries and receive feedback on whether there are more suitable queries available.&lt;/p&gt;

&lt;p&gt;Here the prop is passed as text content to both the label and the clear button. We use the &lt;code&gt;getByText&lt;/code&gt; query to check if an exact match for this is present in the DOM and it is in our label which is what we are looking for. If we tried to query for a substring like this 👇&lt;/p&gt;

&lt;p&gt;&lt;code&gt;screen.getByText(/name/i);&lt;/code&gt; which matches a substring with a case insensitive flag &lt;code&gt;i&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;it would also return our clear button because it contains the word &lt;code&gt;name&lt;/code&gt;. We want an exact match like this to find our label 👇.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;screen.getByText("name");&lt;/code&gt; which matches an exact string.&lt;/p&gt;

&lt;p&gt;Secondly we query for the button by its accessible role and we use the &lt;code&gt;@testing-library/jest-dom&lt;/code&gt; package and its &lt;code&gt;toHaveTextContent()&lt;/code&gt; matcher. This matcher asserts that it has the text content &lt;code&gt;clear name&lt;/code&gt; which partly comes from our prop. If we had more than one button we could query them using &lt;code&gt;getAllByRole()&lt;/code&gt; instead. Now if we run the test it should PASS ✔!&lt;/p&gt;

&lt;p&gt;This package has a lot of great matchers that let us assert different states of the DOM. Check it out here &lt;a href="https://github.com/testing-library/jest-dom" rel="noopener noreferrer"&gt;testing-library/jest-dom&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Next up we want to type into the input and check that it updates the UI with the value provided. Check it out 👇.&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%2F649qo8onw8uc6otd5bpe.jpeg" 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%2F649qo8onw8uc6otd5bpe.jpeg" alt="Testing user input with user events" width="800" height="834"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First we query for the input element and store it in a variable because we will reference it more than once. We query for the text associated with label which in this case is the value of our prop "name".&lt;br&gt;
Then we query for our output which in our case is the heading element &lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt;. We can query this using &lt;code&gt;getByRole("heading")&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next we can start using some events. Here we use the &lt;code&gt;type&lt;/code&gt; event to simulate our users typing into the input and we assert that the input value contains the value "Kieran" which we expect. I then use another type event to show you that it doesn't replace the previous event. Just like a real input field the string continues as we type and we end up with "KieranRoberts".&lt;/p&gt;

&lt;p&gt;Finally we want to check that this is being outputted as we expect. First as the value of the input with &lt;code&gt;toHaveValue()&lt;/code&gt; and secondly to the output heading as text with &lt;code&gt;toHaveTextContent()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Great 👏. Now we have our input tested.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test 2
&lt;/h3&gt;

&lt;p&gt;Next we want to test that our reset button clears our input as the user expects.&lt;/p&gt;

&lt;p&gt;For the purpose of this article I will split our component tests into multiple test blocks so it's easy to follow and there's clear separation with our component features.&lt;/p&gt;

&lt;p&gt;Out second test block looks like 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%2Fgxkc5uwyq4z0b1u2aixf.jpeg" 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%2Fgxkc5uwyq4z0b1u2aixf.jpeg" alt="Testing our clear button" width="596" height="606"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We start very similarly to before by rendering our component and performing a type event into our input. This time we also have a &lt;code&gt;click&lt;/code&gt; event that we trigger on our button. We query for the button using the accessible role &lt;code&gt;button&lt;/code&gt;. Finally we assert that the value of the input and the text of the heading are empty string.&lt;/p&gt;

&lt;p&gt;Great! All the tests pass ✔.&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%2F0ugwlnarfdodmv2f7kke.jpeg" 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%2F0ugwlnarfdodmv2f7kke.jpeg" alt="Passing tests" width="800" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4.) Async component update
&lt;/h2&gt;

&lt;p&gt;Next let's modify our component a little so that we have some async logic to see how we can successfully test this. I will also change up the markup a little so that we can play with some of the other query variations. Check it out 👇.&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%2Ftpq1t8by7dpjjz4yeu1a.jpeg" 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%2Ftpq1t8by7dpjjz4yeu1a.jpeg" alt="Updated Component" width="800" height="1323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first change we have made is to add a &lt;code&gt;setTimeout&lt;/code&gt; function to our reset button click. This is to simulate an asynchronous submission which is often the case in a real application. Secondly I have included a conditional paragraph element &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; so we can see how we should query for elements we expect don't exist.&lt;/p&gt;

&lt;h3&gt;
  
  
  Updating our tests
&lt;/h3&gt;

&lt;p&gt;If your familiar with Jest you will know we need to mock our &lt;code&gt;setTimeout&lt;/code&gt; function for the testing environment. Let's start here 👇&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%2Fu52m6dgqn6oqgfic7ka3.jpeg" 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%2Fu52m6dgqn6oqgfic7ka3.jpeg" alt="mock setTimeout" width="427" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We use to mock &lt;code&gt;jest.useFakeTimers()&lt;/code&gt; inside a &lt;code&gt;beforeEach()&lt;/code&gt; block which will run the mock before each of our tests. We then simply restore the timer function behavior using the &lt;code&gt;afterEach()&lt;/code&gt; block. All of this is just part of the Jest framework.&lt;/p&gt;

&lt;p&gt;In our case the first test for the user input remains the same. It's the second test for the input clear that we need to modify. &lt;/p&gt;

&lt;p&gt;First of all we now have a conditional element so we want to first assert that this element does not exist in the DOM before we have some user input. We should do this using the &lt;code&gt;queryBy...&lt;/code&gt; variation like 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%2Fn9xz0b5asr443y92ykc8.jpeg" 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%2Fn9xz0b5asr443y92ykc8.jpeg" alt="queryBy example" width="800" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we want to query an element that we expect does not exist we use &lt;code&gt;queryBy...&lt;/code&gt; because it returns null if it does not find a match instead of throwing an error like &lt;code&gt;getBy...&lt;/code&gt; would. Our element will have the text "Input is not empty" if it present so we query for this substring with a case insensitive flag &lt;code&gt;i&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To assert our element is not in the document we use the assertion &lt;code&gt;toBeInTheDocument()&lt;/code&gt; from &lt;code&gt;@testing-library/jest-dom&lt;/code&gt; combined with &lt;code&gt;.not()&lt;/code&gt; provided by Jest.&lt;/p&gt;

&lt;p&gt;Then we perform our &lt;code&gt;type&lt;/code&gt; user event and this time we also assert that our conditional element is now in present.&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%2Fpw91xn7nb0xg5bl0evgl.jpeg" 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%2Fpw91xn7nb0xg5bl0evgl.jpeg" alt="Perform out type event with assertions" width="763" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And now we get to our async submission. Here it is 👇.&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%2Fzn73ufav1o2svnty4iax.jpeg" 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%2Fzn73ufav1o2svnty4iax.jpeg" alt="Async example" width="684" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First we click our clear button. Next I make a quick check that our &lt;code&gt;setTimeout&lt;/code&gt; mock is called after the click. Now we have to deal with the &lt;code&gt;async&lt;/code&gt; part. &lt;/p&gt;

&lt;p&gt;When we want to wait some period of time before we make the assertion we can use the &lt;code&gt;waitFor&lt;/code&gt; function provided by Testing Library by importing it like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import { waitFor } from "testing-library/react";&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To this function we pass a callback and we need to &lt;code&gt;await&lt;/code&gt; the result of &lt;code&gt;waitFor()&lt;/code&gt;because it returns a promise . The default timeout for this is 1000ms meaning our promise should resolve before this otherwise it will reject.&lt;/p&gt;

&lt;p&gt;If we did not wrap our assertion this way it would fail because it would run immediately and we currently still have our input value until after 800ms. So instead we &lt;code&gt;waitFor()&lt;/code&gt; our result because it calls our callback at different intervals until the promise is resolved. Other than that we still pass in our same assertions.&lt;/p&gt;

&lt;p&gt;Let's take a look at the completed test file 👏.&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%2Fxcxcymlqg4q48dvnb1z0.jpeg" 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%2Fxcxcymlqg4q48dvnb1z0.jpeg" alt="Complete test file" width="800" height="1477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now when we run our tests we should be greeted by the sweet site of the green PASS ✔.&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%2F13ausw24c8rn2gnzwavw.jpeg" 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%2F13ausw24c8rn2gnzwavw.jpeg" alt="Tests passing in command line" width="800" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Waiting on elements
&lt;/h3&gt;

&lt;p&gt;Another common situation that I wanted to mention is when we are waiting on an async event that causes an element to appear that did not previously exist in the DOM. This can be done using the &lt;code&gt;findBy()&lt;/code&gt; query variation.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;findBy()&lt;/code&gt; is a combination of the &lt;code&gt;getBy()&lt;/code&gt; variation we have seen and the &lt;code&gt;waitFor()&lt;/code&gt; function that we just implemented. It returns a promise that resolves after a default max timeout of 1000ms which means we should await the result.&lt;/p&gt;

&lt;p&gt;Consider a situation where we have an async submission for a form and once submitted we add a heading &lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt; element to the DOM that says 'Submitted' or maybe we want to store the element in a variable. We could use it like 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%2Fiv7mjbolhyt2hzhw5znc.jpeg" 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%2Fiv7mjbolhyt2hzhw5znc.jpeg" alt="findBy queries" width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we seen some examples of testing some async code as well. Great!&lt;/p&gt;

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

&lt;p&gt;There is still a lot to discover so I encourage you to play around using Testing Library yourselves. I hope you at least learned something from this introduction and I appreciate you taking the time to read the article.&lt;/p&gt;

&lt;p&gt;You can find me &lt;a href="https://twitter.com/Kieran6dev" rel="noopener noreferrer"&gt;@Kieran6dev&lt;/a&gt; where I'm always active and if you enjoyed the article feel free to let me know. Thanks 👋.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>testing</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>An introduction to @testing-library: Part 1</title>
      <dc:creator>Kieran Roberts</dc:creator>
      <pubDate>Wed, 24 Mar 2021 14:03:00 +0000</pubDate>
      <link>https://dev.to/kieran6roberts/an-introduction-to-testing-library-part-1-2693</link>
      <guid>https://dev.to/kieran6roberts/an-introduction-to-testing-library-part-1-2693</guid>
      <description>&lt;p&gt;Testing our apps is a vital part of modern web-development that is often overlooked by new developers. I myself struggled with testing early on. It can be difficult to grasp and there are far fewer free resources available online for testing compared to other topics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why do we test our apps?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We want to write tests because they help certify the behavior of our app. You can think of your tests as the documentation for &lt;em&gt;what your code does&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I thought I would introduce you to a set of libraries we can use to help test our apps called &lt;strong&gt;Testing Library&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;For this introduction you will see me use the React package which is a wrapper on the core library. If you're not familiar with React don't worry. The core principles are the same across the other frameworks/libraries.&lt;/p&gt;

&lt;p&gt;On top of the core library there are wrappers that allow us to use this set of testing utilities for multiple different JavaScript frameworks including React, Vue, Svelte and much more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Content
&lt;/h2&gt;

&lt;p&gt;In part one we will explore 👇&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What is Testing Library?&lt;/li&gt;
&lt;li&gt;What benefits does Testing Library provide? &lt;/li&gt;
&lt;li&gt;What kind of tests can we write with Testing Library?&lt;/li&gt;
&lt;li&gt;The flow of testing with Testing Library?&lt;/li&gt;
&lt;li&gt;Queries&lt;/li&gt;
&lt;li&gt;User Events&lt;/li&gt;
&lt;li&gt;Looking ahead to part two!&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1.) What is Testing Library?
&lt;/h2&gt;

&lt;p&gt;Testing Library is a &lt;strong&gt;collection of utilities&lt;/strong&gt; that allow us to test our apps in a similar way to how users interact with our site which is a good testing practice. One of the focuses of the library is to provide us with methods of querying for our DOM nodes that is representative of how users would find these nodes on a page.&lt;/p&gt;

&lt;p&gt;The description provided by Testing Library on their site is as follows:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The core library, DOM Testing Library, is a light-weight solution for testing web pages by querying and interacting with DOM nodes (whether simulated with JSDOM/Jest or in the browser).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is not however a testing framework or a test runner. This means we generally use this set of libraries in combination with a testing framework like Jest or Cypress. For the purpose of this introduction I will be running tests using arguably the most popular testing framework, Jest.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.) What benefits does Testing Library provide?
&lt;/h2&gt;

&lt;p&gt;Testing in a user focused manner gives us the confidence that the tests we write are a true reflection of the user experience.&lt;/p&gt;

&lt;p&gt;When we write our tests we want to ensure that we leave out the implementation details of our app. By doing this we ensure our tests are maintainable because any refactoring of our app/components won't cause tests to suddenly fail.&lt;/p&gt;

&lt;p&gt;What I mean by this is that we typically want to test the things that our users will interact with and see in our apps. Do you have some state that changes what the user will see on the page? &lt;strong&gt;If you do test it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This article by the creator of Testing Library - Kent C. Dodds explains in detail why we want to avoid testing implementation details - &lt;a href="https://kentcdodds.com/blog/testing-implementation-details" rel="noopener noreferrer"&gt;Testing Implementation Details - Kent C. Dodds&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3.) What kind of tests can we write with Testing Library?
&lt;/h2&gt;

&lt;p&gt;The great thing is we can write all kinds of tests using this set of libraries. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unit Tests ✔&lt;/li&gt;
&lt;li&gt;Integration Tests ✔&lt;/li&gt;
&lt;li&gt;End-to-end Test ✔&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4.) The flow of testing with Testing Library?
&lt;/h2&gt;

&lt;p&gt;Personally I have been using Testing Library in combination with React. The idea is the same across other frameworks/libraries.&lt;/p&gt;

&lt;p&gt;The general flow for our tests in React will be something like this 👇.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Render our component passing in some mock props if required&lt;/li&gt;
&lt;li&gt;Query for our nodes in component with maybe some initial assertions.&lt;/li&gt;
&lt;li&gt;Perform some user action like typing or a click&lt;/li&gt;
&lt;li&gt;Assert some change that a user would see based on the user input &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can render our React components for testing using the render method which we can import from the main library like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import { render } from "@testing-library/react";&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and in our test pass in our component to render it:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;render(&amp;lt;SomeComponent /&amp;gt;);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Next we'll take a look at how we query for elements 😃.&lt;/p&gt;

&lt;h2&gt;
  
  
  5.) Queries
&lt;/h2&gt;

&lt;p&gt;An important part of Testing Library is being able to query for DOM nodes in a user focused manner. We do this using methods called &lt;strong&gt;Queries&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Queries allow us to find elements that might exist on the page. Knowing the correct query to use for a given situation is an important part of using the library. We need to query for elements so that we can perform some assertions or user events on them.&lt;/p&gt;

&lt;p&gt;Then general syntax for querying with Testing Library is as follows 👇.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;screen.getByRole("button");&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;screen&lt;/code&gt; is an object that has all the available queries bound to the &lt;code&gt;document.body&lt;/code&gt;. We can import it from the main library of whatever context we are using (in this case React) like this 👇.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import { screen } from "@testing-library/react;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The query we used in this case is called &lt;code&gt;getByRole&lt;/code&gt; which queries for a single node that has the role of &lt;code&gt;button&lt;/code&gt;. Let's take a look at the different query variations we have available.&lt;/p&gt;

&lt;h3&gt;
  
  
  Query Variations
&lt;/h3&gt;

&lt;p&gt;Queries allow us to find DOM nodes. We can query for single nodes or multiple nodes and queries can be put into three different categories. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getBy...&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This query returns a single matching node or an error for no matching nodes. This is usually the go to variation when we are looking for a single node that we expect to be in the document.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;queryBy...&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This query returns a single matching node or &lt;code&gt;null&lt;/code&gt; for no matching nodes. This variation is usually preferred when we want to assert that the node is not present in the document.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;findBy...&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This query returns a promise that resolves when the element is found. It will reject if no node is found before the 1000ms default timeout. We use this query variation when we expect to have to wait some time before our result is present to the user (e.g some asynchronous request).&lt;/p&gt;

&lt;p&gt;These queries also have &lt;code&gt;AllBy...&lt;/code&gt; variations that allow us to query for multiple DOM nodes returned as an arrays (e.g &lt;code&gt;getAllByRole&lt;/code&gt;). Often our components will have multiple elements of the same role for example and we can group them all using this query.&lt;/p&gt;

&lt;p&gt;It is also common to store the results of our queries into variables so that we can reference them in multiple places without having to re-perform the query like this 👇.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const button = screen.getByRole("button");&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What can we query for?
&lt;/h3&gt;

&lt;p&gt;Deciding &lt;strong&gt;how to query&lt;/strong&gt; for an element is an important part of using this library. We can find elements in several different ways such as finding text in the document, element roles and label text. Despite this some query methods are preferred to others.&lt;/p&gt;

&lt;p&gt;This is because we want to ensure that our tests are a good representation of how our users interact with the app. Certain queries are more &lt;strong&gt;accessible&lt;/strong&gt; than others for example users that visit your site using assistive technology such as screen readers.&lt;/p&gt;

&lt;p&gt;If we query an element by its role instead of its text content we can be sure that our elements can be found accessibly as our impaired users may find them.&lt;/p&gt;

&lt;p&gt;Let's take a look at what we can query for. For the following queries I will stick to &lt;code&gt;getBy&lt;/code&gt; but we can also use any of the other variants.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getByRole()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👆 This is usually the preferred method of query because we can query for roles accessibly by the name that screen readers will read out. There is a lot you can get with this query which I was initially unaware of but it should be the first choice. &lt;/p&gt;

&lt;p&gt;You can find a list of ARIA roles here - &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques#roles" rel="noopener noreferrer"&gt;MDN Web Docs - Using ARIA: Roles, states, and properties&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getByText()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👆 Used to query for non interactive elements that have some text content like a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getByLabelText()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👆 This query will get the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; element associated with the &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; text that we pass to it. It is usually the preferred method of querying our inputs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getByPlaceholderText()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👆 Used to query for an element that has some placeholder text such as in an &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;. It is recommended to use &lt;code&gt;getByLabelText&lt;/code&gt; over this for querying inputs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getByDisplayValue()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👆 This will return the element that has a matching value. Can be used to find an &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt; element.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getByAltText()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👆 Used to find the element that has a matching alt text to the value we pass it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getByTitle()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👆 Query an element that has a matching title attribute value to the value we pass it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getByTestId()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👆 We can pass a data attribute in the form &lt;code&gt;data-testid="something"&lt;/code&gt; to an element and then query for it using &lt;code&gt;getByTestId&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;This query is generally &lt;strong&gt;not recommend&lt;/strong&gt; because it is not friendly to accessibility and involves polluting our markup with attributes not relevant to the users.&lt;/p&gt;

&lt;p&gt;Because using the right queries is important Testing Library provides us with a function that provides suggestions for which queries to use. We can import the &lt;code&gt;configure()&lt;/code&gt; function from our primary library like this 👇.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import { configure } from "@testing-library/react";&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and inside our tests we can call it and pass in the &lt;code&gt;throwSuggestions&lt;/code&gt; option like this 👇.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;configure({ throwSuggestions: true });&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will provide you with potentially better query options when you run your tests and can be helpful early on.&lt;/p&gt;

&lt;p&gt;Many of these queries are also able to take optional second parameters for example 👇&lt;/p&gt;

&lt;p&gt;&lt;code&gt;screen.getByText("hello world", { exact: false });&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;meaning we don't have to match the string &lt;code&gt;"hello world"&lt;/code&gt; exactly.&lt;/p&gt;

&lt;p&gt;Or this 👇&lt;/p&gt;

&lt;p&gt;&lt;code&gt;screen.getByRole("button", { name: "reset" });&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;where we narrow down our button search to an element that also has the name &lt;code&gt;"reset"&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;There is a lot we can do with our queries and it would beneficial to you to have a play around with trying out different queries. We will start implementing some of these queries in some tests in part two! &lt;/p&gt;

&lt;p&gt;You can check out these query methods in more detail here - &lt;a href="https://testing-library.com/docs/queries/about#example" rel="noopener noreferrer"&gt;Testing Library - About Queries&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  6.) User Events
&lt;/h2&gt;

&lt;p&gt;Now that know how to query for elements let's see how can simulate some user actions.&lt;/p&gt;

&lt;p&gt;Testing Library provides a companion library called &lt;strong&gt;user-event&lt;/strong&gt; that allows us to perform these user-actions available though &lt;code&gt;@testing-library/user-event&lt;/code&gt;. Using this library we can perform actions such as user click events, typing, tabbing, hovering and much more. Check out the Testing Library docs here for the full list with explanations - &lt;a href="https://testing-library.com/docs/ecosystem-user-event" rel="noopener noreferrer"&gt;Testing Library - user-event&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First we import the &lt;code&gt;userEvent&lt;/code&gt; object as a default export like this 👇.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import userEvent from "@testing-library/user-event";&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then we have a bunch of methods available on this object that allow us to simulate user events like this 👇.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;userEvent.click(screen.getByRole("button"));&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;where we specify the event and the element we wish to execute the event on in the case of the &lt;code&gt;click&lt;/code&gt; event.&lt;/p&gt;

&lt;p&gt;Let's have a quick look at how queries and events are connected inside an example test file for a React component. The logic of the component or tests isn't important at this stage and we won't be making any assertions just yet.&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%2Fjqnb2acq68xari4vs0g7.jpeg" 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%2Fjqnb2acq68xari4vs0g7.jpeg" alt="queries and user events examples" width="800" height="560"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we setup our test with our &lt;code&gt;describe&lt;/code&gt; and &lt;code&gt;test&lt;/code&gt; blocks which are part of the Jest testing framework. First we import our &lt;code&gt;screen&lt;/code&gt; wrapper which allows us to access our queries. Next we import the &lt;code&gt;render&lt;/code&gt; method which just allows us to render our react component to the DOM.&lt;/p&gt;

&lt;p&gt;Then we render our component and perform our queries for elements we would expect in our component. We can store the result of the query inside constants which is good to do if we plan on referencing them often. Finally we execute some example user events on our elements.&lt;/p&gt;

&lt;p&gt;The next step would be to start making some assertions which you will be familiar with if you've used a testing framework like Jest. Testing Library builds on these assertions which we will see in part 2.&lt;/p&gt;

&lt;h2&gt;
  
  
  7.) Looking ahead to part two!
&lt;/h2&gt;

&lt;p&gt;Now we now why we need to test and how Testing Library can help us, the next step is to write some tests. Finally 😂.&lt;/p&gt;

&lt;p&gt;But unfortunately not today otherwise it will end up being far too long. &lt;/p&gt;

&lt;p&gt;If you're new to Testing Library I suggest playing around with rendering some component and practicing with the different queries available. We will see this in action in part 2 along with making assertions, dealing with asynchronous events and a look at different queries in action.&lt;/p&gt;

&lt;p&gt;Thanks for reading! Feel free to say hello &lt;a href="https://twitter.com/Kieran6dev" rel="noopener noreferrer"&gt;@Kieran6dev&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;See you in part 2 👋.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>testing</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Why it's awesome for new developers to blog as they learn</title>
      <dc:creator>Kieran Roberts</dc:creator>
      <pubDate>Wed, 17 Mar 2021 13:35:47 +0000</pubDate>
      <link>https://dev.to/kieran6roberts/why-it-s-awesome-for-new-developers-to-blog-as-they-learn-5b77</link>
      <guid>https://dev.to/kieran6roberts/why-it-s-awesome-for-new-developers-to-blog-as-they-learn-5b77</guid>
      <description>&lt;p&gt;Writing about what we learn provides us with lots of incredible benefits both ourselves and to our awesome community. Many of us write notes as we go so why not share it others as well?&lt;/p&gt;

&lt;p&gt;Before I wrote my first post I honestly thought that I disliked writing but I wanted to give it a go. I used to think that I wasn't qualified to teach others. That I didn't know enough to write a full article about a certain topic. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I could not have been more wrong&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Not only did I enjoy writing about web-development but I learned so much in the process. I was wrong and now I want to encourage others who might think the same.&lt;/p&gt;

&lt;p&gt;Let me explain how writing a blog can benefit everyone and why we need new developers to help teach others 🙂.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Blog
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;You will learn more from writing about it&lt;/li&gt;
&lt;li&gt;You can explain topics how you would have liked them to be explained to you&lt;/li&gt;
&lt;li&gt;You will help teach other developers&lt;/li&gt;
&lt;li&gt;It looks great to future employers&lt;/li&gt;
&lt;li&gt;You will meet a lot of awesome people&lt;/li&gt;
&lt;li&gt;Your writing and communication will improve&lt;/li&gt;
&lt;li&gt;It is a lot of fun if you make it so&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1) You will learn more from writing about it
&lt;/h2&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%2Fc4rn3ybqbyhi7k1r21lr.jpeg" 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%2Fc4rn3ybqbyhi7k1r21lr.jpeg" alt="undrawBooks.jpg" width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are two main reasons why you will learn more. Firstly you can pick exactly what you want to write about. You might choose a technical topic that you're not familiar with and so you will have to do a lot of research in order to write about it well.&lt;/p&gt;

&lt;p&gt;Or maybe you pick a topic that you think you know well. But when you try to explain it you realize that you don't know it as well as you think. It's happened to me on many occasions. And that's a great thing ✔. &lt;/p&gt;

&lt;p&gt;You want to find out the things you don't know because that's how you improve. As developers the learning process never stops. &lt;/p&gt;

&lt;p&gt;It's not about saying &lt;strong&gt;'I've learned to code'&lt;/strong&gt; but instead ask yourself &lt;strong&gt;'What can I learn next?'&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2) You can explain topics how you would have liked them to be explained to you
&lt;/h2&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%2Flr6jtx3n7txwnyye3hmi.jpeg" 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%2Flr6jtx3n7txwnyye3hmi.jpeg" alt="illustration character pointing to article" width="800" height="576"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are a lot experienced and knowledgeable developers who write &lt;strong&gt;awesome&lt;/strong&gt; blogs but we need developers of all levels to create content because they can sometimes simplify topics in a way which others might not.&lt;/p&gt;

&lt;p&gt;Let's say I've just become comfortable with the basics of the JavaScript library React. I know why we have class components and functional components and the differences between them. There are others who might not be sure. They see some tutorials where components are written with classes and others written as functions without much of an explanation.&lt;/p&gt;

&lt;p&gt;If I had also experienced similar confusion then I would be best placed to explain the history of classes and the introduction of hooks before just diving in to writing stateful components.&lt;/p&gt;

&lt;p&gt;As writers we need to write content that is suited to our audience and sometimes those who have recently been though the struggles of a topic are the ones that are best placed to teach it 👍.&lt;/p&gt;

&lt;h2&gt;
  
  
  3) You will help teach other developers
&lt;/h2&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%2F1klloib8pgcxxsdufvvs.jpeg" 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%2F1klloib8pgcxxsdufvvs.jpeg" alt="illustration character pointing to schedule" width="772" height="549"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There will always be new developers taking up coding that rely on community created tutorials and articles. As you progress there will be more and more developers further back in the learning process than you. &lt;/p&gt;

&lt;p&gt;This means that even if you have just started out there will be &lt;strong&gt;others that would love to read the content you create&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you start writing on one of the many amazing community blogging sites such as &lt;a href="https://hashnode.com/" rel="noopener noreferrer"&gt;Hashnode&lt;/a&gt; or &lt;a href="https://dev.to/"&gt;Dev.to&lt;/a&gt; your content is guaranteed to be seen. Start small with a &lt;strong&gt;focused&lt;/strong&gt; article that tries to &lt;strong&gt;solve&lt;/strong&gt; a particular issue and your content will be appreciated by others.&lt;/p&gt;

&lt;p&gt;With consistency your posts will reach a larger audience and you will be helping to teach the next wave of developers and bloggers.&lt;/p&gt;

&lt;h2&gt;
  
  
  4) It looks great to future employers
&lt;/h2&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%2Fmns8leq0m7qr64lp4uwe.jpeg" 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%2Fmns8leq0m7qr64lp4uwe.jpeg" alt="Illustration character holding article" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Writing will help you to prove to employers that you know what you claim to know. Especially for those of us without a CS degree. You could link to your blog on LinkedIn to help enhance your profile and make it stand out.&lt;/p&gt;

&lt;p&gt;If an employer asks you &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;'Tell me what you know about arrow functions'&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;then you can confidently say &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;'Of course! Arrow functions are.... I also wrote an article for my blog all about arrow functions that was well received if you would like to see it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It might just help you stand out from the crowd 😎.&lt;/p&gt;

&lt;h2&gt;
  
  
  5) You will meet a lot of awesome people
&lt;/h2&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%2F86jnpxzs9rjnwt03m050.jpeg" 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%2F86jnpxzs9rjnwt03m050.jpeg" alt="Illustration character with community" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The web-development community is &lt;strong&gt;by far the most amazing and supportive community&lt;/strong&gt; I have been a part of. Without this I probably would never have started this blog.&lt;/p&gt;

&lt;p&gt;The web-development community have welcomed me and made me feel at home especially over on Twitter. Since I started with my blog I have been able to meet a lot of cool people. They have also helped me along by providing ideas on what to write about. &lt;/p&gt;

&lt;p&gt;My first post all about breaking down &lt;a href="https://blog.kieranroberts.dev/react-state-a-simple-and-easy-to-follow-breakdown" rel="noopener noreferrer"&gt;React State&lt;/a&gt; which became a featured article was recommended by someone over in our twitter community 👏.&lt;/p&gt;

&lt;p&gt;Being consistent with your writing will lead to interactions with other developers where you can share information with each other. Everyone benefits from sharing valuable information with each other.&lt;/p&gt;

&lt;h2&gt;
  
  
  6) Your writing and communication will improve
&lt;/h2&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%2Fm31ipvz4jpgllv207wxv.jpeg" 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%2Fm31ipvz4jpgllv207wxv.jpeg" alt="Illustrtion character showing writing" width="756" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As long as you're &lt;strong&gt;consistent&lt;/strong&gt; and you want to get better, you will! I think one of the main reasons we are hesitant to blog is that we have a lack of confidence in our writing. &lt;/p&gt;

&lt;p&gt;There are lots of very successful blog writers who aren't great with the language they write in. &lt;strong&gt;And that's OK! ✔&lt;/strong&gt; What better way is there to improve your writing than to tackle the problem head on.&lt;/p&gt;

&lt;p&gt;Think back to your coding skills in the first month and how they compare to now. You've probably improved a lot. It doesn't matter how great your coding was in the beginning. It only matters that you made the commitment to &lt;strong&gt;start&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  7) It is a lot of fun if you make it so
&lt;/h2&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%2Fl56qjjj1dsdzccsjf4oy.jpeg" 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%2Fl56qjjj1dsdzccsjf4oy.jpeg" alt="Illustration character having a party" width="537" height="642"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Write about &lt;strong&gt;topics you enjoy&lt;/strong&gt; and you will see that it is a lot of fun. Don't write about things that you think will bring you views. If it doesn't go well you will be annoyed with the result and end giving up. It will show in your writing if you're heart isn't in it.&lt;/p&gt;

&lt;p&gt;Instead write about things that will &lt;strong&gt;bring you enjoyment&lt;/strong&gt; or &lt;strong&gt;allow you to learn something new&lt;/strong&gt; in the process. And if you can bring out some of your personality into your writing that's even better 🙂.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Thanks for reading! Now get writing
&lt;/h3&gt;

&lt;p&gt;I hope you enjoyed the article and are now inspired to take up a blog. Let me know if this has helped you make the jump. If you know anyone that is thinking of taking up a blog then feel free to share the article around.&lt;/p&gt;

&lt;p&gt;I'm active over on twitter &lt;a href="https://twitter.com/Kieran6dev" rel="noopener noreferrer"&gt;@Kieran6dev&lt;/a&gt; so come and say hi 👋. Thanks for reading! Until next time&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>writing</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>React State: A simple and easy to follow breakdown</title>
      <dc:creator>Kieran Roberts</dc:creator>
      <pubDate>Wed, 10 Mar 2021 12:58:12 +0000</pubDate>
      <link>https://dev.to/kieran6roberts/react-state-a-simple-and-easy-to-follow-breakdown-3ai</link>
      <guid>https://dev.to/kieran6roberts/react-state-a-simple-and-easy-to-follow-breakdown-3ai</guid>
      <description>&lt;h2&gt;
  
  
  Content
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;What is state?&lt;/li&gt;
&lt;li&gt;What causes a component to re-render?&lt;/li&gt;
&lt;li&gt;How do we use state in React?&lt;/li&gt;
&lt;li&gt;Functional components and the &lt;code&gt;useState()&lt;/code&gt; hook&lt;/li&gt;
&lt;li&gt;Class components and &lt;code&gt;setState()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;State do's &amp;amp; don'ts&lt;/li&gt;
&lt;li&gt;Lifting state&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So you've just started learning and working with React. Great 😄! React is a fantastic JavaScript library that helps us in building interactive sites but it can difficult to grasp at first.&lt;/p&gt;

&lt;p&gt;Coming from vanilla JavaScript into React you will be hit by all kinds of terminology such as props, state, lifecycle, components, hooks and much more. It can be overwhelming but it doesn't have to be. &lt;/p&gt;

&lt;p&gt;State is a core concept of React. One that can be difficult to understand at first and especially difficult to master. So that is why I decided to write this article. I like React a lot and would like to help others who might be having difficulties. Let's get to it 👏.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is state?
&lt;/h2&gt;

&lt;p&gt;Let's consider some simple real world examples for a second. A door can either be open or closed hence in an open or closed state. It can be anything really. Think about a clock ticking over. Each time the second increases, the state of the clock changes. &lt;/p&gt;

&lt;p&gt;In React we build our UI by creating re-usable components that we write using JavaScript(usually JSX which is a syntax extension of JavaScript). Components are able to manage their own state locally and they can be combined to form large and complex UI.&lt;/p&gt;

&lt;p&gt;Consider a project written with vanilla JavaScript for a second. If we want to update an element normally we would have to query for the element and then do something to it to reflect the change of state. A common way to do this is by toggling certain classes that we have set up. Check  it out 👇.&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%2Fp57fmvx3hrwzl1qd01az.jpeg" 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%2Fp57fmvx3hrwzl1qd01az.jpeg" alt="Example of toggling state with vanilla JavaScript" width="800" height="196"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this simple example we are creating a function to toggle the CSS class "open" every time we click on the button element. We could also say that we are toggling the &lt;strong&gt;state&lt;/strong&gt; of the button which we show to the user through a change in style.&lt;/p&gt;

&lt;p&gt;React comes into its own when we are dealing with a more complex application that has a lot of moving parts and requires a lot of state changes/management. &lt;/p&gt;

&lt;p&gt;It is down in large part to React state in whether our components are dynamic or not. Values inside state can and often change over time as we require changes to our UI or data.&lt;/p&gt;

&lt;h2&gt;
  
  
  What causes a component to re-render?
&lt;/h2&gt;

&lt;p&gt;React is very smart when it comes to updating the DOM(Document Object Model). It uses something called the Virtual DOM which is similar to the real DOM that we work with except it is a lightweight virtual representation of it. &lt;/p&gt;

&lt;p&gt;Think about walking into your favorite fast food restaurant for second. You have the person working at the cash register that takes your money and we deal with this person every time we're hungry. But there's also that person in the back and this is the person making our food. The unsung hero and the one we know is there but never get to meet 🤣.&lt;/p&gt;

&lt;p&gt;Each DOM object has a corresponding virtual DOM object and React uses this virtual DOM to check for updates so that it doesn't have to directly update all of the real DOM's objects if they show no changes. This would be otherwise very inefficient.&lt;/p&gt;

&lt;p&gt;Whenever we render a JSX element in React, the whole virtual DOM is updated which happens incredibly quickly. Next up it compares the updated virtual DOM's objects against the real DOM. It will then only make changes to the objects in the real DOM that have changed and that is when we see the changes updated on the screen. This is the reason why React is so fast.&lt;/p&gt;

&lt;p&gt;So how do we update the DOM in React other than the initial first render 🤔 ?&lt;/p&gt;

&lt;p&gt;In React a component will undergo a re-render whenever its state changes. This can be done in two ways. Firstly through a direct change to the state using the state update functions provided by React which we will soon take a look at. Secondly through a change to the components props. &lt;/p&gt;

&lt;p&gt;Now that we have an idea of what state is in the context of React and why we need it, let's see how we can use it in our apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do we use State in React?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Functional components &amp;amp; Class components
&lt;/h3&gt;

&lt;p&gt;Before we start with some example we first have to differentiate the two different methods we have of working with state. While writing or reading about React you may have come across examples of code where components are written as JavaScript classes &lt;code&gt;Class Product extends React.Component {}&lt;/code&gt; or as functional components such as &lt;code&gt;const Product = () =&amp;gt; {}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It used to be that when we required a component to be a &lt;strong&gt;stateful&lt;/strong&gt; component(meaning we want create some local state for the component) we would use classes to construct the component. And when we required a &lt;strong&gt;stateless&lt;/strong&gt;(no local state required) component we would create the component as a functional component.&lt;/p&gt;

&lt;p&gt;The reason for this is that React did not provide a way for us to control a components state when we used functional components. If we wanted the the component to be stateful then we would have to use a class component and then create a state object with &lt;code&gt;this.state = {...};&lt;/code&gt; which we will soon see.&lt;/p&gt;

&lt;p&gt;In February 2019 React released a way in which we could now use state with functional components known as &lt;strong&gt;React Hooks&lt;/strong&gt;. They are essentially special functions that we can use and one of these hooks allows us to control a components state &lt;em&gt;without&lt;/em&gt; having to use classes. This does not mean that you are forced to use hooks instead of classes and vice versa. The definition provided by React fro hooks is as follows.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What is a Hook? A Hook is a special function that lets you “hook into” React features. For example, useState is a Hook that lets you add React state to function components. We’ll learn other Hooks later.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is however my preference to stick to functional components when working with React similar to many others who think that they are simpler to read and write and understand exactly what is going. In fact in the official React documentation in the section &lt;a href="https://reactjs.org/docs/hooks-intro.html" rel="noopener noreferrer"&gt;Introducing Hooks - React&lt;/a&gt;, there is a sub-heading that says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Classes confuse both people and machines&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you are coming from another language where classes are the norm then don't worry, you are more than welcome to use classes in your React code. React have made clear that they have no plans to remove classes from the library. I think those of us whose first programming language is JavaScript tend to prefer functional programming.&lt;/p&gt;

&lt;p&gt;In JavaScript we also have to deal with using the &lt;code&gt;this&lt;/code&gt; keyword in classes which behaves differently to many other programming languages and this can lead to code that can be harder to read or follow.&lt;/p&gt;

&lt;p&gt;To demonstrate this let's take a look at our first example of a simple stateful component. One will be written as a class and the other as a functional component so we can compare both methods but each component is otherwise the same. Don't worry to much if there's something in the code you are not sure about just yet. We'll cover the specifics about handling state very soon.&lt;/p&gt;

&lt;p&gt;Functional Component with &lt;code&gt;useState()&lt;/code&gt; hook 👇.&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%2F41j1dgea780aexmln0vi.jpeg" 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%2F41j1dgea780aexmln0vi.jpeg" alt="React functional component with state" width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we have a simple &lt;code&gt;Button&lt;/code&gt; component that requires us to use state so that we can conditionally show the the user whether it is in an "open" or "closed" state. Really contrived example but go with it 😃 just so we can make a quick comparison.&lt;/p&gt;

&lt;p&gt;Class Component using &lt;code&gt;setState()&lt;/code&gt; 👇.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fefi45eshburmiwwrrepv.jpeg" 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%2Fefi45eshburmiwwrrepv.jpeg" alt="React class component with state" width="800" height="596"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aside from there being less code to write in a functional component it is also &lt;em&gt;for me at least&lt;/em&gt; easier to parse. Despite this it is important to be comfortable with both class and functional components. There are a lot of resources, code snippets and documentation for React that were written before the existence of React hooks. Therefore we want to be comfortable with both so now we'll have a look at them. Let's get into it 👇.&lt;/p&gt;

&lt;h2&gt;
  
  
  Functional components and the &lt;code&gt;useState()&lt;/code&gt; hook
&lt;/h2&gt;

&lt;p&gt;As we briefly saw in the previous comparison we can use state in a functional component with the &lt;code&gt;useState()&lt;/code&gt; hook provided by React. To use this hook we call the &lt;code&gt;useState()&lt;/code&gt; function &lt;strong&gt;inside the component&lt;/strong&gt; and pass in one argument which will be the initial value for the state. This initial value can be anything and is not restricted to being an object such as &lt;code&gt;setState()&lt;/code&gt; which we will see in the next section.&lt;/p&gt;

&lt;p&gt;From calling the &lt;code&gt;useState()&lt;/code&gt; function we get two things back from React and we use array destructuring to deconstruct them into two variables. If you need a refresher for JavaScript destructuring then check out &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment" rel="noopener noreferrer"&gt;MDN - Destructuring Assignment&lt;/a&gt;. The first is called the state variable and we can give it any name we want. I suggest giving it a name that represents what the state is(e.g products, name, isOpen etc.).&lt;/p&gt;

&lt;p&gt;The second value we get back is a function that allows up to update the state and similarly we can choose an appropriate name for it although the convention is to give it the same name as the state value but prefixed with the word "set". For Example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const [ numbers, setNumbers ] = useState([0, 1, 2, 3]);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We can also have multiple different calls to &lt;code&gt;useState()&lt;/code&gt; to keep track of different values in state which may be required in a larger and more complex component. We could inlcude all of the following &lt;code&gt;useState()&lt;/code&gt; calls within a single component if we really desired.&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%2Febwcfl5qzgtbovif5utg.jpeg" 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%2Febwcfl5qzgtbovif5utg.jpeg" alt="useState() initializing examples" width="800" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we know how to create some state let's put it into action. We are going to create a simple component that will output an array of numbers. We will have a button and whenever we click the button we will increment the last number of the array by 1 and output the full list with our state updates. &lt;/p&gt;

&lt;p&gt;Here is an example of it after we have clicked the button once and therefore added the number 4 to the initial list &lt;code&gt;[0, 1, 2, 3]&lt;/code&gt; 👇.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61dcxeqhwrf0kqvdamax.jpeg" 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%2F61dcxeqhwrf0kqvdamax.jpeg" alt="Example project output" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We start by creating the functional component and calling the &lt;code&gt;useState()&lt;/code&gt; function.&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%2Fxvjo29ses11djb5mw4j4.jpeg" 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%2Fxvjo29ses11djb5mw4j4.jpeg" alt="React useState() example" width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So now we have our state value &lt;code&gt;numbers&lt;/code&gt; set initially to the array &lt;code&gt;[0, 1, 2, 3]&lt;/code&gt; that we pass in to &lt;code&gt;useState&lt;/code&gt; and we also have our function that will let us update the state value when something happens. So let's put it all into action.&lt;/p&gt;

&lt;p&gt;Whenever we want to update the state we call the &lt;code&gt;SetNumbers()&lt;/code&gt; function in our case. Let's write a simple function that holds the logic to find the next number to add to the list and then update the state as we have defined. This will cause a component re-render and the result can then be shown to the user.&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%2Felx4cl446ybolyihrzw8.jpeg" 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%2Felx4cl446ybolyihrzw8.jpeg" alt="React.useState() example" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we access the last number of the array with &lt;code&gt;array[array.length - 1]&lt;/code&gt; and then we call the update state function. We pass in an array where we spread the values from the current numbers state value using the JavaScript spread syntax &lt;code&gt;...&lt;/code&gt; so that we can still keep them in state. Then to the end of the array we add current last value + 1.&lt;/p&gt;

&lt;p&gt;The final step is to make sure we return something because all React component must return some kind of React element. In the case of a functional component we can do this with the &lt;code&gt;return&lt;/code&gt; keyword. So let's finish our example and update the UI to show that our state is changing.&lt;/p&gt;

&lt;p&gt;(note: In the map function below each &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; should contain a unique key property which is explained here &lt;a href="https://reactjs.org/docs/lists-and-keys.html" rel="noopener noreferrer"&gt;React - Lists and Keys&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyb4a3bwakpk2mbjfjqt5.jpeg" 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%2Fyb4a3bwakpk2mbjfjqt5.jpeg" alt="Complete useState() example" width="800" height="564"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to trigger the function that add adds a number to the array I have rendered a button for the user with an &lt;code&gt;onClick&lt;/code&gt; handler that will run our function after a click. Then we want to render our list of numbers to the page. We can do with with the JavaScript &lt;code&gt;map()&lt;/code&gt; function which allows us to perform some action on each element of the array and return the result of each action into a new array.&lt;/p&gt;

&lt;p&gt;This is a very common pattern in React where we have some data(e.g result of an external API call) and we have to map it in some form to the DOM. Here we map each number into a list element by passing each number into the &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt;. Often we would have other custom components where we map the data at each index into the component.&lt;/p&gt;

&lt;p&gt;And that's it! We have our stateful functional component that will update upon user interaction 👍. Let's take a look at how we would achieve the same result in a class component.&lt;/p&gt;

&lt;h2&gt;
  
  
  Class components and &lt;code&gt;setState()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Before the introduction of React Hooks we were forced to write our stateful components using classes. React provided us with the &lt;code&gt;setState()&lt;/code&gt; api which allows us to request some changes to our state. I use the word request because it is not guaranteed that React will update the state changes immediately. It is possible that React will delay the update for performance reasons so attempting to read the state value immediately after a change might lead to unexpected results.&lt;/p&gt;

&lt;p&gt;Nevertheless calling this will always lead to a component re-render as we have previously explored. It takes two arguments shown here &lt;code&gt;setState(updater, [ callback ])&lt;/code&gt; where &lt;code&gt;updater&lt;/code&gt; is a function that can take two parameters as state and props and returns the change of state &lt;code&gt;(state, props) =&amp;gt; stateChange&lt;/code&gt;. The callback parameter is an optional function that gets executed after the component has re-rendered with state changes. This callback is not often used and React suggests not to use it but instead provides &lt;a href="https://reactjs.org/docs/state-and-lifecycle.html" rel="noopener noreferrer"&gt;LifeCycle Methods&lt;/a&gt; which we will not cover today.&lt;/p&gt;

&lt;p&gt;We can also choose to just pass an object as the first parameter of &lt;code&gt;setState()&lt;/code&gt; instead of the function and this will create a shallow merge of our new state into the state object. This just means that the values in our object will override any duplicate properties with our new values, leaving other properties unchanged and this is how we are going to update our state in our example. This is an example of the merging 👇.&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%2F32y11wbhpbvlfax11wq4.jpeg" 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%2F32y11wbhpbvlfax11wq4.jpeg" alt="setState({}) shallow merge explanation" width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Back to our example we start by creating our local state object in our class constructor like this 👇.&lt;/p&gt;

&lt;p&gt;(Note: Don't forget to import React which is not shown in the following examples 😅).&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%2Fi9yaqbxztm9wxfn03bvz.jpeg" 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%2Fi9yaqbxztm9wxfn03bvz.jpeg" alt="React class using this.state setup" width="800" height="356"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We do this by setting &lt;code&gt;this.state&lt;/code&gt; to an object where we can specify the properties we want to keep in state with their initial values. Similarly to a functional component we could use more state variables by adding more properties into our state object.  &lt;/p&gt;

&lt;p&gt;Next we can update our &lt;code&gt;handleAddNumber&lt;/code&gt; function to be suitable for a class component.&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%2Fn74q5jnzhz5n7ds47g4g.jpeg" 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%2Fn74q5jnzhz5n7ds47g4g.jpeg" alt="React class using this.state with update function" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The only changes we've made here is to use the &lt;code&gt;this&lt;/code&gt; keyword when referencing our state value and update function so that we are referring to our Numbers Class and I have also stored the current state in a temporary variable for readability. It is also important to note that our &lt;code&gt;handleAddNumber&lt;/code&gt; method is created using the arrow function syntax so that we don't have to bind our function to the correct &lt;code&gt;this&lt;/code&gt; in the &lt;code&gt;onClick&lt;/code&gt; handler. Arrow functions do not have their own &lt;code&gt;this&lt;/code&gt; and therefore it will refer to enclosing execution context, in this case our class.&lt;/p&gt;

&lt;p&gt;If you would like a refresher for understanding the &lt;code&gt;this&lt;/code&gt; keyword in JavaScript then check it out here at &lt;a href="https://javascript.info/object-methods" rel="noopener noreferrer"&gt;JavaScript Info - Object methods, "this"&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we refer to our current state with &lt;code&gt;this.state.numbers&lt;/code&gt; and I have stored this in a constant for readability. In order to update the state we &lt;code&gt;setState()&lt;/code&gt; provided by react and pass in our new state object. Finally let's return some React Element using the React built-in &lt;code&gt;render()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;(note: In the map function below each &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; should contain a unique key property which is explained here &lt;a href="https://reactjs.org/docs/lists-and-keys.html" rel="noopener noreferrer"&gt;React - Lists and Keys&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi6g4tfmv1nh2mf8k2mdi.jpeg" 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%2Fi6g4tfmv1nh2mf8k2mdi.jpeg" alt="React class complete example" width="800" height="612"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once again we have to add the &lt;code&gt;this&lt;/code&gt; keyword to our handler function as explained and also to our state value &lt;code&gt;this.state.numbers&lt;/code&gt; that we are mapping to the DOM.&lt;/p&gt;

&lt;h2&gt;
  
  
  State Do's &amp;amp; Don'ts
&lt;/h2&gt;

&lt;p&gt;Now that we know how to create stateful components we should consider the things to avoid when we use state in React.&lt;/p&gt;

&lt;p&gt;Firstly it is important to know that state changes in React is asynchronous. This means that we need to be careful when calling multiple state change functions in quick succession. We will end up running into problems where we call multiple state updates inside the same cycle.&lt;/p&gt;

&lt;p&gt;Secondly it is important that we should never try to change the state value directly using &lt;code&gt;this.state.numbers = ...&lt;/code&gt; but instead always use the &lt;code&gt;setState()&lt;/code&gt; or &lt;code&gt;useState()&lt;/code&gt; options function for classes or the update function provided by &lt;code&gt;useState()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There are also rules for using React hooks such as the &lt;code&gt;useState()&lt;/code&gt; hook we have previously used ourselves. React provides us with a few more very useful hooks(and some less useful) that give us our functional component alternatives to using React class lifecycle methods.&lt;/p&gt;

&lt;p&gt;The first important rule is that we don't call our hooks anywhere other than the top level. Don't call them inside loops or conditional and try to call them before your functions might experience an early return.&lt;/p&gt;

&lt;p&gt;This is because we have to ensure that our component hooks are executed in the same order every time our component renders otherwise we will run into errors with React. If the component only sometimes executes an &lt;code&gt;if&lt;/code&gt; statement for example with some state update then there will be a difference in the order that the hooks were called. It is a common problem for React learners and one that will get easier to understand with time.&lt;/p&gt;

&lt;p&gt;Secondly we cannot call out &lt;code&gt;useState()&lt;/code&gt; (or other hooks) or subsequent state update function outside of React Functions(this means React components or custom hooks which are just themselves functions). &lt;/p&gt;

&lt;p&gt;For now it is good to just be aware of the important rules and get playing with state. When you run into problems you will have a better understanding of why you are receiving the error 😃.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lifting State
&lt;/h2&gt;

&lt;p&gt;Lifting State is a term you may have come across during your learning and it describes a solution for the flow of data through react components. What happens when we have two different components and we would like them to react(pun intended 😅) to the changes in state of another component. Often we have multiple components and we want them to show some changes based on the state changes of another component.&lt;/p&gt;

&lt;p&gt;In order to understand this further we need to know about the flow of data through our app. In React we have to pass props down the component tree from top to bottom. We cannot pass this data up from a child to a parent or from a child to a sibling. The data comes from ancestors downwards.&lt;/p&gt;

&lt;p&gt;Consider the following example where the &lt;code&gt;Child&lt;/code&gt; component originally has some local state but then we realize that the &lt;code&gt;ChildSibling&lt;/code&gt; component also requires the same state. In React we want to limit the amount of stateful components as much as possible. The possibility of bugs increases when we work with more stateful components and if we keep re-writing the same code in different places then we are not writing efficient code. &lt;/p&gt;

&lt;p&gt;So before we lift our state up we have 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%2Fqbhbue9ztjelx44xxhpw.jpeg" 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%2Fqbhbue9ztjelx44xxhpw.jpeg" alt="Before state is lifted example" width="800" height="788"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we are just toggling the &lt;code&gt;isOpen&lt;/code&gt; state variable with a button click using &lt;code&gt;setIsOpen(!isOpen)&lt;/code&gt; which means not the current value of &lt;code&gt;isOpen&lt;/code&gt;. A boolean can only ever be true or false so we just flip the value when the button is pressed.&lt;/p&gt;

&lt;p&gt;In order for both child components to utilize this state we can 'lift' it to the closest common ancestor of both components. In our case it is the &lt;code&gt;Parent&lt;/code&gt; component which we can see is returning both of the child components. &lt;/p&gt;

&lt;p&gt;So what we can do is lift the state to the &lt;code&gt;Parent&lt;/code&gt; component declaring it only once. Then we can pass the state value as a prop to each component so that it can render something conditionally. We will also move our button to the parent component.&lt;/p&gt;

&lt;p&gt;So let's lift it up to the &lt;code&gt;Parent&lt;/code&gt; and pass it down to each child.&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%2Fly17zhun2ajsncjd40eu.jpeg" 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%2Fly17zhun2ajsncjd40eu.jpeg" alt="After state is lifted" width="800" height="836"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you can see we define our state in the &lt;code&gt;Parent&lt;/code&gt; component and pass it to our children via the props object which we deconstruct inside the parameters into the variable so we don't have to bother with writing &lt;code&gt;props.isOpen&lt;/code&gt;. We still only have on stateful component which is great 😄.&lt;/p&gt;

&lt;p&gt;It is important to not that our child components no longer have control over this state and we cannot modify the values passed down from the parent as props. They can however update in some way as a result of the parent modifying the state.&lt;/p&gt;

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

&lt;p&gt;There is so much more to learn with regards to React and state. Try building some simple components that might be used on a website to practice with state. &lt;/p&gt;

&lt;p&gt;Start small like a box that toggles its visibility with a button click. Maybe a clock that uses state to update itself with every second and eventually you will be building bigger and more complex examples. &lt;/p&gt;

&lt;p&gt;When you are ready I suggest exploring the other react hooks we have available other than &lt;code&gt;useState()&lt;/code&gt; or if you prefer classes then check out the React lifecycle methods.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed reading the article as much as I enjoyed writing it. For more React and front-end related content you can follow me &lt;a href="https://twitter.com/Kieran6dev" rel="noopener noreferrer"&gt;@Kieran6dev&lt;/a&gt;. Until next time 👋.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>A nice introduction to JavaScript variables</title>
      <dc:creator>Kieran Roberts</dc:creator>
      <pubDate>Wed, 03 Mar 2021 18:28:05 +0000</pubDate>
      <link>https://dev.to/kieran6roberts/a-nice-introduction-to-javascript-variables-40gd</link>
      <guid>https://dev.to/kieran6roberts/a-nice-introduction-to-javascript-variables-40gd</guid>
      <description>&lt;h1&gt;
  
  
  Content
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;What is a programming variable?&lt;/li&gt;
&lt;li&gt;How do we create a JavaScript variable?&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;var&lt;/code&gt;, &lt;code&gt;let&lt;/code&gt; &amp;amp; &lt;code&gt;const&lt;/code&gt; declarations&lt;/li&gt;
&lt;li&gt;Scope, Hoisting &amp;amp; Shadowing&lt;/li&gt;
&lt;li&gt;Which variable declaration keyword should I use?&lt;/li&gt;
&lt;li&gt;How should we name our variables?&lt;/li&gt;
&lt;li&gt;What can we store inside variables?&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What is a programming variable?
&lt;/h2&gt;

&lt;p&gt;One of the core features of any programming language are things called variables. We use variables to store data. Think of them as boxes that contain some entity and without them we lose the item that was stored inside.&lt;/p&gt;

&lt;p&gt;Consider a bottle of beer for a second. Or juice depending on your age 🤔. If we empty out the liquid it no longer has a container and is doomed to be lost to the floor.&lt;/p&gt;

&lt;p&gt;Variables are essential to programming languages because they allow us to store pieces of data that we might need later on. &lt;/p&gt;

&lt;p&gt;To be able to focus on variables I will stick to using simple examples and assigning basic primitive data types as values to variables(e.g. numbers, strings and booleans). If you would like to check out more about JavaScript data types you can have a quick read of this article by MDN - &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures" rel="noopener noreferrer"&gt;JavaScript data types and data structures&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ready? Let's go!&lt;/p&gt;

&lt;h2&gt;
  
  
  How do we create a JavaScript variable?
&lt;/h2&gt;

&lt;p&gt;To begin with let's have a look at how we create a variable. The most common syntax is generally as follows where we declare our variable with a name and initialize it with a value 👇.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(variable declaration) (variable name) = (some value);&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;We also add a semi-colon &lt;code&gt;;&lt;/code&gt; after declaring the variable which is used to to separate expressions. It is also used across many other programming languages for this reason and in JavaScript although it is optional, it is highly recommended that we use them after each code instruction to avoid potential bugs that can arise as a result.&lt;/p&gt;

&lt;p&gt;It is also possible to create certain variables that are not initialized with a value. In this case the syntax is as follows:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(variable declaration) (variable name);&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Variables created by in this way are initialized by JavaScript at execution with a value of &lt;code&gt;undefined&lt;/code&gt; and later we will see this in action.&lt;/p&gt;

&lt;p&gt;In JavaScript there are three primary methods of creating variables each with their differences. We start by defining the keyword associated with creating the variable before usually assigning some value to it. Let's take a look at each method and the differences between them.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;var&lt;/code&gt;, &lt;code&gt;let&lt;/code&gt; &amp;amp; &lt;code&gt;const&lt;/code&gt; declarations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  const
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;const&lt;/code&gt; declaration creates a read only reference to a value that we must be defined when we create the variable. Let's create some variables below 👇.&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%2F6er13qhof4u19797pk1k.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%2F6er13qhof4u19797pk1k.jpg" alt="Defining some const variables" width="800" height="620"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(The last example is useless I'll admit. There is no need to store a boolean value in a constant that can't be changed, we could just use the value &lt;code&gt;false&lt;/code&gt; instead but I thought it was funny so it stays 😄).&lt;/p&gt;

&lt;p&gt;When we define a variable using &lt;code&gt;const&lt;/code&gt; what we are actually saying is that the variable identifier(name) cannot be reassigned to another value. See here:&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%2Fff49gzdnf0ojobeigvjn.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%2Fff49gzdnf0ojobeigvjn.jpg" alt="Example of const reassign error" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the &lt;code&gt;const&lt;/code&gt; declaration we must also initialize the variable with a value. Not doing so will result in an error.&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%2Fq98nw03jtvspk65jgu5a.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%2Fq98nw03jtvspk65jgu5a.jpg" alt="Example of const re-assign error" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This does not mean that the value itself is immutable(can't be changed). Check out this article for a deeper dive to constant immutability with an object example (When to capitalize your JavaScript constants - {Brandon Wozniewicz})[&lt;a href="https://www.freecodecamp.org/news/when-to-capitalize-your-javascript-constants-4fabc0a4a4c4/" rel="noopener noreferrer"&gt;https://www.freecodecamp.org/news/when-to-capitalize-your-javascript-constants-4fabc0a4a4c4/&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;We can however create a new &lt;code&gt;const&lt;/code&gt; variable that points at an exisiting &lt;code&gt;const&lt;/code&gt; variable. In this situation the value stored in the existing variable is copied into the new variable.&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%2Fj0jthn1ef71348h73tfn.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%2Fj0jthn1ef71348h73tfn.jpg" alt="Example of pointing one const variable at another" width="800" height="590"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  let
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;let&lt;/code&gt; declaration differs from &lt;code&gt;const&lt;/code&gt; because the value stored within a &lt;code&gt;let&lt;/code&gt; variable can be changed. We use the &lt;code&gt;let&lt;/code&gt; declaration when we know that later on in the program the value is likely to be changed.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;let&lt;/code&gt; variables we are not forced to initialize it with an initial value. In this case the variable will be undefined but will not throw an error. Check it out.&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%2Ftfh33uciuxw2b7tgj1r6.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%2Ftfh33uciuxw2b7tgj1r6.jpg" alt="Examples of declaring let variables" width="800" height="734"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  var
&lt;/h3&gt;

&lt;p&gt;Using the &lt;code&gt;var&lt;/code&gt; declaration predates the previous two examples. It used to be the only way do declare variables until &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt; were introduced to JavaScript with ES6 in 2015. &lt;/p&gt;

&lt;p&gt;In modern code we have taken to using &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt; instead of &lt;code&gt;var&lt;/code&gt; because of a few problems that can arise which we will soon explore. It is advisable to stick with &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt; although having an understanding of how &lt;code&gt;var&lt;/code&gt; works is important to fully understanding JavaScript. &lt;/p&gt;

&lt;p&gt;Perhaps you will come across this syntax in older codebases or maybe will be asked to solve JavaScript problems that use the &lt;code&gt;var&lt;/code&gt; keyword.&lt;/p&gt;

&lt;p&gt;Similarly to &lt;code&gt;let&lt;/code&gt; it allows us create variables can either be initialized with a value or not initialized at all.&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%2Fyv65wcaqgp0vnchpgqmx.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%2Fyv65wcaqgp0vnchpgqmx.jpg" alt="Examples of variables using var" width="800" height="648"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unlike the &lt;code&gt;let&lt;/code&gt; defined variable we can reassign a &lt;code&gt;var&lt;/code&gt; variable to a different value like 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%2F453gr0z087i8ep3v0s8d.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%2F453gr0z087i8ep3v0s8d.jpg" alt="var reassign example" width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to properly understand the what the &lt;code&gt;var&lt;/code&gt; syntax does, we need to know about a couple of core concepts which are key to mastering JavaScript. Those concepts are called &lt;strong&gt;Scope&lt;/strong&gt; and &lt;strong&gt;Hoisting&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scope and Hoisting
&lt;/h2&gt;

&lt;p&gt;While I am not going to dive too far into each topic(this would probably take at least two more articles to fully explore 😃), it is important to grasp the idea so that we can explore the differences between &lt;code&gt;var&lt;/code&gt;, &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Scope is a concept that defines what variables are accessible at any point in a script. When we create a variable we are defining the scope variable and what has access to it without really knowing it. In JavaScript we have two types of scope when we define a variable. They are &lt;strong&gt;Block-scope&lt;/strong&gt; and &lt;strong&gt;Function-scope&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When we create a variable with &lt;code&gt;let&lt;/code&gt; or &lt;code&gt;const&lt;/code&gt; we are defining the scope of the variable as Block-scope. This means that we can only access this variable from within the same block or further down in the scope tree. A block is defined between the curly braces &lt;code&gt;{}&lt;/code&gt; syntax such as in an &lt;code&gt;if&lt;/code&gt; statement, a function and more.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;var&lt;/code&gt; on the other hand defines a variables scope as the current execution context. This is a fancy term that means it will either refer to the global scope(which is shown in the following examples) or the function that it lives in, also known as Function-scope. &lt;/p&gt;

&lt;p&gt;In JavaScript a function is simply a piece of reusable code that we can write that allows us to run it whenever we like. When we create a function a new scope is defined for that function. &lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;var&lt;/code&gt; to create variables can lead to more unpredictable code where access to the variable is possible outside of the current block scope. Consider the following situations 👇.&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%2Ftut3cajx5sf8zqur2z2m.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%2Ftut3cajx5sf8zqur2z2m.jpg" alt="Accessing var variable outside of its block" width="800" height="762"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There the &lt;code&gt;if&lt;/code&gt; statement has its own block scope defined by the curly braces and we define a variable using &lt;code&gt;var&lt;/code&gt;. But this variable is function-scoped meaning it can be accessed from outside in the scope above(in this case the global scope). And this is not necessarily something we want to be able to do. If we try to do the same but instead create the variable using &lt;code&gt;let&lt;/code&gt; then we will see a very different result.&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%2Fjyhjzw6077ybgw2g1rw2.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%2Fjyhjzw6077ybgw2g1rw2.jpg" alt="Example of let block scope" width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;let&lt;/code&gt; defines the scope of the variable as being block-scoped meaning we can only use it from within that block or any nested scope below this block. Here we will add an &lt;code&gt;if&lt;/code&gt; check inside the original &lt;code&gt;if&lt;/code&gt; therefore creating another nested scope such as 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%2Felnkfdubtr5l53bj9z9t.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%2Felnkfdubtr5l53bj9z9t.jpg" alt="Example of nested scope" width="800" height="706"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here you can see we are able to access the &lt;code&gt;let&lt;/code&gt; variable from a nested scope of the scope in which it was created but not from outside. This is a key concept to be aware of as you start working with functions and you are only able to access certain variables in specific scopes. &lt;/p&gt;

&lt;p&gt;The second key concept I mentioned was Hoisting. Hoisting is the JavaScript mechanism by which variables and functions are moved to the top of their own scope before the code is executed. When we declare a JavaScript variable it is hoisted. In the case of the &lt;code&gt;var&lt;/code&gt; declaration if we try to access it before we declare it, we won't get an error and instead it will return the value &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Opposed to this are &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt; where JavaScript does not allow us to access theses variables before we declare them. They are still hoisted to the top of the block however instead of returning &lt;code&gt;undefined&lt;/code&gt; and carrying on we will get an error for trying to access it before declaration.&lt;/p&gt;

&lt;p&gt;It is always advised whenever possible to initialize your variable declarations with a value to avoid situations where you run into &lt;code&gt;undefined&lt;/code&gt; instead of an error resulting in a difficult to debug problem.&lt;/p&gt;

&lt;p&gt;Finally shadowing is a concept that we see when we define a variable in a nested scope that has the same name as a variable in its outer scope. Take a look 👇.&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%2F6fuufd1szwz2misgwmpi.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%2F6fuufd1szwz2misgwmpi.jpg" alt="example of variable shadowing" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even though we have already defined a &lt;code&gt;const&lt;/code&gt; called name, JavaScript does not throw us an error. From the nested scope name will have the value "Bob" while on the outside it will be "Kieran".&lt;/p&gt;

&lt;h2&gt;
  
  
  Which variable declaration syntax should I use?
&lt;/h2&gt;

&lt;p&gt;This decision has become tricky in recent years since &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt; were introduced to JavaScript with ES6(EcmaScript 2015) especially to beginners who are unsure of the differences. In modern code you will often see &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt; used exclusively, replacing the former declaration &lt;code&gt;var&lt;/code&gt;. These newer methods of declaring variables are generally considered the better approach because they solve some of the problems that come with using &lt;code&gt;var&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Using the &lt;code&gt;var&lt;/code&gt; keyword can lead to some unpredictable results. &lt;code&gt;var&lt;/code&gt; allows for multiple variables of the same name to be declared re-assigning it a new value. But this is not really something we want. We might accidentally overwrite an important piece of data and JavaScript would not give us an error leading to problems while debugging.&lt;/p&gt;

&lt;p&gt;This type of silent failing can be largely eliminated if we stick to using &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt; where block-scope is more predictable and easier to grasp for most developers. We will be provided with errors by JavaScript which means we can fix our bugs early before they become a pain in the backside.&lt;/p&gt;

&lt;p&gt;Therefore if we need a constant variable where the value is not going to change we use &lt;code&gt;const&lt;/code&gt;. If it's value is likely to change then go with &lt;code&gt;let&lt;/code&gt;. Even if you are not sure it is not the end of the world. You can start by using &lt;code&gt;const&lt;/code&gt; and if you later change the value stored in the variable, your code editor should warn you about the error and before you know it you'll know exactly which declaration to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  How should we name our variables?
&lt;/h2&gt;

&lt;p&gt;So we now know what variables are. We know how to create them and which versions of variable creation we should use based on the situation. One often overlooked aspect of creating variables is naming them. We should always try to give our variables names that correspond to the data that they hold and sometimes it is more difficult than it seems.&lt;/p&gt;

&lt;p&gt;Assigning names in this way helps us because our code is then more readable and much easier to debug. Check out some examples of good and bad variable names 👇&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%2Fc8tdm9u7hwd2j1cvf4c6.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%2Fc8tdm9u7hwd2j1cvf4c6.jpg" alt="variable naming examples" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and another&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%2Figcbb5lsmb4li1uhonbi.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%2Figcbb5lsmb4li1uhonbi.jpg" alt="variable naming examples" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see in the example above we have a variable name called &lt;code&gt;productName&lt;/code&gt; which contains multiple words with the second of which beginning with an uppercase letter. This naming convention is called "Camel case" or "camelCase" where we don't use any spaces to separate words but instead we capitalize any words that come after the first word.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;My first Name&lt;/em&gt; would become &lt;em&gt;myFirstName&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Camel case naming convention is the commonly accepted method of naming JavaScript variables and also functions with a few exceptions(class initializations, private class properties etc) which will not be covered in this article.&lt;/p&gt;

&lt;p&gt;Another naming convention that you might come across relates to boolean values. To help us differentiate boolean variables from other variable types we prefix the variable name with a helper word such as "is" or "are".&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%2Fc5x5givoz7717i09bkfx.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%2Fc5x5givoz7717i09bkfx.jpg" alt="Example of boolean variable naming convention" width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You might also look at someone else's JavaScript code and see a &lt;code&gt;const&lt;/code&gt; variable that is all uppercase letters. This is used to denote a constant variable that will point at the same primitive value throughout the lifetime of the script. These primitive values include &lt;em&gt;string&lt;/em&gt;, &lt;em&gt;number&lt;/em&gt;, &lt;em&gt;boolean&lt;/em&gt;, &lt;em&gt;symbol&lt;/em&gt;, &lt;em&gt;undefined&lt;/em&gt; and &lt;em&gt;BigInt&lt;/em&gt; but this convention is generally used when the value is a string or number. &lt;/p&gt;

&lt;p&gt;There is really no use case for storing a boolean in a &lt;code&gt;const&lt;/code&gt; (as I explained in the first example 😁) that you never intend to change while storing undefined in a variable is not recommended. Symbols and BigInt types are not used as often although they have their use-cases in other situations.&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%2Fpqejf32iuowwszzi325q.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%2Fpqejf32iuowwszzi325q.jpg" alt="uppercase constant variable naming example" width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is again a convention and not required although it does help us differentiate our variables so they are easier to spot and debug.&lt;/p&gt;

&lt;p&gt;There are two rules when it comes to naming variables that JavaScript imposes on us. These are as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The first character of the variable name cannot be a digit&lt;/li&gt;
&lt;li&gt;Variable name can only contain letters, digits, or the symbols underscore(_) and dollar sign($).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To finish let's take a quick look at a few examples of names we cannot give to variables even if we really wanted to. Check it out 👇.&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%2Fhp7zc3m1kbap0s8jqx1i.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%2Fhp7zc3m1kbap0s8jqx1i.jpg" alt="Variable names not allowed by JavaScript example" width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;JavaScript also has a few keywords that are reserved and cannot be used to name variables. These can be found here at &lt;a href="https://www.w3schools.com/js/js_reserved.asp" rel="noopener noreferrer"&gt;w3schools.com - JavaScript Reserved Words&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff82lytykz2jjdcq4jyg2.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%2Ff82lytykz2jjdcq4jyg2.jpg" alt="examples of variables using reserved words" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What can we store inside variables?
&lt;/h2&gt;

&lt;p&gt;So far you have seen me store strings, booleans and numbers inside variables to introduce you to the basics but really we can use them to store much more. More advanced JavaScript data types such as arrays, objects and also functions which are themselves just objects can and are often stored inside variables so that we can reference the data they hold whenever we require. Below is an example of common types of data we store in variables.&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%2F8q60cqvmywadi29ocf2w.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%2F8q60cqvmywadi29ocf2w.jpg" alt="Examples of advanced data types stored in variables" width="800" height="648"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Variables are key in allowing us to build all kinds of applications and there is so much we can do but this has been a nice introduction to JavaScript variables. We've only just scratched the surface.&lt;/p&gt;

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

&lt;p&gt;Now that you have a basic understanding of JavaScript variables I hope you can go off and experiment yourself to see what else you can do with them.&lt;/p&gt;

&lt;p&gt;Thanks for reading! If you would like to see more from me including my progress as a developer then come say hi on twitter &lt;a href="https://twitter.com/Kieran6dev" rel="noopener noreferrer"&gt;@Kieran6dev&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Lesser known HTML attributes and what they can do for us</title>
      <dc:creator>Kieran Roberts</dc:creator>
      <pubDate>Wed, 24 Feb 2021 14:57:49 +0000</pubDate>
      <link>https://dev.to/kieran6roberts/lesser-known-html-attributes-and-what-they-can-do-for-us-5ebd</link>
      <guid>https://dev.to/kieran6roberts/lesser-known-html-attributes-and-what-they-can-do-for-us-5ebd</guid>
      <description>&lt;p&gt;There are many attributes that we use on a daily basis when writing HTML. Attributes such as &lt;code&gt;src&lt;/code&gt; for &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tags which allows us provide a source destination for where our image resides.&lt;/p&gt;

&lt;p&gt;These are the kind of attributes that most of us are familiar with. Many of them are necessary for the particular element to function as intended. There are however many other attributes that like me, you might not have even known existed.&lt;/p&gt;

&lt;p&gt;Recently I completed a HTML quiz and was surprised at how many attributes I had never seen before. So let's explore some of these attributes together including what they do, when to use them and what elements they suitable with.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Available globally
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;translate&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;translate&lt;/code&gt; is an enumerated attribute meaning we need to explicitly pass &lt;code&gt;translate="yes"&lt;/code&gt; or &lt;code&gt;translate="no"&lt;/code&gt; as opposed to just &lt;code&gt;translate&lt;/code&gt;. It is used to instruct translation tools whether or not the text node of an element and its attribute values that are able to be translated, should be translated.&lt;/p&gt;

&lt;p&gt;Think of a situation where your site is being translated to another language but you would prefer if your brand name was not translated. You can instruct these translation tools to not translate it by passing the attribute &lt;code&gt;translate="no"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Furthermore this attribute is respected by major automatic translation technologies such as Google Translate although it is not currently supported by Firefox or Internet Explorer. It could also be picked up by a human's translator tool.&lt;/p&gt;

&lt;p&gt;Setting this attribute to &lt;code&gt;translate="yes"&lt;/code&gt; is unlikely to ever be required because a lack of any &lt;code&gt;translate&lt;/code&gt; attributes on the page signals to the translation tool that everything is to be translated anyway. Although if you need to override this for a particular then maybe you should consider setting this attribute to &lt;code&gt;translate="no"&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;a href="/" translate="no"&amp;gt;
  My Brand Name
&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;em&gt;dir&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;This attribute is used to change the direction of the elements text content and has three possible states. However it should not be used as a method of aligning text because using &lt;code&gt;dir="rtl"&lt;/code&gt; with an &lt;code&gt;dir="ltr"&lt;/code&gt; based font will mean your full stops will be in the incorrect position on the left side of the text.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ltr&lt;/strong&gt; &lt;br&gt;
Left-to-right text direction. This is the default value.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;rtl&lt;/strong&gt; &lt;br&gt;
Right-to-left text-direction. Languages such as arabic, hebrew, and pashto are written in this direction.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;auto&lt;/strong&gt; &lt;br&gt;
Allows the browser to decide the value based on an algorithm that checks for strong directionality in the elements text characters.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;header&amp;gt;
    &amp;lt;h1&amp;gt;
        dir attribute changes the direction of the elements text content
    &amp;lt;/h1&amp;gt;
    &amp;lt;p dir="rtl"&amp;gt;
        Text is in english but is aligned to the right without any influence from CSS although punctuation might be out of place.
    &amp;lt;/p&amp;gt;
&amp;lt;/header&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;em&gt;spellcheck&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;This attribute is used to determine whether or not an elements text content may be checked for spelling and grammar mistakes. It can be applied to any element that contains the &lt;code&gt;contenteditable&lt;/code&gt; attribute which allows for its text to be edited by the user.&lt;/p&gt;

&lt;p&gt;This however is not recommended especially for production code because. You can however use it on an &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt; element as long as the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; element is not of type &lt;code&gt;password&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It is also an enumerated attribute which means you must explicitly pass &lt;code&gt;spellcheck="true"&lt;/code&gt; or &lt;code&gt;spellcheck="false"&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;textarea contenteditable="true" spellcheck="true"&amp;gt;
    spellcheck enabled with editable conten.
&amp;lt;/textarea&amp;gt;
&amp;lt;textarea spellcheck="false"&amp;gt;
    spellcheck disabl.
&amp;lt;/textarea&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fsw142nzwmdwn5oe8iaex.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%2Fsw142nzwmdwn5oe8iaex.jpg" alt="Example of spellcheck attr on textarea elements" width="800" height="305"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;ping&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;ping&lt;/code&gt; attribute is used on an &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; element and when clicked it sends a POST request with the body "ping" to the url or multiple urls specified which can also be written as a space seperated list of urls.&lt;/p&gt;

&lt;p&gt;A use case for this attribute could be analytics where the owner of the site wants to keep a record of the number of clicks on the link.&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;a href="https://something.com" ping="https://analytics.com"&amp;gt;
  Checkout this content
&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;em&gt;download&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;We can use the &lt;code&gt;download&lt;/code&gt; attribute on the &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag in combination with the &lt;code&gt;href&lt;/code&gt; attribute that we use all the time. When the user clicks on the link the file attributed to the &lt;code&gt;href&lt;/code&gt; tag will be downloaded. You can also set a custom filename for the download by assigning a value to the download such as &lt;code&gt;download="my-burger-menu"&lt;/code&gt; or just &lt;code&gt;download&lt;/code&gt; for the original filename provided by the &lt;code&gt;href&lt;/code&gt; attribute.&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;a href="my-burger-menu.pdf" download="brand-menu"&amp;gt;
  Download our full menu here!
&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;hreflang&lt;/em&gt; &amp;amp; &lt;em&gt;rel&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;hreflang&lt;/code&gt; attribute is used to instruct the browser as to which language the page is served with allowing its users to be provided with the correct version. It can then provide the site to users during browser searches if they are searching in that specific language. It could be included in either the sitemap, http header or the page markup and you can also target more than one country per page.&lt;/p&gt;

&lt;p&gt;To use the &lt;code&gt;hreflang&lt;/code&gt; attribute we can pass in the required two letter language code and the optional two letter country code for example for German it would be &lt;code&gt;hreflang="de"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;rel&lt;/code&gt; attribute belongs to the &lt;code&gt;link&lt;/code&gt; tag that we often use in the &lt;code&gt;head&lt;/code&gt; of a HTML document to link things such as stylesheets, icon packages and so on. Its most common job is to inform the search engines about the relationships that exist between your sites pages. When this attribute is set to &lt;code&gt;rel="alternate"&lt;/code&gt; in combination with &lt;code&gt;hreflang="de"&lt;/code&gt; we are successfully indicating the intended audience of the page.&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;link rel="alternate" hreflang="de" href="https://something.de"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. &lt;code&gt;&amp;lt;ol&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;start&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;If for some reason you would like to start you ordered list from a specific number then we can set the &lt;code&gt;start&lt;/code&gt; attribute to an integer.&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;ol start="5"&amp;gt;
  &amp;lt;li&amp;gt;Five&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Six&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;Seven&amp;lt;/li&amp;gt;
&amp;lt;/ol&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F8yzvl6cftpfriywbtpfv.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%2F8yzvl6cftpfriywbtpfv.jpg" alt="Example of start attribute" width="800" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;reversed&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;reversed&lt;/code&gt; attribute will reverse the order of list's item instead sorting the list from the highest to the lowest.&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;ol start="5" reversed&amp;gt;
    &amp;lt;li&amp;gt;something&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;something else&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;something more&amp;lt;/li&amp;gt;
&amp;lt;/ol&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fniscibyp2xuoxgs5dd9u.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%2Fniscibyp2xuoxgs5dd9u.jpg" alt="Example of the reversed attribute" width="800" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;loading&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Images are often the primary reason as to why your web page's initial load could be slow. Perhaps they are not optimized or maybe your page is trying to load all of the images on the page on the initial load. One way we can speed up this initial load speed is by only loading the images which the user will see after the page loads.&lt;/p&gt;

&lt;p&gt;There is a native solution in HTML which can help use with this. We can add the &lt;code&gt;loading="lazy"&lt;/code&gt; attribute on an &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; element which instructs the browser to defer loading the image until a certain calculated distance from the viewport is reached. The default option for this attribute is &lt;code&gt;loading="eager"&lt;/code&gt; which will load the image immediately on page load.&lt;/p&gt;

&lt;p&gt;If the user has JavaScript disabled in the browser this lazy loading method will no longer function as a deferred loading method which can be seen here &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-loading" rel="noopener noreferrer"&gt;MDN loading attribute&lt;/a&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;img alt="a nice descriptive alt" loading="lazy" src="myimage.webp"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;em&gt;decoding&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Another attribute for our images is the &lt;code&gt;decoding&lt;/code&gt; attribute which allows us to specify how we would like our images decoded with page load. Specifically we can tell the browser whether we want it to decode the images synchronously or asynchronously. It takes three possible values:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;auto&lt;/strong&gt; &lt;br&gt;
This is the default value where the browser will decide what it thinks is best for the decoding.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;sync&lt;/strong&gt; &lt;br&gt;
Decode the image synchronously along with the other page content.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;async&lt;/strong&gt; &lt;br&gt;
Decode the image asynchronously in parallel with other page content which may help speed up the rendering of the page's other content.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;img decoding="async" alt="a nice descriptive alt" src="myimage.webp"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;enctype&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;enctype&lt;/code&gt; atrribute is used on the &lt;code&gt;element&lt;/code&gt; to specify how the data from your form submission should be encoded. There are three states that we can set for this attribute:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;application/x-www-form-urlencoded&lt;/strong&gt; &lt;br&gt;
This is the default setting for the attribute and is suitable for most simple HTML forms. It encodes key-value pairs as tuples where a "&amp;amp;" separates each tuple and a "=" in between each key/ value.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;multipart/form-data&lt;/strong&gt; &lt;br&gt;
This value should be specified if your form requires the user to upload a file through the submission process&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;text/plain&lt;/strong&gt; &lt;br&gt;
Finally this value sets the encoding to none at all and will just send the data as plain text which is not recommended.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form enctype="application/x-www-form-urlencoded"&amp;gt;
  &amp;lt;label for="country"&amp;gt;
  &amp;lt;input id="country" name="country" type="text"&amp;gt;

  &amp;lt;input name="submit" type="submit"&amp;gt;
&amp;lt;/form
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;em&gt;novalidate&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;This is an interesting attribute that allows us to specify whether we would like the data from a form submission to be validated natively on submission. By default it is set as &lt;code&gt;true&lt;/code&gt; even if we don't include it and therefore passing &lt;code&gt;novalidate&lt;/code&gt; on the form will disable the native validation.&lt;/p&gt;

&lt;p&gt;A good use case for setting &lt;code&gt;novalidate&lt;/code&gt; on the &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element is when you want to allow users to save their form progress so they can finish the submission at a later date. It will allow them to save their current form values without running into validation errors preventing them from saving.&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;form novalidate&amp;gt;
  &amp;lt;label for="country" &amp;gt;
  &amp;lt;input id="country" name="country" type="text" /&amp;gt;

  &amp;lt;input name="submit" type="submit" /&amp;gt;
&amp;lt;/form
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7. &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;autocomplete&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;We all despise filling out forms. Despite this there are ways in which we can make it easier for the users of our site to accomplish this quicker. One of them is the &lt;code&gt;autocomplete&lt;/code&gt; attribute which tells the browser how it should populate a given form field if auto-completion is set based off the users history. &lt;/p&gt;

&lt;p&gt;This attribute can be used with &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; elements with value differences. When using forms the &lt;code&gt;name&lt;/code&gt; on the &lt;code&gt;input&lt;/code&gt; element is used to dictate the kind of information that will be used for the auto-completion so make sure you choose an appropriate name for the input (e.g. name, email, city, state, postcode etc...). If used on the &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element it can have the value of &lt;code&gt;on&lt;/code&gt; or &lt;code&gt;off&lt;/code&gt;;&lt;/p&gt;

&lt;p&gt;A full list of &lt;code&gt;autocomplete&lt;/code&gt; options for the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; can be found here &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete" rel="noopener noreferrer"&gt;The HTML autocomplete attribute&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are few use cases for turning off this attribute on your forms. One of them might be that you implement your own custom autocomplete or perhaps you have a field which takes some custom data where you don't need to remember previous results. Even if you set it to off there may be cases the where the browser ignores it if it suspects it is a login form (see here &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion#the_autocomplete_attribute_and_login_fields" rel="noopener noreferrer"&gt;MDN How to turn off form autocompletion&lt;/a&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;form&amp;gt;
  &amp;lt;label for="country" &amp;gt;
  &amp;lt;input id="country" name="country" type="text" autocomplete="off" /&amp;gt;

  &amp;lt;label for="postcode" &amp;gt;
  &amp;lt;input id="postcode" name="postcode" type="text" autocomplete="postal-code" /&amp;gt;

  &amp;lt;input type="submit" /&amp;gt;
&amp;lt;/form
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&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;form autocomplete="on" &amp;gt;
  &amp;lt;label for="country" &amp;gt;
  &amp;lt;input id="country" name="country" type="text"&amp;gt;

  &amp;lt;label for="postcode" &amp;gt;
  &amp;lt;input id="postcode" name="postcode" type="text"&amp;gt;

  &amp;lt;input name="submit" type="submit"&amp;gt;
&amp;lt;/form
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;em&gt;max&lt;/em&gt;/&lt;em&gt;min&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;max&lt;/code&gt; and &lt;code&gt;min&lt;/code&gt; attributes can be specified on an &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; element to limit the valid possible value of the element. The value should be less than or equal to the min and greater than or equal to the max. It can be applied to seven different input types which include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;number&lt;/li&gt;
&lt;li&gt;range&lt;/li&gt;
&lt;li&gt;time&lt;/li&gt;
&lt;li&gt;date&lt;/li&gt;
&lt;li&gt;month&lt;/li&gt;
&lt;li&gt;week&lt;/li&gt;
&lt;li&gt;datetime-local
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form&amp;gt;
  &amp;lt;label for="number"&amp;gt;Number&amp;lt;/label&amp;gt;
  &amp;lt;input id="number" max="30" min="-30" name="number" type="number"&amp;gt;

  &amp;lt;input name="submit" type="submit"&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;em&gt;maxlength&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Another way to limit the value of an input field is through the &lt;code&gt;maxlength&lt;/code&gt; attribute which we can assign to &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt;. It will limit the number of characters that can be entered into the field and it must be an integer that is greater or equal to 0.&lt;/p&gt;

&lt;p&gt;We can use this to limit the characters to a username for example although this method should not be relied upon as form validation. It is more a helpful tool to be accompanied by server-side validation of the input.&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;form&amp;gt;
  &amp;lt;label for="username"&amp;gt;Username&amp;lt;/label&amp;gt;
  &amp;lt;input id="username" maxlength="30" name="username" type="text"&amp;gt;

  &amp;lt;input name="submit" type="submit"&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;em&gt;pattern&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;pattern&lt;/code&gt; attribute when applied to an &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; element provides a regular expression(string of characters to define a pattern) that it can use check against the value of its input. It can be applied to the following input types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;text&lt;/li&gt;
&lt;li&gt;tel&lt;/li&gt;
&lt;li&gt;email&lt;/li&gt;
&lt;li&gt;url&lt;/li&gt;
&lt;li&gt;password&lt;/li&gt;
&lt;li&gt;search&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This functionality could be useful if you need some simple validation without needing to resort to JavaScript. The problem with this type of validation though is the ease at which regular expressions can introduce bugs due to its complexity if not understood or tested properly.&lt;/p&gt;

&lt;p&gt;Once again relying on front-end validation for form submissions is not recommended and we should always include server-side validation. The example below validates that the input only contains letters or numbers.&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;form&amp;gt;
  &amp;lt;label for="username"&amp;gt;Username&amp;lt;/label&amp;gt;
  &amp;lt;input id="username" name="username" pattern="[A-Za-z0-9]+" type="text"&amp;gt;

  &amp;lt;input name="submit" type="submit"&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;em&gt;readonly&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Setting the &lt;code&gt;readonly&lt;/code&gt; attribute on specific &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; elements &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/readonly" rel="noopener noreferrer"&gt;check out which elements here&lt;/a&gt;, or the &lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt; element disables the ability for the user to edit the input value.&lt;/p&gt;

&lt;p&gt;You might think that it sounds the same as the &lt;code&gt;disabled&lt;/code&gt; attribute which is commonly used to achieve a similar effect but there a few differences. Unlike to the &lt;code&gt;disabled&lt;/code&gt; attribute, when &lt;code&gt;readonly&lt;/code&gt; is applied to an input it is still possible to copy the value of the input and users can also focus into the element.&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;form&amp;gt;
  &amp;lt;textarea readonly&amp;gt;
    Users will not be able to edit this field but can copy or tab into it
  &amp;lt;/textarea&amp;gt;

  &amp;lt;input name="submit" type="submit"&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;em&gt;step&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;step&lt;/code&gt; attribute specifies a numeric value that the input uses as the stepping interval whenever the user clicks on the increment or decrement buttons. It can be applied to &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; elements of type &lt;code&gt;range&lt;/code&gt;, &lt;code&gt;number&lt;/code&gt; and the time/date types.&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;form&amp;gt;
  &amp;lt;label for="number"&amp;gt;Number&amp;lt;/label&amp;gt;
  &amp;lt;input id="number" step="5" name="number" type="number"&amp;gt;

  &amp;lt;input name="submit" type="submit"&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Thanks for getting this far! I hope you were able to learn something new about HTML to take with you in your web-development journey.&lt;/p&gt;

&lt;p&gt;You can follow me &lt;a href="https://twitter.com/Kieran6dev" rel="noopener noreferrer"&gt;@Kieran6dev&lt;/a&gt; for more helpful tips as well as my own progress through web development.&lt;/p&gt;

&lt;p&gt;If you know of any other lesser-known HTML attributes which I did not include then let me know in the comments below. Thanks!&lt;/p&gt;

</description>
      <category>html</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Ditch the dreaded &lt;div /&gt;. Semantic HTML elements we should use instead</title>
      <dc:creator>Kieran Roberts</dc:creator>
      <pubDate>Wed, 17 Feb 2021 15:20:00 +0000</pubDate>
      <link>https://dev.to/kieran6roberts/ditch-the-dreaded-div-semantic-html-elements-we-should-use-instead-1k60</link>
      <guid>https://dev.to/kieran6roberts/ditch-the-dreaded-div-semantic-html-elements-we-should-use-instead-1k60</guid>
      <description>&lt;p&gt;Firstly we'll clear up the meaning of semantic HTML. The semantics of an entity describes what its purpose is. By using semantic HTML elements we are able to provide meaning to the structure of our code. If you think about the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; tag for a second ask yourself this: If you had never heard of this element before what would you think its purpose was? &lt;/p&gt;

&lt;p&gt;Difficult right? 🤔&lt;/p&gt;

&lt;p&gt;Imagine trying to build a new desk from one of those sets you can buy at a furniture store. It includes everything you need to construct it as well as an informational booklet with all the information related to the desk. &lt;/p&gt;

&lt;p&gt;Now imagine each page of the instruction booklet is missing a header. It makes finding the instruction page much more difficult as well as the list of contents in the box, the warranty policy, and so on. You can still find them but you have to look very closely. &lt;/p&gt;

&lt;p&gt;The name &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; does not offer any information as to what role it might perform. Now think of the &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; tag or any heading tag for that matter. The heading element has a role that describes the role it performs (as a heading). There should only ever be &lt;em&gt;one&lt;/em&gt; &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; element on the page.&lt;/p&gt;

&lt;p&gt;There are three primary advantages to using semantic HTML elements to you and the users of your site:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search Engine Optimization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This refers to the way in which search engines such as Google interpret the content of your site and it can affect where your site will appear in search results. This means that neglecting semantic HTML could have a negative effect on how many users will find and interact with the site.&lt;/p&gt;

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

&lt;p&gt;Using elements that better describe the role they perform makes it easier for screen readers to inform users with disabilities about the content of your site.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code readability and maintainability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using semantic HTML elements can help you with the maintaining and debugging of your code making it clear which part of the code you are looking at. This is especially important if you are working with other developers in the same codebase.&lt;/p&gt;

&lt;p&gt;There are many semantic elements we can use that in principle do the same thing but offer the benefits outlined above. Now that we understand what a semantic element is and why they are important, let me show you some semantic elements that we can use to replace the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; that you might still be using a little too often.   &lt;br&gt;  &lt;/p&gt;

&lt;p&gt;Throughout the article I will include quote definitions for each element using &lt;a href="https://developer.mozilla.org/en-US/" rel="noopener noreferrer"&gt;MDN Web Docs&lt;/a&gt; before explaining them in simpler terms.&lt;/p&gt;

&lt;p&gt;Let's begin 👏.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;Definition by MDN:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The HTML &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt; element represents a self-contained composition in a document, page, application, or site, which is intended to be independently distributable or reusable (e.g., in syndication). Examples include: a forum post, a magazine or newspaper article, or a blog entry, a product card, a user-submitted comment, an interactive widget or gadget, or any other independent item of content.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This element is often used to wrap pieces of content where your codebase might contain multiples of them. An example of this is a blog post preview card or the post itself but really you could use it whenever you have a piece of content that includes a heading to describe it and the content representative of the heading. You can also nest &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt; elements inside each other.&lt;br&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;article class="product"&amp;gt;
  &amp;lt;h2&amp;gt;
    Coffee
  &amp;lt;/h2&amp;gt;
  &amp;lt;article class="product-info&amp;gt;
    &amp;lt;h3&amp;gt;
      Product information
    &amp;lt;/h3&amp;gt;
    &amp;lt;p&amp;gt;
      Very delicious coffee!
    &amp;lt;/p&amp;gt;
  &amp;lt;/article&amp;gt;
&amp;lt;/article&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;Definition by MDN:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The HTML &lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt; element represents introductory content, typically a group of introductory or navigational aids. It may contain some heading elements but also a logo, a search form, an author name, and other elements.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;br&gt;This element is typically useful for grouping elements that represent the header of an article or post together where at least one of the elements includes a heading element such as &lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt;. I have also used it in the hero of a landing page of a site that includes the main heading element &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; and possibly some images, text, links or other introductory content that support the heading.&lt;/p&gt;

&lt;p&gt;Although called a header element it is not necessary to use this element at the top of the page and can used in other sectional elements such as &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt;.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;Examples 👇&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;header class="header"&amp;gt;
  &amp;lt;h1&amp;gt;
    Hero header
  &amp;lt;/h1&amp;gt;
  &amp;lt;img src="heroimage.webp" alt="a nice descriptive alt text"&amp;gt;
&amp;lt;/header&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&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;article&amp;gt;
  &amp;lt;header&amp;gt;
    &amp;lt;h2&amp;gt;
      Article header
    &amp;lt;/h2&amp;gt;
    &amp;lt;a href="/blog-article"&amp;gt;
      Link
    &amp;lt;/a&amp;gt;
  &amp;lt;/header&amp;gt;
  ...
&amp;lt;/article&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;Definition by MDN:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The HTML &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt; element represents a generic standalone section of a document, which doesn't have a more specific semantic element to represent it. Sections should always have a heading, with very few exceptions.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Similar to the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; there is often a better choice than the &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt; element. Even so it is an improvement on the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; when you need to section-off a piece of content that would not be suitable for a &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt; or similar elements (as long as it is not used for styling purposes). &lt;/p&gt;

&lt;p&gt;If you require an element wrapper for styling purposes it is better to stick to the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; element. &lt;br&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;section id="blog-articles"&amp;gt;
  &amp;lt;h2&amp;gt;
    Section header
  &amp;lt;/h2&amp;gt;
  ...any other content related to the section
&amp;lt;/section&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;Definition by MDN:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The HTML &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt; element represents a section of a page whose purpose is to provide navigation links, either within the current document or to other documents. Common examples of navigation sections are menus, tables of contents, and indexes.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;br&gt;Use it to wrap the primary sets of links that are used to navigate around your page indicating clearly to your screen reader users exactly where the main navigational links of your site are based. &lt;br&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;nav id="main-nav"&amp;gt;
  &amp;lt;ul&amp;gt;
    &amp;lt;li&amp;gt;
      &amp;lt;a href="/"&amp;gt;
        Home
      &amp;lt;/a&amp;gt;
    &amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;
      &amp;lt;a href="/blog"&amp;gt;
        Blog
      &amp;lt;/a&amp;gt;
    &amp;lt;/li&amp;gt;
  &amp;lt;/ul&amp;gt;
&amp;lt;/nav&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;Definition by MDN:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The HTML &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt; element represents the dominant content of the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; of a document. The main content area consists of content that is directly related to or expands upon the central topic of a document, or the central functionality of an application.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You will only ever have one &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt; element per page of a site that indicates to the user where the primary content of the page exists. This is the content that is left when you ignore secondary content that is repeated across other pages of the site such as the content enclosed in the &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;aside&amp;gt;&lt;/code&gt; and similar additional elements. These are sometimes called layout components/elements.&lt;/p&gt;

&lt;p&gt;It also has an important role for users requiring a screen reader to navigate your site because they are able to instruct their browser to skip straight to the &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt; element and the content it includes. &lt;br&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;nav id="main-nav"&amp;gt;
  &amp;lt;ul&amp;gt;
    ...navigational links
  &amp;lt;/ul&amp;gt;
&amp;lt;/nav&amp;gt;
&amp;lt;header id="landing"&amp;gt;
  &amp;lt;h1&amp;gt;
    Some descriptive page header
  &amp;lt;h1&amp;gt;
  &amp;lt;p&amp;gt;
    ...explanation
  &amp;lt;/p&amp;gt;
  &amp;lt;a href="/blog"&amp;gt;
    call to action for user
  &amp;lt;/a&amp;gt;
&amp;lt;/header&amp;gt;
&amp;lt;main&amp;gt;
  &amp;lt;h2&amp;gt;
    Welcome to the main content of the page
  &amp;lt;/h2&amp;gt;
  &amp;lt;article&amp;gt;
    &amp;lt;h3&amp;gt;
      Article title
    &amp;lt;/h3&amp;gt;
    ...
  &amp;lt;/article&amp;gt;
&amp;lt;/main&amp;gt;
&amp;lt;footer&amp;gt;
  ...
&amp;lt;/footer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;&amp;lt;aside&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;Definition by MDN:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The HTML &lt;code&gt;&amp;lt;aside&amp;gt;&lt;/code&gt; element represents a portion of a document whose content is only indirectly related to the document's main content. Asides are frequently presented as sidebars or call-out boxes.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The &lt;code&gt;&amp;lt;aside&amp;gt;&lt;/code&gt; element is to provide some content that is secondary to whatever content it relates to. This means that wherever the element is in the document, it should only contain content that the user does not explicitly require to understand the primary content.&lt;/p&gt;

&lt;p&gt;An example is in an article to provide a definition for something or a further explanation the relates to the content. Maybe some links to other articles that expand on a definition further. &lt;br&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;article&amp;gt;
  &amp;lt;h2&amp;gt;
    Article header
  &amp;lt;/h2&amp;gt;
  &amp;lt;p&amp;gt;
    I really enjoy writing JavaScript.
  &amp;lt;/p&amp;gt;
  &amp;lt;aside&amp;gt;
    JavaScript is a high-level dynamically typed programming language. You can find more information here ...
  &amp;lt;/aside&amp;gt;
  &amp;lt;p&amp;gt;
    I also really like semantic HTML.
  &amp;lt;/p&amp;gt;
&amp;lt;/article&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;&amp;lt;details&amp;gt; &amp;amp; &amp;lt;summary&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;Definition by MDN:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The HTML Details Element (&lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt;) creates a disclosure widget in which information is visible only when the widget is toggled into an "open" state. A summary or label can be provided using the &lt;code&gt;&amp;lt;summary&amp;gt;&lt;/code&gt; element.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These two elements are really useful when you require a widget that can be toggled to an 'open' or 'close' state that reveals or hides some content. A typical use case for this is an faq (frequently asked questions) section of a website that allows the user to click on a question to reveal the answer.&lt;/p&gt;

&lt;p&gt;It uses no JavaScript meaning it will continue to function properly for your uses even if they have set their browser to ignore it, making your site more accessible. The &lt;code&gt;&amp;lt;summary&amp;gt;&lt;/code&gt; tag contains the text that is always visible to the user while the &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; tag holds the information to display when the widget is in the 'open' state. &lt;br&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;details&amp;gt;
  &amp;lt;summary&amp;gt;
    Do you offer tours of the brewery?
  &amp;lt;/summary&amp;gt;
     Unfortunately at this time we do not offer tours of the brewery. We are currently building our taproom so stay tuned.
&amp;lt;/details&amp;gt;
&amp;lt;details&amp;gt;
  &amp;lt;summary&amp;gt;
    Are your beers gluten-free?
  &amp;lt;/summary&amp;gt;
     All of our beers are gluten-free and vegan-friendly!
&amp;lt;/details&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;&amp;lt;figure&amp;gt; &amp;amp; &amp;lt;figcaption&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;Definition by MDN:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The HTML &lt;code&gt;&amp;lt;figure&amp;gt;&lt;/code&gt; (Figure With Optional Caption) element represents self-contained content, potentially with an optional caption, which is specified using the (&lt;code&gt;&amp;lt;figcaption&amp;gt;&lt;/code&gt;) element. The figure, its caption, and its contents are referenced as a single unit.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Generally the &lt;code&gt;&amp;lt;figure&amp;gt;&lt;/code&gt; element encloses an image (although it is not required) and is usually accompanied by a &lt;code&gt;&amp;lt;figcaption&amp;gt;&lt;/code&gt; element that provides the description for the element. You could also include other elements such as the &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tag that is relevant to the figure.&lt;/p&gt;

&lt;p&gt;In my experience it is useful to include the &lt;code&gt;&amp;lt;figure&amp;gt;&lt;/code&gt; element when you include a piece of content such as an image, diagram, or piece of code that relates to the content you are writing within some article or post. &lt;br&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;article&amp;gt;
  &amp;lt;h2&amp;gt;
    Article header
  &amp;lt;/h2&amp;gt;
  &amp;lt;p&amp;gt;
    ...some introductory text
  &amp;lt;/p&amp;gt;
  &amp;lt;figure&amp;gt;
    &amp;lt;img src="post.webp" alt="a nice descriptive alt text" /&amp;gt;
    &amp;lt;figcaption&amp;gt;
      Photo taken by Kieran Roberts
    &amp;lt;/figcaption&amp;gt;
  &amp;lt;/figure&amp;gt;
  &amp;lt;p&amp;gt;
    ..rest of the article
  &amp;lt;/p&amp;gt;
&amp;lt;/article&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;&amp;lt;blockquote&amp;gt;&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;br&gt;Definition by MDN:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The HTML &lt;code&gt;&amp;lt;blockquote&amp;gt;&lt;/code&gt; Element (or HTML Block Quotation Element) indicates that the enclosed text is an extended quotation. Usually, this is rendered visually by indentation (see Notes for how to change it). A URL for the source of the quotation may be given using the cite attribute, while a text representation of the source can be given using the &lt;code&gt;&amp;lt;cite&amp;gt;&lt;/code&gt; element.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Use the &lt;code&gt;&amp;lt;blockquote&amp;gt;&lt;/code&gt; when you want to include text in your site that comes from another source. The &lt;code&gt;cite&lt;/code&gt; attribute on the &lt;code&gt;&amp;lt;blockquote&amp;gt;&lt;/code&gt; element should be used to provide original source of the content. &lt;br&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;blockquote cite="link to the souce"&amp;gt;
  &amp;lt;p&amp;gt;
    This is an inspirational quote from another source
  &amp;lt;/p&amp;gt;
  &amp;lt;footer&amp;gt;
    Source author, &amp;lt;cite&amp;gt;content of the citation&amp;lt;/cite&amp;gt;
  &amp;lt;footer&amp;gt;
&amp;lt;/blockquote&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;&amp;lt;abbr&amp;gt;...&amp;lt;/abbr&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;Definition by MDN:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The HTML Abbreviation element (&lt;code&gt;&amp;lt;abbr&amp;gt;&lt;/code&gt;) represents an abbreviation or acronym; the optional title attribute can provide an expansion or description for the abbreviation. If present, the title must contain this full description and nothing else.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This element is nice for providing a simple but effective tooltip effect to acronyms you might have on your site. I have included this attribute myself in my portfolio for things like JavaScript(js). The &lt;code&gt;title&lt;/code&gt; attribute provides the full description of the acronym when the users hover over it. &lt;br&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;p&amp;gt;
  I really enjoy working with&amp;lt;abbr title="JavaScript"&amp;gt; js &amp;lt;/abbr&amp;gt;and I am now learning &amp;lt;abbr title="TypeScript"&amp;gt; ts &amp;lt;/abbr&amp;gt;.
&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;&amp;lt;footer&amp;gt;...&amp;lt;/footer&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;Definition by MDN:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The HTML &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt; element represents a footer for its nearest sectioning content or sectioning root element. A footer typically contains information about the author of the section, copyright data, or links to related documents.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Typically people include one &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt; at the bottom of the document but we can also include a &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt; for each &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt; element as long as it does not have another &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt; element as a descendant. Inside the &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt; you can include any kind of text, images, or links related to the placement of the element.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;Examples 👇&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;footer&amp;gt;
  &amp;lt;p&amp;gt;
    This is the end of the site
  &amp;lt;/p&amp;gt;
&amp;lt;/footer&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&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;article&amp;gt;
  &amp;lt;h2&amp;gt;
    Article header
  &amp;lt;/h2&amp;gt;
  &amp;lt;p&amp;gt;
    Article content
  &amp;lt;/p&amp;gt;
  &amp;lt;footer&amp;gt;
    &amp;lt;p&amp;gt;
      Article footer
    &amp;lt;/p&amp;gt;
  &amp;lt;footer&amp;gt;
&amp;lt;/article&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;I hope you have learned something about semantic HTML that you can take with you into future projects to make your markup more accessible for everyone that interacts with your site!&lt;/p&gt;

&lt;p&gt;You can follow me &lt;a href="https://twitter.com/Kieran6dev" rel="noopener noreferrer"&gt;@Kieran6dev&lt;/a&gt; where I'm always active and happy to connect with you!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/kieran6roberts" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.buymeacoffee.com%2Fbutton-api%2F%3Ftext%3DBuy%2520me%2520a%2520beer%26emoji%3D%25F0%259F%258D%25BA%26slug%3Dkieran6roberts%26button_colour%3DFFDD00%26font_colour%3D000000%26font_family%3DCookie%26outline_colour%3D000000%26coffee_colour%3Dffffff" width="217.0" height="50"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading 👋&lt;/p&gt;

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