<?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: Aleksandr Hovhannisyan</title>
    <description>The latest articles on DEV Community by Aleksandr Hovhannisyan (@aleksandrhovhannisyan).</description>
    <link>https://dev.to/aleksandrhovhannisyan</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%2F304963%2F9894af56-32fb-4ded-8d66-89904e828dc1.jpg</url>
      <title>DEV Community: Aleksandr Hovhannisyan</title>
      <link>https://dev.to/aleksandrhovhannisyan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aleksandrhovhannisyan"/>
    <language>en</language>
    <item>
      <title>What Are Higher-Order Components in React?</title>
      <dc:creator>Aleksandr Hovhannisyan</dc:creator>
      <pubDate>Thu, 29 Oct 2020 20:34:58 +0000</pubDate>
      <link>https://dev.to/aleksandrhovhannisyan/what-are-higher-order-components-in-react-2452</link>
      <guid>https://dev.to/aleksandrhovhannisyan/what-are-higher-order-components-in-react-2452</guid>
      <description>&lt;p&gt;If you're new to React, or even if you've been using it for a while, you may have heard about these things called &lt;strong&gt;higher-order components (HOCs)&lt;/strong&gt;, and shuddered at the apparent complexity of the term. It certainly &lt;em&gt;sounds&lt;/em&gt; like something fancy that's beyond a beginner's comprehension. But that's not the case at all—the truth is that higher-order components in React are a very intuitive (and powerful!) design pattern.&lt;/p&gt;

&lt;p&gt;In this tutorial, we'll explore what higher-order components are and why you might want to use them. We'll also learn how you can combine them with the React Context API to create reusable components and behaviors. Let's dig in!&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  Prerequisite Terminology
&lt;/li&gt;
&lt;li&gt;  What Are Higher-Order Components?
&lt;/li&gt;
&lt;li&gt;  Example of Higher-Order Components

&lt;ul&gt;
&lt;li&gt;  Creating Reusable Stateful Logic with Higher-Order Components
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;  Higher-Order Components and the Power of Composition
&lt;/li&gt;
&lt;li&gt;  Higher-Order Components vs. Wrapper Components
&lt;/li&gt;
&lt;li&gt;  Using Higher-Order Components with the React Context API
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisite Terminology
&lt;/h2&gt;

&lt;p&gt;As a super-quick refresher, note that a React &lt;strong&gt;component&lt;/strong&gt; is just a function that returns a React element:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This is a component&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;img&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;className&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;img&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// This is basically the same component but using JSX&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"image"&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all you really need to know before moving on.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are Higher-Order Components?
&lt;/h2&gt;

&lt;p&gt;Simply put, a &lt;strong&gt;higher-order component&lt;/strong&gt; is a function that returns a component. At the end of the day, it's &lt;em&gt;just a function&lt;/em&gt;, like any other that you're used to working with by now in JavaScript and other languages.&lt;/p&gt;

&lt;p&gt;To go a bit more into detail, a higher-order component is a special kind of function that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Accepts a React component as one of its arguments (among others, potentially).&lt;/li&gt;
&lt;li&gt;Injects certain props into the component to "decorate" it or extend its behavior.&lt;/li&gt;
&lt;li&gt;Returns this "decorated" component so that others can render it later on.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In other words, a higher-order component is essentially a &lt;strong&gt;component factory&lt;/strong&gt;. It's a design pattern that allows you to create new versions of existing components by injecting additional props into them. Notably, higher-order components are used to consolidate reusable, &lt;strong&gt;stateful logic&lt;/strong&gt; in a single place.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9gOOwaBH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/higher-order-components/diagram.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9gOOwaBH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/higher-order-components/diagram.png" alt="A higher-order component returns a component, which returns a React element."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Don't get confused—an HOC is not itself a component. Remember: Components are functions that return a React element; higher-order components are functions that return &lt;em&gt;components&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;At a high level, without going into any specifics, here's what a higher-order component might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// A higher-order component...&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;hoc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;other&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ... returns a component...&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...which is just a function that returns an element!&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="na"&gt;someProp&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"someValue"&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Awesome!&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;&amp;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;Of course, this doesn't tell you much about why you might want to use a higher-order component. To truly see the benefits, we'll now look at a practical example of higher-order components.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example of Higher-Order Components
&lt;/h2&gt;

&lt;p&gt;Suppose we're using React to create a blog (e.g., with a static site generator like Gatsby). You can follow along with the code in this tutorial or view the &lt;a href="https://codesandbox.io/embed/higher-order-components-demoexample-fvlhy"&gt;companion CodeSandbox demo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To kick things off, we'll create a basic presentational component named &lt;code&gt;PostList&lt;/code&gt; that represents a generic list of posts. Nothing fancy here:&lt;/p&gt;

&lt;p&gt;(File: &lt;code&gt;components/PostList/index.js&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&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;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PostList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;posts&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ol&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;post&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ol&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;PostList&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your blog is going to have three different kinds of posts: recent, popular, and archived. Since we don't actually have any real data to work with here, we'll create some fake data and use that for this tutorial:&lt;/p&gt;

&lt;p&gt;(File: &lt;code&gt;containers/Posts/api.js&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;recentPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&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;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Recent Post 1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/recent-post-1/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Recent post 1 description&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;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Recent Post 2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/recent-post-2/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Recent post 2 description&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;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Recent Post 3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/recent-post-3/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Recent post 3 description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;popularPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&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;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Popular Post 1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/popular-post-1/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Popular post 1 description&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;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Popular Post 2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/popular-post-2/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Popular post 2 description&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;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Popular Post 3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/popular-post-3/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Popular post 3 description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;archivedPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&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;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Archived Post 1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/archived-post-1/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Archived post 1 description&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;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Archived Post 2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/archived-post-2/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Archived post 2 description&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;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Archived Post 3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/archived-post-3/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Archived post 3 description&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getRecentPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;recentPosts&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;getPopularPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;popularPosts&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;getArchivedPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;archivedPosts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the real world, you'd hit an actual API endpoint rather than returning local, static data. For the purposes of this tutorial, though, we've hardcoded our data for recent, popular, and archived posts in arrays. And at the bottom, we've exported three functions that return these arrays.&lt;/p&gt;

&lt;p&gt;Our blog will consist of the following container component:&lt;/p&gt;

&lt;p&gt;(File: &lt;code&gt;containers/Posts/index.js&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&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;react&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;ArchivedPosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;PopularPosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;RecentPosts&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;../../components/PostList&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;article&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Recent Posts&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RecentPosts&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Popular Posts&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PopularPosts&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Archived Posts&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ArchivedPosts&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;article&lt;/span&gt;&lt;span class="p"&gt;&amp;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="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Posts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, the three components you see here don't exist just yet, so let's go ahead and create them now. We'll use the fetch functions we defined just a few seconds ago to do that. Keep in mind that in the real world, you'd probably use some Promise-based fetch function to get your data, and thus you'd need to either &lt;code&gt;await&lt;/code&gt; your data or chain &lt;code&gt;then&lt;/code&gt;s:&lt;/p&gt;

&lt;p&gt;(File: &lt;code&gt;components/PostList/index.js&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&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;react&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;getArchivedPosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getPopularPosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getRecentPosts&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;../../containers/Posts/api&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Same as before&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PostList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;posts&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ol&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;post&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ol&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;RecentPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPosts&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;

  &lt;span class="nx"&gt;useEffect&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;setPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getRecentPosts&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PostList&lt;/span&gt; &lt;span class="na"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PopularPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPosts&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;

  &lt;span class="nx"&gt;useEffect&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;setPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getPopularPosts&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PostList&lt;/span&gt; &lt;span class="na"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ArchivedPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPosts&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;

  &lt;span class="nx"&gt;useEffect&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;setPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getArchivedPosts&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PostList&lt;/span&gt; &lt;span class="na"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;PostList&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basically, each component fetches its respective type of posts after it mounts and renders a &lt;code&gt;PostList&lt;/code&gt;, passing along the result of our fake API call to the &lt;code&gt;posts&lt;/code&gt; prop.&lt;/p&gt;

&lt;p&gt;This works just fine, but notice how we ended up repeating a lot of common logic. Each component:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Initializes an empty array as its state.&lt;/li&gt;
&lt;li&gt;Makes an API call on mount and updates its state.&lt;/li&gt;
&lt;li&gt;Returns a &lt;code&gt;PostList&lt;/code&gt;, injecting the &lt;code&gt;posts&lt;/code&gt; prop and spreading the rest.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The only thing that differs is the fetch function that gets called on mount: it's either &lt;code&gt;getRecentPosts&lt;/code&gt;, &lt;code&gt;getPopularPosts&lt;/code&gt;, or &lt;code&gt;getArchivedPosts&lt;/code&gt;. What if we could instead create a helper function—a factory, really—that consolidates this shared logic in a function that spits out specialized &lt;code&gt;PostList&lt;/code&gt; components?&lt;/p&gt;

&lt;p&gt;That's precisely the idea behind higher-order components in React.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating Reusable Stateful Logic with Higher-Order Components
&lt;/h3&gt;

&lt;p&gt;I'll show the higher-order component for this scenario now, in its entirety, and then explain how it works:&lt;/p&gt;

&lt;p&gt;(File: &lt;code&gt;components/PostList/withPosts.js&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&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;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;withPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getPosts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPosts&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;

    &lt;span class="nx"&gt;useEffect&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;setPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getPosts&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="na"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;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="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;withPosts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, it's worth reiterating that a higher-order component is just a function like any other in JavaScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;withPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getPosts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key difference between an ordinary function and a higher-order component is that an HOC returns a React component, rather than some other result. If you're curious, the term "higher-order component" is derived from "higher-order function." A &lt;strong&gt;higher-order function&lt;/strong&gt; is one that returns another function. This concept exists not only in JavaScript but also many other languages, especially functional ones.&lt;/p&gt;

&lt;p&gt;Our &lt;code&gt;withPosts&lt;/code&gt; higher-order component accepts two arguments in this particular case: a React component and a function that should be called to fetch posts (recent, popular, or archived) from our API. Inside the higher-order component, all we're doing is returning a &lt;strong&gt;functional React component&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;withPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getPosts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In fact, if we had wanted to, we could've used the legacy React syntax and returned a class instead, to make it perfectly clear that a higher-order component returns a React component:&lt;/p&gt;

&lt;p&gt;(File: &lt;code&gt;components/PostList/withPosts.js&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&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;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;withPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getPosts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Same as before, but more verbose without hooks&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;componentDidMount&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Again, you'd most likely await this&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getPosts&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="na"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;withPosts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In both versions of the code, the inner component accepts props (just like all React components do), initializes an empty array of posts as its state, and calls the fetch function on mount. Once the API call finishes, the component updates its state. Finally, it returns the original &lt;code&gt;Component&lt;/code&gt; that we passed in, but injecting the &lt;code&gt;posts&lt;/code&gt; array as an additional prop and spreading the remaining props.&lt;/p&gt;

&lt;p&gt;Now, using this higher-order component couldn't be easier:&lt;/p&gt;

&lt;p&gt;(File: &lt;code&gt;components/PostList/index.js&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;RecentPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;withPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PostList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getRecentPosts&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;PopularPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;withPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PostList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getPopularPosts&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;ArchivedPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;withPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PostList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getArchivedPosts&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that we're calling the higher-order component three times here, once for each type of post. Each time, we're passing in two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The component to modify (in this case, our presentational component &lt;code&gt;PostList&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The function that fetches posts (&lt;code&gt;getRecentPosts&lt;/code&gt;, &lt;code&gt;getPopularPosts&lt;/code&gt;, or &lt;code&gt;getArchivedPosts&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since the result of a call to a higher-order component is just another component, these exported variables can be rendered. Thus, the code from earlier should make sense:&lt;/p&gt;

&lt;p&gt;(File: &lt;code&gt;containers/Posts/Posts.js&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&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;react&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;ArchivedPosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;PopularPosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;RecentPosts&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;../../components/PostList&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;article&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Recent Posts&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RecentPosts&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Popular Posts&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PopularPosts&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Archived Posts&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ArchivedPosts&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;article&lt;/span&gt;&lt;span class="p"&gt;&amp;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="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Posts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally, if we had wanted to, we could've also passed along more props to these components:&lt;/p&gt;

&lt;p&gt;(File: &lt;code&gt;containers/Posts/Posts.js&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&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;react&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;RecentPosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;ArchivedPosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;PopularPosts&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;components/PostList&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;article&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Recent Posts&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RecentPosts&lt;/span&gt; &lt;span class="na"&gt;prop1&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"foo"&lt;/span&gt; &lt;span class="na"&gt;prop2&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Popular Posts&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PopularPosts&lt;/span&gt; &lt;span class="na"&gt;prop1&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"xyz"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Archived Posts&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ArchivedPosts&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;article&lt;/span&gt;&lt;span class="p"&gt;&amp;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="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Posts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're able to do this because of the following two lines of code in our higher-order component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&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;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;withPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getPosts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// the component accepts props&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="p"&gt;...&lt;/span&gt;

   &lt;span class="c1"&gt;// and spreads them here&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="na"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;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 last thing worth noting with this example: You may be wondering why we didn't just return a &lt;code&gt;PostList&lt;/code&gt; from the higher-order component instead of accepting a generic reference to some &lt;code&gt;Component&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In other words, why not do this:&lt;/p&gt;

&lt;p&gt;(File: &lt;code&gt;components/PostList/withPosts.js&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&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;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;PostList&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;./PostList&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;withPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getPosts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPosts&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;

    &lt;span class="nx"&gt;useEffect&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;getPosts&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setPosts&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PostList&lt;/span&gt; &lt;span class="na"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;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="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;withPosts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That would certainly save us some typing here, as we'd no longer have to specify &lt;code&gt;PostList&lt;/code&gt; as the first argument to each function call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;RecentPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;withPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getRecentPosts&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;PopularPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;withPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getPopularPosts&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;ArchivedPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;withPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getArchivedPosts&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, this isn't a good idea in general, as you may run into a situation later on where you actually want to pass in a more customized version of &lt;code&gt;PostList&lt;/code&gt;—like one that only shows the first five posts, or one that renders posts as cards instead of in a list, and so on. By accepting a generic reference to a component, our higher-order component is not only more flexible but also easier to test, as we've no longer hard-coded a dependency in the implementation. Instead, we allow the consumer to specify the component to render.&lt;/p&gt;

&lt;h2&gt;
  
  
  Higher-Order Components and the Power of Composition
&lt;/h2&gt;

&lt;p&gt;If you're with me so far, you may have noticed an interesting fact: Higher-order components accept a component as one of their arguments, but they also &lt;em&gt;return&lt;/em&gt; a component. Naturally, this means we can pass the result of one higher-order component as an argument to another, like nested Matryoshka dolls:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xJwYa3dG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/higher-order-components/matryoshka-dolls.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xJwYa3dG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/higher-order-components/matryoshka-dolls.png" alt="The classic Russian Matryoshka dolls, in decreasing size, can be nested in one another."&gt;&lt;/a&gt;&lt;br&gt;Image source: &lt;a href="https://en.wikipedia.org/wiki/Matryoshka_doll#/media/File:Russian-Matroshka.jpg"&gt;Wikimedia Commons user Fanghong&lt;/a&gt;
    &lt;/p&gt;

&lt;p&gt;Consider this toy example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Div&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;withX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setX&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// simulate async fetch/call&lt;/span&gt;
      &lt;span class="nx"&gt;setTimeout&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;setX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;x&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="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

    &lt;span class="c1"&gt;// inject x&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;withY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setY&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// simulate async fetch/call&lt;/span&gt;
      &lt;span class="nx"&gt;setTimeout&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;setY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;y&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="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

    &lt;span class="c1"&gt;// inject y&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;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="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;withY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;withX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Div&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The composition happens here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;withY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;withX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Div&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you work your way from the inside out, you should understand why we're able to do this: &lt;code&gt;withX&lt;/code&gt; returns the &lt;code&gt;Div&lt;/code&gt; component with the state variable &lt;code&gt;x&lt;/code&gt; injected into it. So, you can think of the export as being this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;withY&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Div&lt;/span&gt; &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"x"&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And &lt;code&gt;withY&lt;/code&gt; is yet another higher-order component that accepts a generic component and injects the &lt;code&gt;y&lt;/code&gt; prop into it. In the end, we get an exported component that has &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; injected dynamically based on the stateful logic in each HOC. So you can think of the export as really being this component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Div&lt;/span&gt; &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"x"&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"y"&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see this pattern of composing higher-order components frequently in React. For example, your app may have a higher-order component that injects user login information into a component, another that injects theme variables, yet another that injects internationalization settings, and so on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;withIntl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;withTheme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;withUserLogin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MyComponent&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll actually look at a concrete example of one of these in the section on using higher-order components with the Context API. But the key takeaway from this section is that you can compose higher-order components together, allowing you to customize your components by combining HOCs in various ways.&lt;/p&gt;

&lt;h2&gt;
  
  
  Higher-Order Components vs. Wrapper Components
&lt;/h2&gt;

&lt;p&gt;Throughout this tutorial, I described higher-order components as factories that accept a reference to a component and decorate it with certain props. How does this differ from wrapper components, which accept props and return a component? The two certainly sound similar, but consider this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Option 1: Wrapper component&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Wrapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// ... mounts and useEffect logic here somewhere (optional)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="na"&gt;prop1&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Option 2: Higher-order component&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HOC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// ... mounts and useEffect logic here somewhere (optional)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="na"&gt;prop1&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;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;Notice the difference?&lt;/p&gt;

&lt;p&gt;The higher-order component doesn't render anything—it just returns a &lt;strong&gt;component definition&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="na"&gt;prop1&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That component instance can be rendered later.&lt;/p&gt;

&lt;p&gt;In contrast, the wrapper component returns the result of actually rendering the &lt;code&gt;Component&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="na"&gt;prop1&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the &lt;a href="https://stackoverflow.com/questions/36960675/difference-between-using-a-hoc-vs-component-wrapping#comment75670399_36970073"&gt;key distinction between higher-order components and wrapper components&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;HOCs are called with &lt;strong&gt;component instances&lt;/strong&gt;, to which the HOC can inject props before the component is rendered. Container components are called with &lt;strong&gt;the result of rendering a component instance&lt;/strong&gt;, not the component instance itself.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because of this, you can't compose wrapper components like you can higher-order components. The result of a wrapper component is a rendered component, not a reference to a component instance, so it's not nearly as flexible as the HOC pattern.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Higher-Order Components with the React Context API
&lt;/h2&gt;

&lt;p&gt;In practice, higher-order components are especially useful when combined with React's &lt;a href="https://reactjs.org/docs/context.html"&gt;Context API&lt;/a&gt;. The Context API solves the problem of &lt;a href="https://kentcdodds.com/blog/prop-drilling"&gt;prop-drilling hell&lt;/a&gt;, without introducing a state management library like Redux, immer, zustand, and the many others that are currently competing in React.&lt;/p&gt;

&lt;p&gt;By &lt;strong&gt;combining higher-order components with the Context API&lt;/strong&gt;, we can give any deeply nested component in our app access to a particular context's value, without having to write tedious boilerplate or drilling props.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codesandbox.io/embed/ecstatic-wiles-0c2qv"&gt;Here's a CodeSandbox demonstrating this&lt;/a&gt;. We have an app where every component needs a &lt;code&gt;theme&lt;/code&gt; variable, as well as potentially the ability to toggle that theme (e.g., for light and dark modes).&lt;/p&gt;

&lt;p&gt;We &lt;em&gt;could&lt;/em&gt; define the theme in our App as a local state variable and simply drill it down to every component in the app that needs it. But that's not maintainable at all. Another option is to use a state management library like Redux, although one could argue it's a bit overkill for this scenario, especially now that we can take advantage of React's powerful Context API.&lt;/p&gt;

&lt;p&gt;So, let's break down how the demo code works.&lt;/p&gt;

&lt;p&gt;We've created a theme context here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ThemeContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, our theme starts with the value &lt;code&gt;"light"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Looking at our app's &lt;code&gt;render&lt;/code&gt; method, we see it's creating a provider for this context and setting its value to be the app's state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;setTheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ThemeContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Article&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Div&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ThemeToggle&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ThemeContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;&amp;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;That state consists of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The current value of the theme (&lt;code&gt;"light"&lt;/code&gt; initially).&lt;/li&gt;
&lt;li&gt;A method to update the theme.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, the most relevant part of the code is the following higher-order component, &lt;code&gt;withTheme&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;withTheme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ThemeContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Consumer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;setTheme&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setTheme&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ThemeContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Consumer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This higher-order component accepts a reference to any generic component and returns a new component that's wrapped in &lt;code&gt;ThemeContext.Consumer&lt;/code&gt;. Effectively, the HOC consumes the theme's current &lt;code&gt;value&lt;/code&gt; and injects this into the component as additional props.&lt;/p&gt;

&lt;p&gt;This allows us to then do the following in any of our components:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;withTheme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MyComponent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check it out—here's the code for the &lt;code&gt;ThemeToggle&lt;/code&gt; button:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&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;react&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;themeMap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;withTheme&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;../App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ThemeToggle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setTheme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;themeMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    Toggle theme (current: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;)
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// This gives us access to two additional props: theme and setTheme&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;withTheme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ThemeToggle&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We've defined a simple functional component like any other that you're used to by now, except we inject the theme variables into this component before exporting it. This gives the button access to the theme value as well as the ability to toggle said theme. We do precisely that in the button's &lt;code&gt;onClick&lt;/code&gt; handler.&lt;/p&gt;

&lt;p&gt;Now, anytime we want a component to be aware of the current theme, all we have to do is wrap it with the higher-order component, and we're done!&lt;/p&gt;

&lt;p&gt;As I mentioned earlier, other real-world examples of higher-order components include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Injecting internationalization settings into a component to regulate text formatting.&lt;/li&gt;
&lt;li&gt;Injecting user login info into a component to check permissions.&lt;/li&gt;
&lt;li&gt;... and much, &lt;em&gt;much&lt;/em&gt; more.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One thing worth noting is that when the value of the context changes, all components that consume it will re-render. But you'd get the same behavior if you were to use a state management library like Redux. When you map state to props in Redux, a state change triggers a prop change, and a prop change causes your connected components to re-render.&lt;/p&gt;

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

&lt;p&gt;The higher-order component design pattern is pretty powerful once you get comfortable with it and realize what it's doing. In a nutshell, higher-order components are &lt;strong&gt;component factories&lt;/strong&gt; that take a component, inject props into it, and return the modified component. As we saw, you can compose higher-order components and even combine them with React's Context API to write powerful, reusable code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Attributions
&lt;/h2&gt;

&lt;p&gt;The copyright for the React logo used in this blog post's thumbnail &lt;a href="https://commons.wikimedia.org/wiki/File:React-icon.svg"&gt;belongs to Facebook&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The image of the factory was taken by &lt;a href="https://unsplash.com/photos/6xeDIZgoPaw"&gt;Patrick Hendry&lt;/a&gt; on Unsplash.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
    </item>
    <item>
      <title>An Introduction to HTTP Cookies</title>
      <dc:creator>Aleksandr Hovhannisyan</dc:creator>
      <pubDate>Thu, 20 Aug 2020 11:37:54 +0000</pubDate>
      <link>https://dev.to/aleksandrhovhannisyan/what-are-cookies-11gm</link>
      <guid>https://dev.to/aleksandrhovhannisyan/what-are-cookies-11gm</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This post was &lt;a href="https://www.aleksandrhovhannisyan.com/blog/http-cookies/" rel="noopener noreferrer"&gt;originally published on my dev blog&lt;/a&gt;. Since reposting it here on Dev.to, I've edited the original considerably. I recommend reading it on my blog for the latest revisions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Have you ever wondered how a website remembers who you are when you navigate between different pages, or when you close the site and come back later? Why is it that you only have to log in if you've been gone for a really long time? What's this magic glue that seemingly holds these separate pages together as if they're a single unit—and, for you as a user, a single experience?&lt;/p&gt;

&lt;p&gt;In this guide, we'll take a look at everything you need to know about &lt;strong&gt;browser cookies&lt;/strong&gt;—you know, those things that a support rep once told you to clear, along with &lt;a href="https://en.wikipedia.org/wiki/Cache_(computing)" rel="noopener noreferrer"&gt;your hard-earned money&lt;/a&gt;. We'll look at what cookies are, how they get set, how advertising cookies work, and much more.&lt;/p&gt;

&lt;p&gt;The only prerequisite is a basic understanding of how the web works. In particular, we'll be referring to things like HTTP requests, browsers, and servers. Let's dig in!&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul id="markdown-toc"&gt;
  &lt;li&gt;How Does a Website Remember Who You Are?&lt;/li&gt;
  &lt;li&gt;
What Is a Cookie?    &lt;ul&gt;
      &lt;li&gt;
Types of Cookies: Session vs. Permanent        &lt;ul&gt;
          &lt;li&gt;1. Session Cookies&lt;/li&gt;
          &lt;li&gt;2. Permanent Cookies&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
How Do Cookies Get Set in a Browser?    &lt;ul&gt;
      &lt;li&gt;HTTP Request and Response Headers&lt;/li&gt;
      &lt;li&gt;The &lt;code class="language-plaintext highlighter-rouge"&gt;Set-Cookie&lt;/code&gt; HTTP Response Header&lt;/li&gt;
      &lt;li&gt;
Reading and Creating Cookies via JavaScript        &lt;ul&gt;
          &lt;li&gt;HTTPOnly Cookies: Protecting Sensitive Data&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;The Same-Origin Policy and Session Hijacking&lt;/li&gt;
  &lt;li&gt;
Why Do Websites Ask for My Permission to Store Cookies?    &lt;ul&gt;
      &lt;li&gt;How Advertising Cookies Work&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
Where Are Cookies Stored on My Computer?    &lt;ul&gt;
      &lt;li&gt;Chrome&lt;/li&gt;
      &lt;li&gt;Firefox&lt;/li&gt;
      &lt;li&gt;Microsoft Edge&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
How Do I Clear My Cookies?    &lt;ul&gt;
      &lt;li&gt;What Happens if I Clear My Cookies?&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
Alternatives to Cookies    &lt;ul&gt;
      &lt;li&gt;Cookies vs. &lt;code class="language-plaintext highlighter-rouge"&gt;localStorage&lt;/code&gt; vs. &lt;code class="language-plaintext highlighter-rouge"&gt;sessionStorage&lt;/code&gt;
&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Final Thoughts&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How Does a Website Remember Who You Are?
&lt;/h2&gt;

&lt;p&gt;From a technical perspective, each page of a website corresponds to a different "resource" that's hosted on a web server—a computer whose job is to listen for requests from a user's browser and to respond accordingly. For example, when you loaded this page, your browser requested a bunch of different resources from my web server, such as the HTML document itself, its stylesheet, some JavaScript, images, and more. Thus, navigating to a different page on a site initiates a new &lt;strong&gt;HTTP request&lt;/strong&gt; to fetch that resource (and potentially any related resources) from the web server.&lt;/p&gt;

&lt;p&gt;Yet the HTTP protocol is &lt;strong&gt;stateless&lt;/strong&gt;, meaning a server does not keep track of any of your prior HTTP requests for the purposes of matching future requests to older ones ("who did this come from?"). This means that HTTP requests sent by your browser need to contain all necessary information in order for the server to identify you. This is especially important if you're trying to access privileged resources that require authentication, like the settings under your user profile. So how exactly is this accomplished?&lt;/p&gt;

&lt;p&gt;Websites have a few different options for tracking your identity, as well as managing what's called your &lt;strong&gt;session state&lt;/strong&gt;: information about your current browsing session. In this post, we'll take a look at just one particular approach: storing cookies in your web browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is a Cookie?
&lt;/h2&gt;

&lt;p&gt;If you Google "what is a cookie," chances are that you'll come across a definition like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A cookie is a piece of data that a browser stores on your computer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Great! Unfortunately, while this definition is accurate, it doesn't actually give you a sense of what a cookie really is or what one looks like. First, it helps to understand what a cookie &lt;em&gt;isn't&lt;/em&gt;. Cookies in your browser are not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Processes that are running in the background.&lt;/li&gt;
&lt;li&gt;Malware or spyware that's listening to your activity.&lt;/li&gt;
&lt;li&gt;Delicious snacks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cookies are literally inert pieces of textual data. And the best way to understand cookies is to actually &lt;em&gt;look at one&lt;/em&gt;. Follow these simple steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your browser's developer tools (&lt;code&gt;Ctrl+Shift+I&lt;/code&gt; on Windows / &lt;code&gt;Cmd+Shift+I&lt;/code&gt; on Mac).&lt;/li&gt;
&lt;li&gt;Navigate to the &lt;code&gt;Application&lt;/code&gt; tab in Chrome (&lt;code&gt;Storage&lt;/code&gt; in Firefox and Edge).&lt;/li&gt;
&lt;li&gt;Expand &lt;code&gt;Cookies&lt;/code&gt; in the left-hand panel.&lt;/li&gt;
&lt;li&gt;Click a domain that's listed to view the cookies that are associated with it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For the purposes of this tutorial, I'll be using Reddit as an example. Here are the cookies associated with my Reddit account (I've intentionally obfuscated potentially sensitive values out of an abundance of caution):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Freddit-cookies.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Freddit-cookies.png" alt="Examining the cookies associated with my Reddit user account"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;True to its definition, a cookie is in fact "just a piece of data" stored on your computer. Each site may store zero or more cookies. Here, Reddit is storing 15 different cookies. A cookie consists of a name, a value, an expiration date or "age," a size in bytes, and so on.&lt;/p&gt;

&lt;p&gt;Notice how each cookie stores certain information identifying me as a user, as well as my preferences and settings to help the web server customize my user experience and the results returned in my Reddit feed. For example, &lt;code&gt;redesign_optout&lt;/code&gt; is one cookie in this list. Its value is set to &lt;code&gt;true&lt;/code&gt; here for my Reddit account because I prefer to use the old interface. Since Reddit uses server-side rendering, the server needs to know which version of the Reddit interface a user wants to fetch: the old one or the new one. There are a few other cookies in the list, some of which are specific to my user profile and current browsing session.&lt;/p&gt;

&lt;p&gt;Over on the far right, you'll see a &lt;code&gt;Size&lt;/code&gt; column. The size of a cookie is the total number of characters (bytes) in its name and value. For example, the cookie &lt;code&gt;redesign_optout=true&lt;/code&gt; has a size of &lt;code&gt;19&lt;/code&gt; because the combined character length of &lt;code&gt;redesign_optout&lt;/code&gt; and &lt;code&gt;true&lt;/code&gt; is &lt;code&gt;19&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Types of Cookies: Session vs. Permanent
&lt;/h3&gt;

&lt;p&gt;There's another column in the table above that deserves our attention: &lt;code&gt;Expires / Max-Age&lt;/code&gt;. These two attributes basically tell your browser for how long a cookie should be kept around. There are two types of cookies that we'll look at, each defined by its expiration/max age.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Session Cookies
&lt;/h4&gt;

&lt;p&gt;Notice that some cookies have &lt;code&gt;Session&lt;/code&gt; as their value under the &lt;code&gt;Expires / Max-Age&lt;/code&gt; column:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Fsession-cookies.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Fsession-cookies.png" alt="Exploring session cookies on Reddit via Firefox dev tools"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These are known as &lt;strong&gt;session cookies&lt;/strong&gt;, also called &lt;strong&gt;temporary cookies&lt;/strong&gt; because they're only kept around for your &lt;em&gt;current browsing session&lt;/em&gt;. It's up to the browser itself to define what constitutes a "current browsing session." In Chrome and Firefox, this is when you fully shut down your browser (i.e., close all tabs). At that point, the cookie may get cleared.&lt;/p&gt;

&lt;p&gt;Why do I say "may"? Because there's a &lt;a href="https://textslashplain.com/2019/06/24/surprise-undead-session-cookies/" rel="noopener noreferrer"&gt;hidden gotcha&lt;/a&gt;. When you launch these browsers, some of them give you the option of restoring your previously open tabs. This means that certain browsers may restore a session cookie even after a browsing session has technically ended.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Permanent Cookies
&lt;/h4&gt;

&lt;p&gt;While the term "permanent" seems to imply that these cookies never go away, that's not the case at all. A permanent cookie is simply one that has an explicit expiration date and time or that has a max age set to a certain duration in milliseconds. These cookies will be cleared once they've expired.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Do Cookies Get Set in a Browser?
&lt;/h2&gt;

&lt;p&gt;So we've seen that a cookie is in fact "a piece of data" stored in your browser. But how exactly does a cookie get created in the first place? Where does it come from?&lt;/p&gt;

&lt;p&gt;As I mentioned earlier in this post, the HTTP protocol is stateless, meaning a web server does not keep track of any information about your prior HTTP requests. This means that requests sent from your browser to a web server must include all information that the server needs in order to identify you. Guess what? This means that your browser will need to include your cookies for that domain (assuming that you have any) in its requests.&lt;/p&gt;

&lt;p&gt;For the upcoming section, you'll only need a basic understanding of how the web works—in particular, the HTTP protocol. Here's a quick refresher:&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP Request and Response Headers
&lt;/h3&gt;

&lt;p&gt;HTTP consists of requests and responses. A browser sends a request to a server; the server sends back a response. Both requests and responses can contain data, but they also include certain metadata (supplementary information) about the request/response itself. These are known as &lt;strong&gt;request headers&lt;/strong&gt; and &lt;strong&gt;response headers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, a request header may contain some of this information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The type of device being used to initiate the request (e.g., &lt;code&gt;Windows NT 10.0; Win64; x64&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The browser that's sending the request (e.g., &lt;code&gt;AppleWebKit/537.36 (KHTML, like Gecko)&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The URL that is being requested (e.g., &lt;code&gt;https://www.reddit.com&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;... and much more.&lt;/p&gt;

&lt;p&gt;Conversely, servers send back a response containing data like images, CSS, HTML, JSON, etc., along with certain metadata about the response itself. This information appears in the response header. For example, servers may tell a browser:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whether the request was successfully handled, via &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" rel="noopener noreferrer"&gt;HTTP response status codes&lt;/a&gt;. The most common ones you'll encounter are 200, 304, 404, and 500.&lt;/li&gt;
&lt;li&gt;The type of content returned (e.g., &lt;code&gt;application/json&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;For how long the content should be cached by the browser.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;... and much more.&lt;/p&gt;

&lt;p&gt;You can view request and response headers for any HTTP request using the &lt;code&gt;Network&lt;/code&gt; tab in your browser's dev tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  The &lt;code&gt;Set-Cookie&lt;/code&gt; HTTP Response Header
&lt;/h3&gt;

&lt;p&gt;Here's the key: A server may also send along a &lt;strong&gt;&lt;code&gt;Set-Cookie&lt;/code&gt; response header&lt;/strong&gt; that tells your browser to store a cookie. A response may contain as many of these &lt;code&gt;Set-Cookie&lt;/code&gt; headers as needed, one for each cookie that needs to get set. Basically, cookies can be generated &lt;em&gt;programmatically&lt;/em&gt; on the server side and sent along with responses whenever they need to get set by a browser. But you can also create cookies with JavaScript, as we'll see shortly.&lt;/p&gt;

&lt;p&gt;Here's an example of monitoring XHR requests with the Firefox Dev Tools on Reddit and intercepting the &lt;code&gt;Set-Cookie&lt;/code&gt; response header:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Fset-cookie.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Fset-cookie.gif" alt="Reddit sets the redesign_optout cookie to be true when I opt out of the new user interface"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, if you inspect future requests, you'll find that this cookie is included in the &lt;strong&gt;&lt;code&gt;Cookie&lt;/code&gt; HTTP request header&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Fresponse-cookie.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Fresponse-cookie.png" alt="Inspecting a response header in the Firefox dev tools for Reddit"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Reading and Creating Cookies via JavaScript
&lt;/h3&gt;

&lt;p&gt;Before we move on, note that there's a second way to view cookies in your developer tools. Simply navigate to the &lt;code&gt;Console&lt;/code&gt; tab, enter the following code, and press enter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cookie&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see one big output string containing &lt;code&gt;name=value&lt;/code&gt; pairs of cookies strung together with semicolons. Here, &lt;code&gt;document.cookie&lt;/code&gt; is how you create, update, and delete cookies via JavaScript. Notice that some of the supplementary information—like the expiration date or size of the cookie—does not appear in this string. However, those values &lt;em&gt;will&lt;/em&gt; get set internally in the browser.&lt;/p&gt;

&lt;p&gt;Here's an example of creating a cookie with JavaScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cookie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;foo=bar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, this API is a little weird. While you would expect the above line of code to replace the whole cookie string, this new cookie will actually get &lt;em&gt;concatenated&lt;/em&gt; to the existing cookie string (or take the place of an existing cookie, if it has the same name). Here's an example of creating three cookies:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Fcreating-cookies-with-javascript.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Fcreating-cookies-with-javascript.png" alt="Creating cookies with JavaScript via the Google Chrome console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that you can't create multiple cookies in one go, like &lt;code&gt;document.cookie = 'foo=bar; hello=world; id=123'&lt;/code&gt;. You have to call &lt;code&gt;document.cookie = ...&lt;/code&gt; separately for each cookie.&lt;/p&gt;

&lt;p&gt;When you just specify the name and value of a cookie, it gets created as a session cookie by default. You can also optionally specify an expiration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cookie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;foo=bar; expires=Su, 20 Dec 2020 20:20:20 UTC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: If "today" is past the above date when you're reading this, the code won't work. And that's because of the next point.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To delete a cookie with JavaScript, you need to set its expiration date to be sometime in the past:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cookie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;foo=bar; expires=Fri, 24 Jul 2020 04:00:00 UTC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll take a closer look at how to delete cookies cookies later in this guide.&lt;/p&gt;

&lt;h4&gt;
  
  
  HTTPOnly Cookies: Protecting Sensitive Data
&lt;/h4&gt;

&lt;p&gt;If you compare the output of &lt;code&gt;document.cookie&lt;/code&gt; to the table that we looked at earlier, you may be surprised to find that some cookies are missing from the output string. And that's because of an additional property that we haven't yet covered: &lt;strong&gt;HTTPOnly cookies&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Fhttp-only-cookies.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Fhttp-only-cookies.png" alt="A list of http-only cookies for my Reddit account"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A cookie that is marked as HTTPOnly cannot be read via JavaScript. Usually, you'll find that session cookies are marked as HTTPOnly. This is a safety precaution to protect you against session hijacking, where a malicious actor may try to read your cookie via JavaScript and use it to masquerade as you.&lt;/p&gt;

&lt;p&gt;Speaking of session hijacking...&lt;/p&gt;

&lt;h2&gt;
  
  
  The Same-Origin Policy and Session Hijacking
&lt;/h2&gt;

&lt;p&gt;It's important to understand that every cookie stored on your computer is associated with a specific domain, like &lt;code&gt;reddit.com&lt;/code&gt; in the examples above.&lt;/p&gt;

&lt;p&gt;Naturally, that begs the following question: If cookies for Site A and cookies for Site B are both stored in the same browser and on the same computer, is it possible for Site B to use Site A's cookies in its request headers? Fortunately, because of the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy" rel="noopener noreferrer"&gt;same-origin policy&lt;/a&gt;, this is not possible.&lt;/p&gt;

&lt;p&gt;If you think about it, that would be pretty dangerous if it were allowed—it would mean that Site B could read cookies stored for Site A in your browser and then use those cookies to &lt;a href="https://en.wikipedia.org/wiki/Session_hijacking#:~:text=In%20computer%20science%2C%20session%20hijacking,services%20in%20a%20computer%20system." rel="noopener noreferrer"&gt;hijack your browsing session&lt;/a&gt;. All that Site B would need to do is send those exact cookies in a request header to Site A's server, and voila—the server, none the wiser, would think that the request is coming from you, when really it's someone who's impersonating you.&lt;/p&gt;

&lt;p&gt;There's a tutorial on &lt;a href="https://embracethered.com/blog/posts/passthecookie/#attack-chain" rel="noopener noreferrer"&gt;how to perform session hijacking&lt;/a&gt; that helps drive home the following key point: There is nothing special about you and your browser when you access a particular site. The only way a web server knows who you are is based on the information your browser passes along in an HTTP request. If someone has your session cookies, they can simply copy those cookies locally, refresh the page, and essentially bypass traditional authentication mechanisms like usernames and passwords.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Fun fact: This is why I obfuscated my session cookies (e.g., &lt;code&gt;reddit_session&lt;/code&gt;) in the screenshots above. While session cookies are technically temporary, we've already seen that they can stick around for longer than a browser session.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why Do Websites Ask for My Permission to Store Cookies?
&lt;/h2&gt;

&lt;p&gt;This is typically where the misconceptions and fears arise regarding what cookies are and whether they're dangerous. Remember: A cookie is nothing but a piece of data. It's inert—it's only useful if your browser sends it to a server via an HTTP request. Rather, people are wary of browser cookies because they're (rightfully) concerned about their online privacy.&lt;/p&gt;

&lt;p&gt;With the advent of the GDPR in the European Union and the 2018 amendments to the California Consumer Privacy Act, companies were forced to comply with new privacy regulations. Many decided to go about this by showing popups and notices that ask for your permission to store cookies on your computer, rather than simply doing so without your knowledge.&lt;/p&gt;

&lt;p&gt;Cookies are important. But &lt;em&gt;certain kinds of cookies&lt;/em&gt; pose a privacy concern for users since they can be used to store personally identifiable information about you based on your activity on a particular website. This is typically done with &lt;a href="https://www.cookiepro.com/knowledge/what-are-targeting-advertising-cookies/" rel="noopener noreferrer"&gt;advertising cookies&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Advertising Cookies Work
&lt;/h3&gt;

&lt;p&gt;Advertising cookies are used by &lt;a href="https://marketing.toolbox.com/articles/what-is-an-ad-network-definition-types-and-examples" rel="noopener noreferrer"&gt;ad networks&lt;/a&gt; like Google AdSense to show you personalized content, as well as to share your information with advertisers within the network to collect usage data and analytics. A website is considered to be part of an ad network like Google AdSense if it's paying that network to show ads on its behalf.&lt;/p&gt;

&lt;p&gt;This quote from &lt;a href="https://policies.google.com/technologies/types?hl=en-US" rel="noopener noreferrer"&gt;Google's policy on advertising&lt;/a&gt; is particularly enlightening about how Google AdSense stores its cookies:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We also use one or more cookies for advertising we serve across the web. One of the main advertising cookies on non-Google sites is named ‘IDE‘ and is stored in browsers under the domain &lt;code&gt;doubleclick.net&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here's a breakdown of how advertising cookies work:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You visit a site (e.g., &lt;code&gt;https://www.foo.bar&lt;/code&gt;) that happens to be part of some ad network (e.g., Google AdSense, which has a domain of &lt;code&gt;doubleclick.net&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The site has ads embedded in its HTML markup, such as in an &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;, or &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Those ads are hosted on the ad network's domain (e.g., &lt;code&gt;doubleclick.net&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;When you load the page, your browser requests those ads from the ad network's domain, just like it requests any other resource on the page (images, videos, and so on).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The secret sauce&lt;/strong&gt;: The ad network sends the requested ads, &lt;em&gt;along with an advertising cookie&lt;/em&gt; in the response header.&lt;/li&gt;
&lt;li&gt;Your browser records the cookie for that ad network's domain (in this case, &lt;code&gt;doubleclick.net&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;When you visit another site that's part of the same ad network, the cookie will follow you.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Steps 4–6 may not occur if you're in private browsing, have an adblocker enabled, or have enabled &lt;a href="https://blog.mozilla.org/blog/2019/06/04/firefox-now-available-with-enhanced-tracking-protection-by-default/" rel="noopener noreferrer"&gt;Enhanced Tracking Protection in Firefox&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is one of the reasons why people sometimes find that ads are following them around the web no matter where they go, and that these ads are often tailored to the content they previously viewed. For example, if you're shopping online for dog toys and later visit a social media site with ads enabled, you may see ads for dog toys and related accessories in a sidebar. It's not a coincidence—it's an advertising cookie in action, and some people find this to be an invasion of privacy.&lt;/p&gt;

&lt;p&gt;Here's a real-world example of inspecting that very &lt;code&gt;IDE&lt;/code&gt; advertising cookie that Google mentions. This is on StackOverflow, one of the few sites where I felt it would be safe to temporarily disable my adblocker for this tutorial:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Fstackoverflow-cookies.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Fstackoverflow-cookies.png" alt="Examining the cookies associated with doubleclick.net"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Time for a fun experiment, assuming you're willing to accept cookies and sell your soul to advertisers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Launch Google Chrome. Firefox's privacy protections are pretty aggressive, which is usually a good thing—but it will get in the way of this valuable learning experience.&lt;/li&gt;
&lt;li&gt;Visit a popular website and temporarily disable your adblocker.&lt;/li&gt;
&lt;li&gt;Open your devtools and try to find any cookies that seem to be from a Google domain. Look for &lt;code&gt;doubleclick.net&lt;/code&gt; in the &lt;code&gt;Domain&lt;/code&gt; column (see the screenshot above).&lt;/li&gt;
&lt;li&gt;Visit another website that you suspect will show ads, and disable your adblocker again.&lt;/li&gt;
&lt;li&gt;Open your devtools and see if there are any cookies from the same ad network domain.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In particular, you'll want to look for the &lt;code&gt;IDE&lt;/code&gt; cookie. And what you'll find is that it's exactly the same on the second site as it is on the first one that you visited. I tested this with Quora:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Fquora-cookies.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Fquora-cookies.png" alt="Inspecting Quora cookies via Chrome dev tools"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Everything&lt;/strong&gt; is the same, down to the cookie's expiration date and time.&lt;/p&gt;

&lt;p&gt;As we've learned, this is because the advertising cookie is not associated with StackOverflow's or Quora's domain—it's associated with the ad network's domain (in this case, &lt;code&gt;doubleclick.net&lt;/code&gt;). So as long as it remains on your computer, it'll follow you around on other sites that are part of the same ad network. Pretty neat—and definitely something to be worried about if you're privacy conscious.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Are Cookies Stored on My Computer?
&lt;/h2&gt;

&lt;p&gt;By their very nature, cookies do not sync between browsers. They're just inert pieces of data. So, cookies set in Chrome for a domain have nothing to do with cookies set in Firefox, Edge, or any other browser for the same domain. This is why you'll be prompted to log into your account if you try visiting a site or app with a browser that you don't normally use.&lt;/p&gt;

&lt;p&gt;Most major browsers store their cookies in an SQLite database file. You can open this database file using an app like &lt;a href="https://sqlitebrowser.org/" rel="noopener noreferrer"&gt;DB Browser for SQLite&lt;/a&gt;. Note that the location of your cookies will vary depending on the browser and operating system you're using.&lt;/p&gt;

&lt;h3&gt;
  
  
  Chrome
&lt;/h3&gt;

&lt;p&gt;Chrome stores its cookies in an SQLite database file named &lt;code&gt;Cookies&lt;/code&gt;, which is located here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Windows: &lt;code&gt;C:\Users\&amp;lt;your_username&amp;gt;\AppData\Local\Google\Chrome\User Data\Default\Cookies&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Mac: &lt;code&gt;~/Library/Application Support/Google/Chrome/Default/Cookies&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Linux: &lt;code&gt;~/.config/google-chrome/Default/Cookies&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Apparently, Chrome maintains two separate database tables for cookies—a &lt;code&gt;cookies&lt;/code&gt; table and a &lt;code&gt;meta&lt;/code&gt; table:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Fschemas.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Fschemas.png" alt="Exploring the schemas of the two tables in Chrome's cookies database"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And here's what the data looks like for the &lt;code&gt;cookies&lt;/code&gt; table:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Fcookie-data.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Fcookie-data.png" alt="Exploring Chrome's cookies table"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Firefox
&lt;/h3&gt;

&lt;p&gt;Like Chrome, Firefox stores its cookies in an SQLite database file. Here's how to find it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click the hamburger icon (top-right of your browser) to open the Firefox settings.&lt;/li&gt;
&lt;li&gt;Go to &lt;code&gt;Help &amp;gt; Troubleshooting Information&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Locate &lt;code&gt;Profile Folder&lt;/code&gt; in the table. Click the &lt;code&gt;Open Folder&lt;/code&gt; button.&lt;/li&gt;
&lt;li&gt;Scroll down and find &lt;code&gt;cookies.sqlite&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For example, on Windows 10, you'll find your Firefox cookies under &lt;code&gt;C:\Users\&amp;lt;your_username&amp;gt;\AppData\Roaming\Mozilla\Firefox\Profiles\&amp;lt;your_firefox_profile&amp;gt;\cookies.sqlite&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Microsoft Edge
&lt;/h3&gt;

&lt;p&gt;Edge stores its cookies not in a single file but rather as separate files under &lt;code&gt;C:\Users\&amp;lt;your_username&amp;gt;\AppData\Local\Microsoft\Windows\INetCookies&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Fedge-cookies.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Fedge-cookies.png" alt="Viewing a list of cookies stored by Microsoft Edge, via File Explorer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can open these files with a plain text editor.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Do I Clear My Cookies?
&lt;/h2&gt;

&lt;p&gt;There are two ways you can clear your cookies:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Via your browser's developer tools, which we've already used quite a bit in this tutorial.&lt;/li&gt;
&lt;li&gt;Via your browser's settings, usually under History.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first one is the more flexible option of the two, as it allows you to only delete cookies from a particular domain as opposed to all cookies across all domains. You can either right-click a cookie and delete it or simply click the clear icon (a trashcan in Firefox) to delete all cookies:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Fdeleting-cookies.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Fdeleting-cookies.png" alt="Deleting cookies either by right-clicking a cookie or clearing all cookies at once, via browser dev tools"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And as we saw in an earlier section, you can also clear a cookie via JavaScript by setting its expiration date to be sometime in the past.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Happens if I Clear My Cookies?
&lt;/h3&gt;

&lt;p&gt;If you've been following along, you should already know the answer to this question. Remember: A web server uses cookies as a form of authentication, to ensure that you're allowed to view the pages that you're trying to access. It also uses cookies to personalize your website experience by storing certain settings and preferences. So, if you clear your cookies for a website, two things will happen:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You'll be logged out the next time you visit the site. This is because the browser won't send any cookies to the server when you request that page, so the server won't have any way of knowing who you are. Once you log back in, you'll get a new set of cookies, fresh from the oven.&lt;/li&gt;
&lt;li&gt;Your preferences or settings may get cleared for that website or app.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that certain other user settings are stored in an app's database rather than in cookies on the client side. So, when you clear your cookies, those other settings will be left untouched.&lt;/p&gt;

&lt;h2&gt;
  
  
  Alternatives to Cookies
&lt;/h2&gt;

&lt;p&gt;Cookies are just one way that websites can save information on the client side. Browsers may also use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API" rel="noopener noreferrer"&gt;The Web Storage API&lt;/a&gt;: &lt;code&gt;localStorage&lt;/code&gt; and &lt;code&gt;sessionStorage&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API" rel="noopener noreferrer"&gt;IndexedDB&lt;/a&gt;, typically for large amounts of data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I use the first option on my blog to store your selected theme (light mode or dark mode). You can explore &lt;code&gt;localStorage&lt;/code&gt; just like you would any other storage option in your browser's dev tools:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Flocal-storage.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fwhat-are-cookies%2Flocal-storage.png" alt="Exploring localStorage for my website"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also clear &lt;code&gt;localStorage&lt;/code&gt; via the same tab in dev tools or via JavaScript.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cookies vs. &lt;code&gt;localStorage&lt;/code&gt; vs. &lt;code&gt;sessionStorage&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Here's a brief look at the major differences between cookies and the Web Storage API:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
    &lt;thead&gt;
        &lt;tr&gt;
            &lt;th&gt;Storage&lt;/th&gt;
            &lt;th&gt;Expiration&lt;/th&gt;
            &lt;th&gt;Use cases&lt;/th&gt;
        &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;localStorage&lt;/td&gt;
            &lt;td&gt;None, but users can manually clear it via dev tools or the console (&lt;code&gt;localStorage.clear()&lt;/code&gt;).&lt;/td&gt;
            &lt;td&gt;Storing data on the client side that the server does not need (e.g., preferences, settings).&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;sessionStorage&lt;/td&gt;
            &lt;td&gt;Until the end of the current browsing session (i.e., until you shut down your browser).&lt;/td&gt;
            &lt;td&gt;Storing data specific to the user's current browsing session.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;Cookies&lt;/td&gt;
            &lt;td&gt;Current browsing session, if an expiration/max age is not specified.&lt;/td&gt;
            &lt;td&gt;Storing data received in a response header. Included in all future request headers.&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;Cookies are a pretty interesting (and sometimes controversial) topic in web development. &lt;a href="https://www.webdesignerdepot.com/2019/06/does-the-web-really-need-cookies/" rel="noopener noreferrer"&gt;Some people question whether they're really necessary these days&lt;/a&gt;. Others are worried about the privacy implications of advertising cookies that follow you around the web.&lt;/p&gt;

&lt;p&gt;In any case, cookies exist, and probably will for quite some time. I hope you now have a better understanding of what browser cookies are and the role that they play on the web!&lt;/p&gt;

</description>
      <category>dev</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Binary for Beginners: The ABCs of 0s and 1s</title>
      <dc:creator>Aleksandr Hovhannisyan</dc:creator>
      <pubDate>Sat, 08 Aug 2020 15:27:32 +0000</pubDate>
      <link>https://dev.to/aleksandrhovhannisyan/binary-for-beginners-the-abcs-of-0s-and-1s-137n</link>
      <guid>https://dev.to/aleksandrhovhannisyan/binary-for-beginners-the-abcs-of-0s-and-1s-137n</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This post was &lt;a href="https://www.aleksandrhovhannisyan.com/blog/computer-science/the-binary-number-system/" rel="noopener noreferrer"&gt;originally published on my dev blog&lt;/a&gt;. Also, it's really long, lol. My aim was to create the most comprehensive tutorial on binary numbers—one that I wish I had back when I was learning this stuff. I hope someone out there finds this helpful!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What is &lt;code&gt;10&lt;/code&gt;? If this is your first time learning about the binary number system, then this question may seem odd. Of course it's ten, right?&lt;/p&gt;

&lt;p&gt;Let's try something different. Have you ever heard this joke?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There are &lt;code&gt;10&lt;/code&gt; types of people in the world: those who understand binary and those who don't.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Unless you're familiar with binary numbers, this probably doesn't make much sense. But by the end of this post, you'll come to appreciate this and many other awful developer jokes!&lt;/p&gt;

&lt;p&gt;In this beginner's tutorial, we'll look at everything you need to know about the binary number system, but we'll also take a quick look at decimal and hexadecimal, as they're closely related. I'll include relevant bits of code and real-life examples to help you appreciate the beauty of binary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
What Is a Number System?

&lt;ul&gt;
&lt;li&gt;Bases, Exponents, and Digits&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

The Binary Number System (Base 2)

&lt;ul&gt;
&lt;li&gt;Binary Is Close to the Hardware of a Computer&lt;/li&gt;
&lt;li&gt;The ASCII Standard&lt;/li&gt;
&lt;li&gt;1 Character = 1 Byte&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

The Hexademical Number System (Base 16)

&lt;ul&gt;
&lt;li&gt;How to Convert Between Binary and Hexadecimal&lt;/li&gt;
&lt;li&gt;Binary to Hexadecimal&lt;/li&gt;
&lt;li&gt;Hexadecimal to Binary&lt;/li&gt;
&lt;li&gt;Real-World Application: Representing Colors with RGB/Hex&lt;/li&gt;
&lt;li&gt;How Many Colors Are There?&lt;/li&gt;
&lt;li&gt;What Are 8-Bit Colors?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Signed Binary Number System: Two's Complement

&lt;ul&gt;
&lt;li&gt;How Does Two's Complement Work?&lt;/li&gt;
&lt;li&gt;The Intuitive Approach: What Does a Leading 1 Denote?&lt;/li&gt;
&lt;li&gt;Two's Complement Shortcut: Flip the Bits and Add a 1&lt;/li&gt;
&lt;li&gt;How Many Signed Binary Numbers Are There?&lt;/li&gt;
&lt;li&gt;
What Is the Largest Signed 32-bit Integer?

&lt;ul&gt;
&lt;li&gt;Real-World Application: Video Game Currency&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;What Is the Smallest Signed 32-bit Integer?&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

Basic Arithmetic in the Binary Number System

&lt;ul&gt;
&lt;li&gt;Adding Binary Numbers&lt;/li&gt;
&lt;li&gt;Subtracting Binary Numbers&lt;/li&gt;
&lt;li&gt;Multiplying Binary Numbers&lt;/li&gt;
&lt;li&gt;Dividing Binary Numbers&lt;/li&gt;
&lt;li&gt;Integer Overflow and Underflow in Binary&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;The Binary Number System: Additional Topics for Exploration&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Is a Number System?
&lt;/h2&gt;

&lt;p&gt;Before we look at binary, let's take a step back and discuss number systems &lt;em&gt;in general&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Now, it may be strange to think of number "systems" in the plural if this is your first time learning about them. That's because the majority of the world is familiar with just one: the &lt;strong&gt;decimal number system&lt;/strong&gt; (aka "base ten"), also known as the &lt;strong&gt;Arabic number system&lt;/strong&gt;. This system has digits ranging from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;9&lt;/code&gt;, which we use to form numbers in our daily lives.&lt;/p&gt;

&lt;p&gt;For example, in the decimal number system, &lt;code&gt;579&lt;/code&gt; expands to this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;579 = 5(10&lt;sup&gt;2&lt;/sup&gt;) + 7(10&lt;sup&gt;1&lt;/sup&gt;) + 9(10&lt;sup&gt;0&lt;/sup&gt;) = 500 + 70 + 9&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;As a kid, you were taught that the &lt;code&gt;5&lt;/code&gt; in &lt;code&gt;579&lt;/code&gt; is in the "hundreds place," the &lt;code&gt;7&lt;/code&gt; is in the "tens place," and the &lt;code&gt;9&lt;/code&gt; is in the ones place. Notice that the &lt;code&gt;5&lt;/code&gt; is multiplied by one hundred (&lt;code&gt;10&lt;sup&gt;2&lt;/sup&gt;&lt;/code&gt;), the &lt;code&gt;7&lt;/code&gt; by ten (&lt;code&gt;10&lt;sup&gt;1&lt;/sup&gt;&lt;/code&gt;), and the &lt;code&gt;9&lt;/code&gt; by one (&lt;code&gt;10&lt;sup&gt;0&lt;/sup&gt;&lt;/code&gt;) to form the decimal number &lt;code&gt;579&lt;/code&gt;. Makes sense, right?&lt;/p&gt;

&lt;p&gt;Here, the number &lt;code&gt;10&lt;/code&gt; is what we call the &lt;strong&gt;base&lt;/strong&gt; (aka &lt;strong&gt;radix&lt;/strong&gt;) of our number system. Notice the powers of &lt;code&gt;10&lt;/code&gt; in the expanded expression above: &lt;code&gt;10&lt;sup&gt;2&lt;/sup&gt;&lt;/code&gt;, &lt;code&gt;10&lt;sup&gt;1&lt;/sup&gt;&lt;/code&gt;, and &lt;code&gt;10&lt;sup&gt;0&lt;/sup&gt;&lt;/code&gt;. For this reason, the terms &lt;em&gt;decimal&lt;/em&gt; and &lt;em&gt;base 10&lt;/em&gt; are interchangeable.&lt;/p&gt;

&lt;p&gt;In the decimal number system, a number is represented by placing digits into "buckets" that represent &lt;strong&gt;increasing powers of ten&lt;/strong&gt;, starting with &lt;code&gt;10&lt;sup&gt;0&lt;/sup&gt;&lt;/code&gt; in the rightmost "bucket," followed by &lt;code&gt;10&lt;sup&gt;1&lt;/sup&gt;&lt;/code&gt; to its immediate left, and so on infinitely:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fthe-binary-number-system%2Fbuckets.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fthe-binary-number-system%2Fbuckets.png" alt="Increasing powers of ten"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Any unused buckets to the far left have an implicit value of &lt;code&gt;0&lt;/code&gt; in them. We usually trim leading zeros because there is no use in saying &lt;code&gt;00579&lt;/code&gt; when that's mathematically identical to &lt;code&gt;579&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Why did humans pick &lt;code&gt;10&lt;/code&gt; to be the base of their preferred number system? Most likely because we're born with ten fingers and ten toes, and we're used to counting with our fingers when we're young. So it's simply natural for us to use this number system!&lt;/p&gt;

&lt;h3&gt;
  
  
  Bases, Exponents, and Digits
&lt;/h3&gt;

&lt;p&gt;As I've already hinted, the decimal number system (base &lt;code&gt;10&lt;/code&gt;) isn't the only one in existence. Let's use a more general mathematical notation to represent number systems beyond just our familiar one.&lt;/p&gt;

&lt;p&gt;In a number system with a fixed base of &lt;code&gt;b&lt;/code&gt;, the available digits range from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;b - 1&lt;/code&gt;. For example, in the decimal number system (&lt;code&gt;b = 10&lt;/code&gt;), we can only use the digits &lt;code&gt;0, 1, 2, ..., 9&lt;/code&gt;. When you "run out" of digits in a single bucket, you carry over a one to the next power of the base. For example, to get to the number after &lt;code&gt;99&lt;/code&gt;, you carry a one to the next power of ten: &lt;code&gt;100&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, suppose that we have a string of digits &lt;code&gt;d1 d2 ... dn&lt;/code&gt; (where &lt;code&gt;n&lt;/code&gt; is just the number of digits). Maybe that's &lt;code&gt;d1 d2 ... dn = 579&lt;/code&gt; from our earlier example. That string expands like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;d1b&lt;sup&gt;n-1&lt;/sup&gt; + d2b&lt;sup&gt;n-2&lt;/sup&gt; + ... + dnb&lt;sup&gt;0&lt;/sup&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And you can visualize that like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fthe-binary-number-system%2Fbases.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fthe-binary-number-system%2Fbases.png" alt="A generic base of b with digits d"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using our same example, &lt;code&gt;d1b&lt;sup&gt;n-1&lt;/sup&gt; + d2b&lt;sup&gt;n-2&lt;/sup&gt; + ... + dnb&lt;sup&gt;0&lt;/sup&gt; = 5(10&lt;sup&gt;2&lt;/sup&gt;) + 7(10&lt;sup&gt;1&lt;/sup&gt;) + 9(10&lt;sup&gt;0&lt;/sup&gt;)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fthe-binary-number-system%2F579.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fthe-binary-number-system%2F579.png" alt="Expanding 579 in terms of powers of 10"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Again, we have buckets from right to left in increasing powers of our base (&lt;code&gt;10&lt;/code&gt;).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The rightmost bucket will always represent &lt;code&gt;dn&lt;/code&gt; in any number system. Why? Because any base raised to the power of &lt;code&gt;0&lt;/code&gt; is just &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, in reality, you can have a number system that uses a base of &lt;code&gt;2&lt;/code&gt;, &lt;code&gt;3&lt;/code&gt;, &lt;code&gt;4&lt;/code&gt;, &lt;code&gt;120&lt;/code&gt;, and so on. Some of these have special names because they're used more often than others:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
    &lt;thead&gt;
        &lt;th&gt;Base&lt;/th&gt;
        &lt;th&gt;Name&lt;/th&gt;
        &lt;th&gt;Description&lt;/th&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;1&lt;/td&gt;
            &lt;td&gt;Unary&lt;/td&gt;
            &lt;td&gt;Also known as tallying. A number &lt;code&gt;n&lt;/code&gt; is represented by picking an arbitrary character and repeating it &lt;code&gt;n&lt;/code&gt; times (e.g., &lt;code&gt;xxxx&lt;/code&gt; would be &lt;code&gt;4&lt;/code&gt;).&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;2&lt;/td&gt;
            &lt;td&gt;Binary&lt;/td&gt;
            &lt;td&gt;Only two digits: zero and one. Most commonly used in computing. Everything on a computer is, at the lowest possible level, stored using the binary number system.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;8&lt;/td&gt;
            &lt;td&gt;Octal&lt;/td&gt;
            &lt;td&gt;Only eight digits are available: &lt;code&gt;0–7&lt;/code&gt;.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;16&lt;/td&gt;
            &lt;td&gt;Hexadecimal&lt;/td&gt;
            &lt;td&gt;Fifteen digits: &lt;code&gt;0–9&lt;/code&gt; and &lt;code&gt;a–f&lt;/code&gt;. Often used to express binary strings more compactly.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;60&lt;/td&gt;
            &lt;td&gt;Sexagesimal&lt;/td&gt;
            &lt;td&gt;How many seconds are in a minute? How many minutes in an hour? This is the basis of the modern circular coordinate system (degrees, minutes, and seconds).&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For this reason, when discussing number systems, we usually subscript a number with its base to clarify its value. Alternatively, you can prepend a number with a certain string (usually &lt;code&gt;0b&lt;/code&gt; for binary or &lt;code&gt;0x&lt;/code&gt;/&lt;code&gt;#&lt;/code&gt; for hexadecimal). So we'd write &lt;code&gt;579&lt;/code&gt; as &lt;code&gt;57910&lt;/code&gt;, or the binary number &lt;code&gt;1001&lt;/code&gt; as &lt;code&gt;10012&lt;/code&gt; (or &lt;code&gt;0b1001&lt;/code&gt;). Otherwise, if we were to merely write the number &lt;code&gt;1001&lt;/code&gt; without providing any context, nobody would know whether that's in binary, octal, decimal, hexadecimal, and so on because the digits &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt; are valid in all of those number systems, too!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: When not comparing number systems, we usually assume that a given number is in decimal unless otherwise noted, and thus the subscript is omitted.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Binary Number System (Base 2)
&lt;/h2&gt;

&lt;p&gt;So far so good—we're all familiar with decimal numbers because we use them everyday. But what's the deal with the binary number system?&lt;/p&gt;

&lt;p&gt;By definition, the &lt;strong&gt;binary number system&lt;/strong&gt; has a base of &lt;code&gt;2&lt;/code&gt;, and thus we can only work with two digits to compose numbers: &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt;. Technically speaking, we don't call these digits—they're called &lt;strong&gt;bits&lt;/strong&gt; in binary lingo.&lt;/p&gt;

&lt;p&gt;Each "bucket" in a binary string represents an increasing power of two: &lt;code&gt;2&lt;sup&gt;0&lt;/sup&gt;&lt;/code&gt;, &lt;code&gt;2&lt;sup&gt;1&lt;/sup&gt;&lt;/code&gt;, &lt;code&gt;2&lt;sup&gt;2&lt;/sup&gt;&lt;/code&gt;, and so on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fthe-binary-number-system%2Fbinary.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fthe-binary-number-system%2Fbinary.png" alt="The binary number system uses powers of two"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The leftmost bit is called the &lt;strong&gt;most significant bit (MSB)&lt;/strong&gt;, while the rightmost bit is called the &lt;strong&gt;least significant bit (LSB)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here are some examples of representing decimal numbers in the binary number system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zero: &lt;code&gt;010 = 02&lt;/code&gt;. Expansion: &lt;code&gt;0 (2&lt;sup&gt;0&lt;/sup&gt;)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;One: &lt;code&gt;110 = 12&lt;/code&gt;. Expansion: &lt;code&gt;1(2&lt;sup&gt;0&lt;/sup&gt;)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Two: &lt;code&gt;210 = 102&lt;/code&gt;. Expansion: &lt;code&gt;1(2&lt;sup&gt;1&lt;/sup&gt;) + 0(2&lt;sup&gt;0&lt;/sup&gt;)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Three: &lt;code&gt;310 = 112&lt;/code&gt;. Expansion: &lt;code&gt;1(2&lt;sup&gt;1&lt;/sup&gt;) + 1(2&lt;sup&gt;0&lt;/sup&gt;)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Four: &lt;code&gt;410 = 1002&lt;/code&gt;. Expansion: &lt;code&gt;1(2&lt;sup&gt;2&lt;/sup&gt;) + 0(2&lt;sup&gt;1&lt;/sup&gt;) + 0(2&lt;sup&gt;0&lt;/sup&gt;)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Five: &lt;code&gt;510 = 1012&lt;/code&gt;. Expansion: &lt;code&gt;1(2&lt;sup&gt;2&lt;/sup&gt;) + 0(2&lt;sup&gt;1&lt;/sup&gt;) + 1(2&lt;sup&gt;0&lt;/sup&gt;)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Like in the decimal number system, leading zeros are usually stripped from binary strings. The only exception is if you're working with a signed binary number system, where a leading zero indicates that a number is positive and a leading one indicates that it's negative.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Having learned the binary number system, you should now understand the joke from earlier:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There are &lt;code&gt;10&lt;/code&gt; types of people in the world: those who understand binary and those who don't.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here, we really mean the binary equivalent of two, which &lt;em&gt;looks&lt;/em&gt; like ten to our eyes when it's not properly subscripted: &lt;code&gt;102 = 1 × 2&lt;sup&gt;1&lt;/sup&gt; = 210&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Binary Is Close to the Hardware of a Computer
&lt;/h3&gt;

&lt;p&gt;Why do we bother with using the binary number system in the first place? Doesn't it seem like a whole lot of extra work to represent numbers in this manner when we could instead use the decimal number system? Well, yes—if you're writing these out by hand, it's certainly more work to represent (and manipulate) binary numbers.&lt;/p&gt;

&lt;p&gt;You may not see any point in using binary if you haven't learned about computer architecture at a low level. Internally, computers are nothing more than electrical circuits tied to hardware. Current either flows through a wire or doesn't—a &lt;strong&gt;binary state&lt;/strong&gt;. Likewise, computers use &lt;strong&gt;logic gates&lt;/strong&gt; (AND/OR/NOR/XOR) to control the flow of a program's execution, and these take binary inputs (&lt;code&gt;true&lt;/code&gt;/&lt;code&gt;false&lt;/code&gt;). The best way to represent these low-level interactions is to use the binary number system: &lt;code&gt;0&lt;/code&gt; means OFF (or &lt;code&gt;false&lt;/code&gt; in its logical form) and &lt;code&gt;1&lt;/code&gt; means ON (or &lt;code&gt;true&lt;/code&gt;).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: If the whole world were to agree to it, we could just as well instead treat &lt;code&gt;0&lt;/code&gt; as ON and &lt;code&gt;1&lt;/code&gt; as OFF. However, it just makes more sense to treat &lt;code&gt;0&lt;/code&gt; as OFF/false—after all, zero denotes the absence of a value. Hence, it's a natural candidate for representing things like falsehood or the lack of a current flowing through a wire.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Everything on your computer—the files you save and the software you install—is represented as nothing more than zeros and ones. But how is this possible?&lt;/p&gt;

&lt;h3&gt;
  
  
  The ASCII Standard
&lt;/h3&gt;

&lt;p&gt;Suppose you create a file on your computer and store some basic text in it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo Hello, Binary &amp;gt; file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the end of the day, your computer can't store a character like &lt;code&gt;H&lt;/code&gt;, &lt;code&gt;e&lt;/code&gt;, &lt;code&gt;l&lt;/code&gt;, or &lt;code&gt;o&lt;/code&gt; (or even the space between two words) &lt;em&gt;literally&lt;/em&gt;. Computers only know how to work with &lt;em&gt;binary&lt;/em&gt;. Thus, we need some way to convert these characters to numbers. And that's why the ASCII standard was introduced.&lt;/p&gt;

&lt;p&gt;Formally, ASCII is referred to as a &lt;strong&gt;character encoding standard&lt;/strong&gt;. Put more simply, it's a method of representing human-readable characters like &lt;code&gt;H&lt;/code&gt;, &lt;code&gt;e&lt;/code&gt;, &lt;code&gt;,&lt;/code&gt;, &lt;code&gt;?&lt;/code&gt;, and &lt;code&gt;9&lt;/code&gt; numerically so that computers can understand and use them like we do.&lt;/p&gt;

&lt;p&gt;Here is a typical &lt;a href="http://www.asciitable.com/" rel="noopener noreferrer"&gt;ASCII chart&lt;/a&gt; that you may have seen before:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fthe-binary-number-system%2Fascii.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fthe-binary-number-system%2Fascii.png" alt="An ASCII table showing characters and their numerical representations"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the ASCII standard, there are a total of 128 characters, each mapped to a unique number in binary (with an equivalent representation in decimal that we humans understand more naturally):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Arabic digits: &lt;code&gt;0-9&lt;/code&gt; (10)&lt;/li&gt;
&lt;li&gt;Capital letters of the English alphabet: &lt;code&gt;A-Z&lt;/code&gt; (26)&lt;/li&gt;
&lt;li&gt;Lowercase letters of the English alphabet: &lt;code&gt;a-z&lt;/code&gt; (26)&lt;/li&gt;
&lt;li&gt;Punctuation and special characters (66)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1 Character = 1 Byte
&lt;/h3&gt;

&lt;p&gt;In the decimal number system, we're used to working with digits. In binary, as we already saw, we're used to working with &lt;strong&gt;bits&lt;/strong&gt;. There's another special group of digits in binary that's worth mentioning: A sequence of eight bits is called a &lt;strong&gt;byte&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here are some examples of valid bytes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;00000000
10000000
11101011
11111111
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... and any other valid permutation of eight &lt;code&gt;0&lt;/code&gt;s and &lt;code&gt;1&lt;/code&gt;s that you can think of.&lt;/p&gt;

&lt;p&gt;Why is this relevant? Because on modern computers, &lt;strong&gt;characters are represented using bytes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Recall that the ASCII standard needs to support a total of &lt;strong&gt;128 characters&lt;/strong&gt;. So how many unique number can we represent with &lt;code&gt;8&lt;/code&gt; bits (a byte)?&lt;/p&gt;

&lt;p&gt;Well, using the product rule from combinatorics, we have eight "buckets," each with two possible values: either a &lt;code&gt;0&lt;/code&gt; or a &lt;code&gt;1&lt;/code&gt;. Thus, we have &lt;code&gt;2 × 2 × ... × 2 = 2&lt;sup&gt;8&lt;/sup&gt;&lt;/code&gt; possible values.&lt;/p&gt;

&lt;p&gt;In decimal, this is &lt;code&gt;2&lt;sup&gt;8&lt;/sup&gt; = 256&lt;/code&gt; possible values. By comparison, &lt;code&gt;2&lt;sup&gt;7&lt;/sup&gt; = 128&lt;/code&gt;. And &lt;code&gt;128&lt;/code&gt; happens to be the number of characters that we want to represent.&lt;/p&gt;

&lt;p&gt;So... That's weird, and seemingly wasteful, right? Why do we use &lt;code&gt;8&lt;/code&gt; bits (one byte) to represent a character when we could use &lt;code&gt;7&lt;/code&gt; bits instead and meet the precise character count that we need?&lt;/p&gt;

&lt;p&gt;Good question! We use bytes because &lt;strong&gt;it's not possible to evenly divide a group of &lt;code&gt;7&lt;/code&gt; bits&lt;/strong&gt;, making certain low-level computations difficult if we decide to use &lt;code&gt;7&lt;/code&gt; bits to represent a character. In contrast, a byte can be evenly split into powers of two:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;11101011
[1110][1011]
[11][10][10][11]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key takeaway here is that we only need one byte to store one character on a computer. This means that a string of five characters—like &lt;code&gt;Hello&lt;/code&gt;—occupies five bytes of space, with each byte being the numerical representation of the corresponding character per the ASCII standard.&lt;/p&gt;

&lt;p&gt;Remember the file we created earlier? Let's view its binary representation using the &lt;code&gt;xxd&lt;/code&gt; Unix tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;xxd -b file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;-b&lt;/code&gt; flag stands for binary. Here's the output that you'll get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;00000000: 01001000 01100101 01101100 01101100 01101111 00101100  Hello,
00000006: 00100000 01000010 01101001 01101110 01100001 01110010   Binar
0000000c: 01111001 00001010                                      y.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first line shows a sequence of six bytes, each corresponding to one character in &lt;code&gt;Hello,&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's decode the first two bytes using our knowledge of the binary number system and ASCII:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;01001000 = 1(2&lt;sup&gt;6&lt;/sup&gt;) + 1(2&lt;sup&gt;3&lt;/sup&gt;) = 7210&lt;/code&gt;. Per our ASCII table, this corresponds to &lt;code&gt;H&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;01100101 = 1(2&lt;sup&gt;6&lt;/sup&gt;) + 1(2&lt;sup&gt;5&lt;/sup&gt;) + 1(2&lt;sup&gt;2&lt;/sup&gt;) + 1(2&lt;sup&gt;0&lt;/sup&gt;) = 10110&lt;/code&gt;, which is &lt;code&gt;e&lt;/code&gt; in ASCII.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cool! Looks like the logic pans out. You can repeat this for all of the other bytes as well. Notice that on the second line, we have a leading space (from &lt;code&gt;Hello, Binary&lt;/code&gt;), represented as &lt;code&gt;2&lt;sup&gt;5&lt;/sup&gt; = 3210&lt;/code&gt; in ASCII (which is indeed &lt;code&gt;Space&lt;/code&gt; per the lookup table!).&lt;/p&gt;

&lt;p&gt;By the way, what's up with the numbers along the left-hand side of the output? What does &lt;code&gt;0000000c&lt;/code&gt; even mean? Time to explore another important number system!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hexademical Number System (Base 16)
&lt;/h2&gt;

&lt;p&gt;As I mentioned in the table from earlier, the hexadecimal number system is closely related to binary because it's often used to express binary numbers more compactly, instead of writing out a whole bunch of zeros and ones.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;hexadecimal number system&lt;/strong&gt; has a base of &lt;code&gt;16&lt;/code&gt;, meaning its digits range from &lt;code&gt;0–15&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: In technical terms, a hexadecimal digit is called a &lt;strong&gt;nibble&lt;/strong&gt;, but you'll commonly hear people just call them "hex digits."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is our first time encountering a number system whose digits are made up of more than two characters. How do we squeeze &lt;code&gt;10&lt;/code&gt;, &lt;code&gt;11&lt;/code&gt;, or &lt;code&gt;15&lt;/code&gt; into a single "bucket" or "slot" for a digit? To be clear, &lt;strong&gt;this is perfectly doable&lt;/strong&gt; if you have clear delimiters between digits. But in reality, that's not practical.&lt;/p&gt;

&lt;p&gt;Let's take a step back and consider a simple hexadecimal number:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;0x42&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What does this mean to us humans in our decimal number system? Well, all we have to do is multiply each digit by its corresponding power of &lt;code&gt;16&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;0x42 = 4(16&lt;sup&gt;1&lt;/sup&gt;) + 2(16&lt;sup&gt;0&lt;/sup&gt;) = 6410 + 210 = 6610&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Okay, so that's a simple hex number. Back to the problem at hand: How do we represent the hex digits &lt;code&gt;10&lt;/code&gt;, &lt;code&gt;11&lt;/code&gt;, and so on? Here's an example that's pretty confusing unless we introduce some alternative notation:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;0x15&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Is this a &lt;code&gt;15&lt;/code&gt; in a single slot or a &lt;code&gt;1&lt;/code&gt; and a &lt;code&gt;5&lt;/code&gt; in two separate slots? One way to make this less ambiguous is to use some kind of delimiter between slots, but again, that's not very practical:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;0x8[15]29&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The better solution that people came up with is to map &lt;code&gt;10–15&lt;/code&gt; to the the English letters &lt;code&gt;a–f&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Capitalization doesn't matter, so you can use &lt;code&gt;a-f&lt;/code&gt; or &lt;code&gt;A-F&lt;/code&gt;. Just be consistent.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here's an example of a hexadecimal number that uses one of these digits:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;0xf4&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And here's its expansion:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;0xf4 = 15(16&lt;sup&gt;1&lt;/sup&gt;) + 4(16&lt;sup&gt;0&lt;/sup&gt;) = 24010 + 410 = 24410&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;There's nothing magical about the hexadecimal number system—it works just like unary, binary, decimal, and others. All that's different is the base!&lt;/p&gt;

&lt;p&gt;Before we move on, let's revisit the output from earlier when we used &lt;code&gt;xxd&lt;/code&gt; on our sample file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;00000000: 01001000 01100101 01101100 01101100 01101111 00101100  Hello,
00000006: 00100000 01000010 01101001 01101110 01100001 01110010   Binar
0000000c: 01111001 00001010                                      y.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The numbers along the left-hand side mark the starting byte for each line of text on the far right. For example, the first line of text (&lt;code&gt;Hello,&lt;/code&gt;) ranges from byte #0 (&lt;code&gt;H&lt;/code&gt;) to byte #5 (&lt;code&gt;,&lt;/code&gt;). The next line is marked as &lt;code&gt;00000006&lt;/code&gt;, meaning we're now looking at bytes #6 through 11 (&lt;code&gt;B&lt;/code&gt; to &lt;code&gt;r&lt;/code&gt;). Finally, the last label should make sense now that you know the hexadecimal number system: &lt;code&gt;c&lt;/code&gt; maps to &lt;code&gt;12&lt;/code&gt;, meaning the byte that follows corresponds to the twelfth character in our file.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Convert Between Binary and Hexadecimal
&lt;/h3&gt;

&lt;p&gt;Now that we know a bit about binary and hexadecimal, let's look at how we can convert between the two systems.&lt;/p&gt;

&lt;h4&gt;
  
  
  Binary to Hexadecimal
&lt;/h4&gt;

&lt;p&gt;Say you're given this binary string and you'd like to represent it in hexadecimal:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;011011100101&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;While at first this may seem like a pretty difficult task, it's actually &lt;strong&gt;very easy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let's do a bit of a thought exercise:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In the hexadecimal number system, we have &lt;code&gt;16&lt;/code&gt; digits from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;15&lt;/code&gt;. Over in binary land, how many bits do we need to represent these &lt;code&gt;16&lt;/code&gt; values?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The answer is four because &lt;code&gt;2&lt;sup&gt;4&lt;/sup&gt; = 16&lt;/code&gt;. With four "buckets," we can create the numbers zero (&lt;code&gt;0000&lt;/code&gt;), one (&lt;code&gt;0001&lt;/code&gt;), ten (&lt;code&gt;1010&lt;/code&gt;), all the way up to fifteeen (&lt;code&gt;1111&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;This means that when you're given a binary string, all you have to do is &lt;strong&gt;split it into groups of four bits&lt;/strong&gt; and evaluate them to convert binary to hexadecimal!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;011011100101
[0110][1110][0101]
6 14 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we just replace &lt;code&gt;10–15&lt;/code&gt; with &lt;code&gt;a-f&lt;/code&gt; and we're done: &lt;code&gt;0x6e5&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Hexadecimal to Binary
&lt;/h4&gt;

&lt;p&gt;What about the reverse process? How do you convert a hexadecimal number to binary?&lt;/p&gt;

&lt;p&gt;Say you're given the hexadecimal number &lt;code&gt;0xad&lt;/code&gt;. What do we know about each hexadecimal digit? Well, from our earlier thought exercise, we know that four bits = one hex digit. So now we just have to convert each indiviual digit to its &lt;code&gt;4&lt;/code&gt;-bit binary representation and then stick each group together!&lt;/p&gt;

&lt;p&gt;&lt;code&gt;0xad = 0b10101101&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Super easy, just like I promised.&lt;/p&gt;

&lt;h3&gt;
  
  
  Real-World Application: Representing Colors with RGB/Hex
&lt;/h3&gt;

&lt;p&gt;While we're on the topic of binary and hexadecimal, it's worth taking a look at one real-world use case for the things we've learned so far: &lt;strong&gt;RGB and hex colors&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Colors have three components: red, green, and blue (RGB). With LED (light-emitting diode) displays, each pixel is really split into these three components using a color diode. If a color component is set to &lt;code&gt;0&lt;/code&gt;, then it's effectively turned off. Otherwise, its intensity is modulated between &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;255&lt;/code&gt;, giving us a color format like &lt;code&gt;rgb(0-255, 0-255, 0-255)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's consider this hex color: &lt;code&gt;#4287f5&lt;/code&gt;. What is it in the RGB format?&lt;/p&gt;

&lt;p&gt;Well, we need to split this hex string evenly between red, green, and blue. That's two digits per color:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[42][87][f5]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, we simply interpret the decimal equivalent for each part:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Red&lt;/strong&gt;: &lt;code&gt;4216 = 4(16&lt;sup&gt;1&lt;/sup&gt;) + 2(16&lt;sup&gt;0&lt;/sup&gt;) = 66&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Green&lt;/strong&gt;: &lt;code&gt;8716 = 8(16&lt;sup&gt;1&lt;/sup&gt;) + 7(16&lt;sup&gt;0&lt;/sup&gt;) = 135&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blue&lt;/strong&gt;: &lt;code&gt;f516 = 15(16&lt;sup&gt;1&lt;/sup&gt;) + 5(16&lt;sup&gt;0&lt;/sup&gt;) = 245&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That means &lt;code&gt;#4287f5&lt;/code&gt; is really &lt;code&gt;rgb(66, 135, 245)&lt;/code&gt;! You can verify this using a &lt;a href="https://www.w3schools.com/colors/colors_converter.asp" rel="noopener noreferrer"&gt;Color Converter&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fthe-binary-number-system%2Fcolor-converter.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fthe-binary-number-system%2Fcolor-converter.png" alt="A color converter verifying that #4287f5 is really rgb(66, 135, 245)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For practice, let's convert this to binary as well. I'll mark the groups of four bits to make it easier to see how I did this (note: you can also convert from the decimal RGB representation if you want to):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;0x4287f5 = 0b[0100][0010][1000][0111][1111][0101]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, two groups of four bits will represent one component of the color (red/green/blue):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;0b[01000010][10000111][11110101]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Notice that each color &lt;em&gt;component&lt;/em&gt; takes up a byte (&lt;code&gt;8&lt;/code&gt; bits) of space.&lt;/p&gt;

&lt;h4&gt;
  
  
  How Many Colors Are There?
&lt;/h4&gt;

&lt;p&gt;As an additional exercise, how many unique colors can you possibly have in the modern RGB format?&lt;/p&gt;

&lt;p&gt;We know that each component (red/green/blue) is represented using one byte (&lt;code&gt;8&lt;/code&gt; bits). So the colors we're used to are really &lt;code&gt;24&lt;/code&gt;-bit colors.&lt;/p&gt;

&lt;p&gt;That means there are a whopping &lt;code&gt;2&lt;sup&gt;24&lt;/sup&gt; = 16,777,216&lt;/code&gt; possible unique colors that you can generate using hex/rgb! The &lt;code&gt;24&lt;/code&gt;-bit color system is known simply as &lt;strong&gt;truecolor&lt;/strong&gt;. And as you can see, it's capable of representing millions of colors.&lt;/p&gt;

&lt;p&gt;Note that you could just as well have performed this calculation using hex: &lt;code&gt;#4287f5&lt;/code&gt;. There are six slots, each capable of taking on a value from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;f&lt;/code&gt;. That gives us a total of &lt;code&gt;16 × 16 × ... × 16 = 16&lt;sup&gt;6&lt;/sup&gt; = 16,777,216&lt;/code&gt; values—the same result as before.&lt;/p&gt;

&lt;p&gt;Or, if you're using the decimal RGB format, the math still pans out: &lt;code&gt;256 × 256 × 256 = 16,777,216&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  What Are 8-Bit Colors?
&lt;/h4&gt;

&lt;p&gt;On older systems with limited memory, colors were represented using just eight bits (one byte). These &lt;strong&gt;8-bit colors&lt;/strong&gt; had a very limited palette, which meant that most computer graphics didn't have gradual color transitions (so images looked very pixelated/grainy). With only &lt;code&gt;8&lt;/code&gt; bits to work with, you are limited to just &lt;code&gt;2&lt;sup&gt;8&lt;/sup&gt; = 256&lt;/code&gt; colors!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fthe-binary-number-system%2F8-bit.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fthe-binary-number-system%2F8-bit.png" alt="An 8-bit color palette"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Naturally, you may be wondering: How did they split &lt;code&gt;8&lt;/code&gt; bits evenly among red, green, and blue? After all, &lt;code&gt;8&lt;/code&gt; isn't divisible by three!&lt;/p&gt;

&lt;p&gt;Well, the answer is that &lt;em&gt;they didn't&lt;/em&gt;. The process of splitting these bits among the color components is called &lt;a href="https://en.wikipedia.org/wiki/8-bit_color#Color_quantization" rel="noopener noreferrer"&gt;color quantization&lt;/a&gt;, and the most common method (known as &lt;strong&gt;8-bit truecolor&lt;/strong&gt;) split the bits as 3-3-2 red-green-blue. Apparently, this is because the human eye is less sensitive to blue light than the other two, and thus it simply made sense to distribute the bits heavily in favor of red and green and leave blue with one less bit to work with.&lt;/p&gt;

&lt;h2&gt;
  
  
  Signed Binary Number System: Two's Complement
&lt;/h2&gt;

&lt;p&gt;Now that we've covered decimal, binary, and hexadecimal, I'd like us to revisit the binary number system and learn how to represent negative numbers. Because so far, we've only looked at positive numbers. How do we store the negative sign?&lt;/p&gt;

&lt;p&gt;To give us some context, I'll assume that we're working with standard &lt;code&gt;32&lt;/code&gt;-bit integers that most (all?) modern computers support. We could just as well look at &lt;code&gt;64&lt;/code&gt;-bit or &lt;code&gt;N&lt;/code&gt;-bit integers, but it's good to have a concrete basis for a discussion.&lt;/p&gt;

&lt;p&gt;If we have &lt;code&gt;32&lt;/code&gt; bits to fiddle with, that means we can represent a total of &lt;code&gt;2&lt;sup&gt;32&lt;/sup&gt; = 4,294,967,296&lt;/code&gt; (4 billion) numbers. More generally, if you have &lt;code&gt;N&lt;/code&gt; bits to work with, you can represent &lt;code&gt;2&lt;sup&gt;N&lt;/sup&gt;&lt;/code&gt; values. But we'd like to split this number range evenly between negatives and positives.&lt;/p&gt;

&lt;p&gt;Positive or negative... positive or negative. One thing or another thing—ring a bell? That sounds like it's binary in nature. And hey—we're already using binary to &lt;em&gt;store&lt;/em&gt; our numbers! Why not reserve just a single bit to represent &lt;em&gt;the sign&lt;/em&gt;? We can have the most significant (leading) bit be a &lt;code&gt;0&lt;/code&gt; when our number is positive and a &lt;code&gt;1&lt;/code&gt; when it's negative!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This is once again one of those situations where you could just as well do the opposite, except you'd have to convince the whole world to follow your chosen convention.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Earlier, when we were first looking at the binary number systems, I mentioned that you can strip leading zeros because they are meaningless. This is true except when you actually care about distinguishing between positive and negative numbers in binary. Now, we need to be careful—if you strip all leading zeros, you my be left with a leading &lt;code&gt;1&lt;/code&gt;, and that would imply that your number is negative (in a signed number system).&lt;/p&gt;

&lt;p&gt;You can think of two's complement as a new &lt;em&gt;perspective&lt;/em&gt; or lens through which we look at binary numbers. The number &lt;code&gt;1002&lt;/code&gt; ordinarily means &lt;code&gt;410&lt;/code&gt; if we don't care about its sign (i.e., we assume it's &lt;strong&gt;unsigned&lt;/strong&gt;). But if we do care, then we have to ask ourselves (or whoever provided us this number) whether it's a signed number.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Does Two's Complement Work?
&lt;/h3&gt;

&lt;p&gt;What does a leading &lt;code&gt;1&lt;/code&gt; actually represent when you expand a signed binary number, and how do we convert a positive number to a negative one, and vice versa?&lt;/p&gt;

&lt;p&gt;For example, suppose we're looking at the number &lt;code&gt;2210&lt;/code&gt;, which is represented like this in unsigned binary:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;101102&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Since we're looking at signed binary, we need to pad this number with an extra &lt;code&gt;0&lt;/code&gt; out in front (or else a leading &lt;code&gt;1&lt;/code&gt; would imply that it's negative):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;0101102&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Okay, so this is positive &lt;code&gt;2210&lt;/code&gt;. How do we represent &lt;code&gt;-2210&lt;/code&gt; in binary?&lt;/p&gt;

&lt;p&gt;There are two ways we can do this: the intuitive (longer) approach and the "shortcut" approach. I'll show you both, but I'll start with the more intuitive one.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Intuitive Approach: What Does a Leading 1 Denote?
&lt;/h4&gt;

&lt;p&gt;Given an &lt;code&gt;N&lt;/code&gt;-bit binary string, a leading &lt;code&gt;1&lt;/code&gt; in two's complement represents &lt;code&gt;-1&lt;/code&gt; multiplied by its corresponding power of two (&lt;code&gt;2&lt;sup&gt;N-1&lt;/sup&gt;&lt;/code&gt;). A digit of &lt;code&gt;1&lt;/code&gt; in any other slot represents &lt;code&gt;+1&lt;/code&gt; times its corresponding power of two.&lt;/p&gt;

&lt;p&gt;For example, the signed number &lt;code&gt;110102&lt;/code&gt; has this expansion:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;110102 = -1(2&lt;sup&gt;4&lt;/sup&gt;) + 1(2&lt;sup&gt;3&lt;/sup&gt;) + 1(2&lt;sup&gt;1&lt;/sup&gt;) = -1610 + 810 + 210 = -610&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We simply treat the leading &lt;code&gt;1&lt;/code&gt; as a negative, and that changes the resulting sum in our expansion.&lt;/p&gt;

&lt;h4&gt;
  
  
  Two's Complement Shortcut: Flip the Bits and Add a 1
&lt;/h4&gt;

&lt;p&gt;To convert a number represented in two's complement binary to its opposite sign, follow these two simple steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Flip all of the bits (&lt;code&gt;0&lt;/code&gt; becomes &lt;code&gt;1&lt;/code&gt; and vice versa).&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;1&lt;/code&gt; to the result.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For example, let's convert &lt;code&gt;4310&lt;/code&gt; to &lt;code&gt;-4310&lt;/code&gt; in binary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+43 in binary: 0101011
Flipped:       1010100
Add one:       1010101
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What is this number? It should be &lt;code&gt;-4310&lt;/code&gt;, so let's expand it by hand to verify:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;-1(2&lt;sup&gt;6&lt;/sup&gt;) + 1(2&lt;sup&gt;4&lt;/sup&gt;) + 1(2&lt;sup&gt;2&lt;/sup&gt;) + 1(2&lt;sup&gt;0&lt;/sup&gt;) = -6410 + 1610 + 410 + 110 = -43&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Sure enough, the process works!&lt;/p&gt;

&lt;h4&gt;
  
  
  How Many Signed Binary Numbers Are There?
&lt;/h4&gt;

&lt;p&gt;We've seen that in a signed binary system, the most significant bit is reserved for the sign. What does this do to our number range? Effectively, it halves it!&lt;/p&gt;

&lt;p&gt;Let's consider &lt;code&gt;32&lt;/code&gt;-bit integers to give us a concrete basis for discussion. Whereas before we had &lt;code&gt;32&lt;/code&gt; bits to work with for the magnitude of an unsigned number, we now have only &lt;code&gt;31&lt;/code&gt; for the magnitude of a signed number:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Unsigned magnitude bits:  [31 30 29 ... 0]
Signed magnitude bits:    31 [30 29 ... 0]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We went from having &lt;code&gt;2&lt;sup&gt;32&lt;/sup&gt;&lt;/code&gt; numbers to &lt;code&gt;2&lt;sup&gt;31&lt;/sup&gt;&lt;/code&gt; positive and negative numbers, which is precisely half of what we started with!&lt;/p&gt;

&lt;p&gt;More generally, if you have an &lt;code&gt;N&lt;/code&gt;-bit signed binary string, there are going to be &lt;code&gt;2&lt;sup&gt;N&lt;/sup&gt;&lt;/code&gt; values, split evenly between &lt;code&gt;2&lt;sup&gt;N-1&lt;/sup&gt;&lt;/code&gt; positives and &lt;code&gt;2&lt;sup&gt;N-1&lt;/sup&gt;&lt;/code&gt; negatives.&lt;/p&gt;

&lt;p&gt;Notice that the number zero gets bunched in with the positives and not the negatives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Signed zero:  0  0  0  0 ... 0 0 0 0
Bits:        31 30 29 28 ... 3 2 1 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we're about to see, this has an interesting consequence.&lt;/p&gt;

&lt;h4&gt;
  
  
  What Is the Largest Signed 32-bit Integer?
&lt;/h4&gt;

&lt;p&gt;The largest signed 32-bit integer is positive, meaning its leading bit is a zero. So we just need to maximize the remaining bits to get the largest possible value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Num:      0  1  1  1 ... 1
Bits:    31 30 29 28 ... 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is &lt;code&gt;2&lt;sup&gt;31&lt;/sup&gt; - 1&lt;/code&gt;, which is &lt;code&gt;2,147,483,647&lt;/code&gt;. In Java, this number is stored in &lt;code&gt;Integer.MAX_VALUE&lt;/code&gt;, and in C++, it's &lt;code&gt;std::numeric_limits::max()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;More generally, for an &lt;code&gt;N&lt;/code&gt;-bit system, the largest signed integer is &lt;code&gt;2&lt;sup&gt;N-1&lt;/sup&gt;-1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Why did we subtract a one at the end? Because as I mentioned in the previous section, the number zero gets grouped along with the positives when we split our number range:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Signed zero:  0  0  0  0 ... 0 0 0 0
Bits:        31 30 29 28 ... 3 2 1 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So to get our largest signed integer, we need to subtract one—we've effectively "lost" a magnitude of one.&lt;/p&gt;

&lt;h5&gt;
  
  
  Real-World Application: Video Game Currency
&lt;/h5&gt;

&lt;p&gt;In video games like RuneScape that use &lt;code&gt;32&lt;/code&gt;-bit signed integers to represent in-game currency, the max "cash stack" that you can have caps out at exactly &lt;code&gt;2&lt;sup&gt;31&lt;/sup&gt; - 1&lt;/code&gt;, which is roughly 2.1 billion.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fthe-binary-number-system%2Fmax-cash-stack.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.aleksandrhovhannisyan.com%2Fassets%2Fimg%2Fposts%2Fthe-binary-number-system%2Fmax-cash-stack.png" alt="The max cash stack you can have in Runescape is 2147m, or 2.1 billion."&gt;&lt;/a&gt;&lt;/p&gt;
Image source: &lt;a href="https://www.youtube.com/watch?v=c2ZsPPDH08g" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;



&lt;p&gt;Now you know why! If you're wondering why they don't just use unsigned ints, it's because RuneScape runs on Java, and &lt;a href="https://stackoverflow.com/questions/9854166/declaring-an-unsigned-int-in-java" rel="noopener noreferrer"&gt;Java doesn't support unsigned ints&lt;/a&gt; (except in SE 8+).&lt;/p&gt;

&lt;h4&gt;
  
  
  What Is the Smallest Signed 32-bit Integer?
&lt;/h4&gt;

&lt;p&gt;This occurs when we set the leading bit to be a &lt;code&gt;1&lt;/code&gt; and set all remaining bits to be a &lt;code&gt;0&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;Num:      1  0  0  0 ... 0
Bits:    31 30 29 28 ... 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why? Because recall that in the expansion of negative numbers in two's complement binary, the leading &lt;code&gt;1&lt;/code&gt; is a &lt;code&gt;-1&lt;/code&gt; times &lt;code&gt;2&lt;sup&gt;N-1&lt;/sup&gt;&lt;/code&gt;, and a &lt;code&gt;1&lt;/code&gt; in any other position will be treated as &lt;code&gt;+1&lt;/code&gt; times its corresponding power of two. Since we want the smallest negative number, we don't want any positive terms, as those take away from our magnitude. So we set all remaining bits to be &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer&lt;/strong&gt;: &lt;code&gt;-2&lt;sup&gt;31&lt;/sup&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In Java, this value is stored in &lt;code&gt;Integer.MIN_VALUE&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In C++, it's in &lt;code&gt;std::numeric_limits::min()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Generalizing things once again, if we have an &lt;code&gt;N&lt;/code&gt;-bit system, the smallest representable signed int is &lt;code&gt;-2&lt;sup&gt;N-1&lt;/sup&gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Arithmetic in the Binary Number System
&lt;/h2&gt;

&lt;p&gt;Spoiler: Adding, subtracting, multiplying, and dividing numbers in the binary number system is &lt;strong&gt;exactly the same&lt;/strong&gt; as it is in decimal!&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding Binary Numbers
&lt;/h3&gt;

&lt;p&gt;We'll first revisit what we learned in elementary school for decimal numbers and then look at how to add two binary numbers.&lt;/p&gt;

&lt;p&gt;To add two numbers in the decimal number system, you stack them on top of one another visually and work your way from right to left, adding two digits and "carrying the one" as needed.&lt;/p&gt;

&lt;p&gt;Now you should know what carrying the one really means: When you run out of digits to represent something in your fixed-base number system (e.g., &lt;code&gt;13&lt;/code&gt; isn't a digit in base &lt;code&gt;10&lt;/code&gt;), you represent the part that you can in the current digits place and move over to the next power of your base (the "column" to the left of your current one).&lt;/p&gt;

&lt;p&gt;For example, let's add &lt;code&gt;24&lt;/code&gt; and &lt;code&gt;18&lt;/code&gt; in decimal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  24
+ 18
————
  42
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We first add the &lt;code&gt;4&lt;/code&gt; and &lt;code&gt;8&lt;/code&gt; to get &lt;code&gt;12&lt;/code&gt;, which is not a digit we support in the decimal number system. So we represent the part that we can (&lt;code&gt;2&lt;/code&gt;) and carry the remaining value (ten) over to the next column as a &lt;code&gt;1&lt;/code&gt; (&lt;code&gt;1 × 10&lt;sup&gt;1&lt;/sup&gt; = 1010&lt;/code&gt;). There, we have &lt;code&gt;1 + 2 + 1 = 4&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;      1  &amp;lt;-- carried
      24
    + 18
————————
      42
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's add these same two numbers (&lt;code&gt;2410&lt;/code&gt; and &lt;code&gt;1810&lt;/code&gt;) using the binary number system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  11000
+ 10010
———————
 101010
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We work from right to left:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ones place: &lt;code&gt;0 + 0 = 0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Twos place: &lt;code&gt;0 + 1 = 1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Fours place: &lt;code&gt;0 + 0 = 0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Eights place: &lt;code&gt;1 + 0 = 1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Sixteens place: &lt;code&gt;1 + 1 = 102&lt;/code&gt; (two)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last step deserves some clarification: When we try to add the two ones, we get &lt;code&gt;12 + 12 = 102&lt;/code&gt; (two), so we put a &lt;code&gt;0&lt;/code&gt; in the current column and carry over the &lt;code&gt;1&lt;/code&gt; to the next power of two, where we have a bunch of implicit leading zeros:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;               1      &amp;lt;-- carry bits
0000  ...    00011000
0000  ...  + 00010010
—————————————————————
0000  ...    00101010
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In that column, &lt;code&gt;1 (carried) + 0(implicit) = 1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If we expand the result, we'll find that it's the same answer we got over in decimal:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;1(2&lt;sup&gt;5&lt;/sup&gt;) + 1(2&lt;sup&gt;3&lt;/sup&gt;) + 1(2&lt;sup&gt;1&lt;/sup&gt;) = 32 + 8 + 2 = 4210&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let's look at one more example to get comfortable with carrying bits in binary addition: &lt;code&gt;2210 + 1410&lt;/code&gt;, which we know to be &lt;code&gt;3610&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;  10110
+ 01110
———————
 100100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Something interesting happens when we look at the twos place (the &lt;code&gt;2&lt;sup&gt;1&lt;/sup&gt;&lt;/code&gt; column): We add &lt;code&gt;12&lt;/code&gt; to &lt;code&gt;12&lt;/code&gt;, giving us two (&lt;code&gt;102&lt;/code&gt;), so we put a zero in the &lt;code&gt;2&lt;sup&gt;1&lt;/sup&gt;&lt;/code&gt; column and carry the remaining one.&lt;/p&gt;

&lt;p&gt;Now we have three ones in the &lt;code&gt;2&lt;sup&gt;2&lt;/sup&gt;&lt;/code&gt; column: &lt;code&gt;12(carried) + 12(operand1) + 12(operand2) = 112&lt;/code&gt; (three). So we put a one in the &lt;code&gt;2&lt;sup&gt;2&lt;/sup&gt;&lt;/code&gt; column and carry a one yet again. Rinse and repeat!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;               1111    &amp;lt;-- carry bits
0000  ...    00010110
0000  ...  + 00001110
—————————————————————
0000  ...    00100100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once again, it's a good idea to expand the result so you can verify your work:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;1(2&lt;sup&gt;5&lt;/sup&gt;) + 1(2&lt;sup&gt;2&lt;/sup&gt;) = 3210 + 410 = 3610&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: We've only looked at examples of adding two binary numbers, but you could just as well stack &lt;code&gt;x&lt;/code&gt; numbers on top of one another and add them in binary, just like you would in decimal. How far ahead you need to carry your ones depends on the result that you get in a particular column, represented as a binary string.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Subtracting Binary Numbers
&lt;/h3&gt;

&lt;p&gt;Subtraction is addition with a negative operand: &lt;code&gt;a - b = a + (-b)&lt;/code&gt;. Now that we know how to represent negative numbers in the binary system thanks to two's complement, this should be a piece of cake: &lt;strong&gt;negate the second operand and perform addition&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, what's &lt;code&gt;1210 - 2610&lt;/code&gt;? In decimal, we know this to be &lt;code&gt;-1410&lt;/code&gt;. Over in binary, we know that &lt;code&gt;1210&lt;/code&gt; is &lt;code&gt;01100&lt;/code&gt;. What about &lt;code&gt;-2610&lt;/code&gt;? We'll represent that using two's complement.&lt;/p&gt;

&lt;p&gt;We start by first representing &lt;code&gt;2610&lt;/code&gt; in binary:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;+2610 = 0110102&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now we negate it by flipping the bits and adding one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;26 in binary: 011010
Flipped:      100101
Add one:      100110  = -26
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Stack up your operands and add them like we did before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     11    &amp;lt;-- carry bits
    001100
  + 100110
——————————
    110010
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that the result has a leading one, which we know denotes a negative number in signed binary. So we at least got the sign part right! Let's check the magnitude:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;-1(2&lt;sup&gt;5&lt;/sup&gt;) + 1(2&lt;sup&gt;4&lt;/sup&gt;) + 1(2&lt;sup&gt;1&lt;/sup&gt;) = -3210 + 1610 + 210 = -1410&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;See what I mean? Adding and subtracting numbers in the binary number system is just as easy as it is over in decimal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multiplying Binary Numbers
&lt;/h3&gt;

&lt;p&gt;Let's remind ourselves how we multiply numbers in decimal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  21
x 12
————
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember the process? We multiply the &lt;code&gt;2&lt;/code&gt; by each digit in the first multiplicand and write out the result under the bar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  21
x 12
————
  42
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we move on to the &lt;code&gt;1&lt;/code&gt; in &lt;code&gt;12&lt;/code&gt; and repeat the process, but adding a &lt;code&gt;0&lt;/code&gt; in the right column of the result. Add the two intermediate products to get the answer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   21
x  12
—————
   42
+ 210
—————
  252
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Guess what? The process is exactly the same in the binary number system!&lt;/p&gt;

&lt;p&gt;Let's multiply these same two numbers in binary. They are &lt;code&gt;2110 = 010101&lt;/code&gt; and &lt;code&gt;1210 = 01100&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;   010101
x   01100
—————————
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Obviously, this is going to be more involved in binary since we're working with bits (and thus longer strings), but the logic is still the same. In fact, beyond having to write out so many intermediate results, we actually have it much easier over in binary. Whenever a digit is &lt;code&gt;1&lt;/code&gt;, you simply copy down the first multiplicand, padded with zeros. Whenever it's a zero times the first multiplicand, the result is zero!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      010101
x      01100
————————————
      000000
     0000000
    01010100
   010101000
+ 0000000000
————————————
  0011111100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expanding this in binary, we get:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;00111111002 = 1(2&lt;sup&gt;7&lt;/sup&gt;) + 1(2&lt;sup&gt;6&lt;/sup&gt;) + 1(2&lt;sup&gt;5&lt;/sup&gt;) + 1(2&lt;sup&gt;4&lt;/sup&gt;) + 1(2&lt;sup&gt;3&lt;/sup&gt;) + 1(2&lt;sup&gt;2&lt;/sup&gt;) = 25210&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Easy peasy. The same process applies regardless of whether your multiplicands are signed or unsigned.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dividing Binary Numbers
&lt;/h3&gt;

&lt;p&gt;Let's divide &lt;code&gt;12610&lt;/code&gt; by &lt;code&gt;1210&lt;/code&gt; using long division:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    0 1 0 . 5
   _______
12 |1 2 6
  - 1 2
   ————
      0 6
    -   0
   ——————
        6 0
      - 6 0
      —————
          0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Answer: &lt;code&gt;10.5&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now let's repeat the process over in the binary number system. Note that I'm going to strip leading zeros to make my life easier since we're working with two unsigned numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
      _______
1100 |1111110
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take things one digit at a time, and &lt;a href="https://www.youtube.com/watch?v=VKemv9u40gc" rel="noopener noreferrer"&gt;reference this useful YouTube video&lt;/a&gt; if you get stuck:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;         0 0 0 1 0 1 0 . 1
        ______________
1 1 0 0 |1 1 1 1 1 1 0 . 0
        -0
        ——
         1 1
        -  0
        ————
         1 1 1
        -    0
        ——————
         1 1 1 1
       - 1 1 0 0
        ————————
             1 1 1
          -      0
        ——————————
             1 1 1 1
           - 1 1 0 0
           —————————
             0 0 1 1 0
             -       0
             —————————
                 1 1 0
                 -   0
                 —————
                 1 1 0 0
              -  1 1 0 0
                 ———————
                 0 0 0 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Answer: &lt;code&gt;01010.1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What does the &lt;code&gt;1&lt;/code&gt; to the right of the decimal point represent? Well, in the decimal number system, anything to the right of the decimal point represents a negative power of ten: &lt;code&gt;10&lt;sup&gt;-1&lt;/sup&gt;&lt;/code&gt;, &lt;code&gt;10&lt;sup&gt;-2&lt;/sup&gt;&lt;/code&gt;, and so on. &lt;/p&gt;

&lt;p&gt;As you may have guessed, in the binary number system, these are &lt;code&gt;2&lt;sup&gt;-1&lt;/sup&gt;&lt;/code&gt;, &lt;code&gt;2&lt;sup&gt;-2&lt;/sup&gt;&lt;/code&gt;, and so on. So &lt;code&gt;.1&lt;/code&gt; above really means &lt;code&gt;1(2&lt;sup&gt;-1&lt;/sup&gt;)&lt;/code&gt;, which is &lt;code&gt;1 / 2 = 0.510&lt;/code&gt; in decimal. And of course, the part in front of the decimal point evaluates to &lt;code&gt;1010&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That gives us &lt;code&gt;1010 + 0.510 = 10.5&lt;/code&gt;. So our answer using binary long division is &lt;strong&gt;exactly the same&lt;/strong&gt; as the one we got over in decimal!&lt;/p&gt;

&lt;h3&gt;
  
  
  Integer Overflow and Underflow in Binary
&lt;/h3&gt;

&lt;p&gt;What happens if you try to add one to the largest representable &lt;code&gt;N&lt;/code&gt;-bit signed integer?&lt;/p&gt;

&lt;p&gt;For example, if &lt;code&gt;N = 32&lt;/code&gt;, we're really asking what happens if we try adding one to the largest representable &lt;code&gt;32&lt;/code&gt;-bit signed int.&lt;/p&gt;

&lt;p&gt;Let's give it a shot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    0111...11111
  + 0000...00001
————————————————
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the rightmost column, we'll get &lt;code&gt;12 + 12 = 102&lt;/code&gt;, so that's a zero carry a one. But as a result, all of the remaining additions will be &lt;code&gt;12 + 12&lt;/code&gt; since we'll always carry a one until we get to the leading bit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    11111111111  &amp;lt;-- carry bits
    0111...11111     (2^{N-1} - 1)
  + 0000...00001     (1)
————————————————
    1000...00000     (-2^{N-1})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And what number is that in signed binary? Hmm... Looks like it's the smallest representable negative number! What we've observed here is called &lt;strong&gt;integer overflow&lt;/strong&gt;. When you try to go past the largest representable signed integer in a given &lt;code&gt;N&lt;/code&gt;-bit system, the result &lt;em&gt;overflows&lt;/em&gt; or &lt;em&gt;wraps around&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;What if we try to subtract one from the smallest representable &lt;code&gt;N&lt;/code&gt;-bit signed integer? First, we'll represent &lt;code&gt;-110&lt;/code&gt; as a signed integer in binary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 in binary: 0000...00001
Flipped:     1111...11110
Add one:     1111...11111  &amp;lt;-- -1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's add this to the smallest representable signed integer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   1             &amp;lt;-- carry bits
    1000...00000     (-2^{N-1})
  + 1111...11111     (-1)
————————————————
  1|0111...11111     (2^{N-1} - 1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that the result carries an additional bit over, yielding a result that has &lt;code&gt;N+1&lt;/code&gt; bits. But our system only supports &lt;code&gt;N&lt;/code&gt; bits, so that leading &lt;code&gt;1&lt;/code&gt; is actually discarded. The result is the largest representable &lt;code&gt;N&lt;/code&gt;-bit signed integer, and this is known as &lt;strong&gt;integer underflow&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Overflow and underflow are things you should be mindful of in programs that are performing lots of computations, as you may end up getting unexpected results.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Binary Number System: Additional Topics for Exploration
&lt;/h2&gt;

&lt;p&gt;That about does it for this introduction to the binary number system! We took a pretty in-depth look at decimal, binary, and hexadecimal, and I hope you now have a greater appreciation for the binary number system and the role that it plays in computing.&lt;/p&gt;

&lt;p&gt;In reality, there's much more to learn beyond what we covered here. If you're curious, I encourage you to look into &lt;a href="https://en.wikipedia.org/wiki/Floating-point_arithmetic" rel="noopener noreferrer"&gt;representing floating point numbers in binary&lt;/a&gt; using the IEE754 format.&lt;/p&gt;

&lt;p&gt;I hope you found this helpful! If you struggled with anything in particular, please let me know and I'll try my best to help you out.&lt;/p&gt;

</description>
      <category>computerscience</category>
    </item>
    <item>
      <title>Semantic HTML: Building a More Accessible Web</title>
      <dc:creator>Aleksandr Hovhannisyan</dc:creator>
      <pubDate>Fri, 31 Jul 2020 12:23:11 +0000</pubDate>
      <link>https://dev.to/aleksandrhovhannisyan/semantic-html-building-a-more-accessible-web-4n6p</link>
      <guid>https://dev.to/aleksandrhovhannisyan/semantic-html-building-a-more-accessible-web-4n6p</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This article was originally published &lt;a href="https://www.aleksandrhovhannisyan.com/blog/dev/semantic-html-accessibility/"&gt;on my blog&lt;/a&gt;. It has since been updated on my site.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Semantic HTML&lt;/strong&gt; isn't just some buzzword that people throw around for no good reason—it's an important concept in front-end development that gives meaning to your HTML markup. When you use semantic HTML, you not only make it easier for sighted users to understand your markup, but you also help &lt;em&gt;unsighted&lt;/em&gt; users who rely on screen readers to make sense of your &lt;em&gt;content organization&lt;/em&gt;. This is just one part of creating a more accessible user experience.&lt;/p&gt;

&lt;p&gt;In this guide, we'll take a look at everything you need to know about building a more accessible user experience through semantic HTML. We'll also touch on some more general accessibility best practices towards the end of the guide.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes HTML Accessible?
&lt;/h2&gt;

&lt;p&gt;Accessibility is a hot topic in front-end development, yet it's also frequently overlooked or executed poorly, even on some of the world's most popular apps and websites. Developers tend to design a user experience with &lt;em&gt;sighted&lt;/em&gt; users in mind, forgetting about users who rely on screen readers. Worse still, they may end up using color combinations that have too low of a contrast, or violating a number of other HTML accessibility best practices.&lt;/p&gt;

&lt;p&gt;Accessible HTML conveys meaning and content organization to both sighted and unsighted users. Moreover, it uses the right HTML elements for the task at hand, rather than trying to force an element into a different role. Part of creating an accessible user experience means learning how to make the most of semantic HTML.&lt;/p&gt;

&lt;p&gt;Unfortunately, developers tend to fall into a number of common traps that violate HTML accessibility best practices. In the following section, we'll take a look at how to use semantic HTML to create an accessible user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Semantic HTML Basics
&lt;/h2&gt;

&lt;p&gt;So let's just clear this up now—there are only two non-semantic HTML elements: &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;. By definition, this means that anything else is &lt;strong&gt;semantic HTML&lt;/strong&gt;: an element that has some sort of inherent meaning. Some of these are depicted below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ki9i-qZG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/semantic-html.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ki9i-qZG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/semantic-html.png" alt="The main pieces of a website can be broken down into semantic elements and groupings"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Think of &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;s and &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;s as generic containers: They're simply there for grouping things at either the block or inline level. Beyond that, you can't really attach any meaning to a div: It's just a box.&lt;/p&gt;

&lt;p&gt;With all of that in mind, is it fair to say that the term "semantic HTML" a bit overused? Yes—one could argue that there's no need to talk about semantic HTML when pretty much 99% of HTML &lt;em&gt;is&lt;/em&gt; semantic.&lt;/p&gt;

&lt;p&gt;However, just because &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; are the only non-semantic HTML elements out there doesn't mean that it's less likely for people to abuse them, rather than using the right HTML elements for the task at hand.&lt;/p&gt;

&lt;p&gt;Before we move on, let's do a quick recap of the most notable semantic HTML elements and how they should be used on a website.&lt;/p&gt;

&lt;h3&gt;
  
  
  Main
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt; element represents the main content region of a website:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZplObGsh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/main.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZplObGsh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/main.png" alt="The main content region of a website"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Typically, you'll want to wrap everything in &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt; except for your navigation header and footer. Also, note that a page should only ever have one &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt; present to avoid confusing screen readers and search engine crawlers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Header and Footer
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fSYDyRIp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/header-footer.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fSYDyRIp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/header-footer.png" alt="The header and footer HTML elements"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can think of the &lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt; element as a container for certain "visible metadata" on your page. For example, you can use it at the top of an article to group your title, publication date, tags, and so on. You can also use header elements at the top of material cards, where you'll usually find things like thumbnails, titles, and other descriptive information about the card and its contents. Finally, you can also wrap your site's navbar in a &lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt; to set it apart from the main content of your site. If a &lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt; element is at the very top level of your HTML and is not a descendant of other semantic HTML elements, it'll have an implicit aria role of &lt;code&gt;banner&lt;/code&gt;, meaning screen readers will say something like "banner landmark" when they encounter it.&lt;/p&gt;

&lt;p&gt;On the other hand, a &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt; should be used for anything that logically follows your content, essentially providing additional information. For example, you can wrap an About the Author section in a footer, or a "you may also like" section at the end of an article. Of course, it should also be your go-to element for the literal footer of your website.&lt;/p&gt;

&lt;p&gt;The only thing to keep in mind is that &lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt; should never appear as children of each other. In other words, never put a header in a footer, or vice versa.&lt;/p&gt;

&lt;h3&gt;
  
  
  Article and Section
&lt;/h3&gt;

&lt;p&gt;Simply put, an &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt; is a self-contained piece of content that people would understand if you were to redistribute it externally. This means that blog posts, articles, and forum threads are a perfect use case for the &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt; element.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_cvHxsQ6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/article.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_cvHxsQ6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/article.png" alt="The article HTML element"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the other hand, &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt; represents... well, a section. This one typically confuses people because they're not sure what the difference is between a &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt; and a plain old &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;. What makes a section inherently semantic? Well, for one, sections typically have a heading. And if you omit one, you'll get an HTML validation warning. Sections are good for things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Comment sections at the end of an article.&lt;/li&gt;
&lt;li&gt;The literal sections of a blog post or article, as delineated by headings.&lt;/li&gt;
&lt;li&gt;"Chapters" (this one is brought up frequently, but it makes little sense in the context of the web).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don't use a &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt; just to avoid using a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;. There's nothing taboo about using divs, so long as you're not &lt;em&gt;misusing&lt;/em&gt; them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nav
&lt;/h3&gt;

&lt;p&gt;Simply put, use a &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt; to group primary or secondary navigation links, either in your top navigation bar or a table of contents, sidebar, breadcrumb links, and so on. Note that you shouldn't stick every single link on your site in a &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt;. Just because something is a link does not mean that it's part of some &lt;em&gt;navigation&lt;/em&gt; on your site. So while it's perfectly fine to use multiple &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt;s on your site, you should use this element sparingly and only if it makes sense to do so.&lt;/p&gt;

&lt;h3&gt;
  
  
  Other Semantic HTML Elements
&lt;/h3&gt;

&lt;p&gt;When talking about semantic HTML, people usually stop at just the generic bunch: nav, main, article, section, header, footer, and aside. But remember: &lt;em&gt;Everything&lt;/em&gt; is semantic except for divs and spans. Here are some of the more notable elements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Forms and their inputs (&lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Text: anchors (&lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;), paragraphs (&lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt;), lists (&lt;code&gt;ul/ol/li&lt;/code&gt;), headings (&lt;code&gt;h1-h6&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Inline markup (e.g., &lt;code&gt;&amp;lt;strong&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;em&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;mark&amp;gt;&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Images (&lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;), figures (&lt;code&gt;&amp;lt;figure&amp;gt;&lt;/code&gt;), tables (&lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt;), audio (&lt;code&gt;&amp;lt;audio&amp;gt;&lt;/code&gt;), video (&lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;... and much more. I won't delve into everything here. In a nutshell, any element that can be described as more than just a generic "container" is considered to be semantic HTML.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating an Accessible User Experience with Semantic HTML
&lt;/h2&gt;

&lt;p&gt;Now that we've done a quick review of what semantic HTML is, we're ready to look at examples of what you should and should not do in order to create an accessible user experience. For a list of browsers that support HTML accessibility, check out &lt;a href="https://www.html5accessibility.com/"&gt;html5accessibility.com&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don't Use Divs for Interactive Elements
&lt;/h3&gt;

&lt;p&gt;Using divs for user interactions is a terrible practice for web accessibility. In other words, don't do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;tabindex=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"toggle"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If an element's role is &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;, it may as well just be a &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; to begin with.&lt;/p&gt;

&lt;p&gt;Worse still, don't add an event listener that checks to see if the user pressed the &lt;code&gt;Enter&lt;/code&gt; key as a pseudo-click (&lt;a href="https://github.com/AleksandrHovhannisyan/aleksandrhovhannisyan.com/commit/fd0bf980501937c45ceb99a18a38418ffc86e12c"&gt;I've definitely never done this&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;toggle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keyup&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;keyEvent&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;keyEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Enter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="nx"&gt;doSomething&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;Just because something is possible with JavaScript and HTML doesn't mean that it's a good idea 😉 (or that it's truly accessible for keyboard and screen reader users). You certainly &lt;em&gt;can&lt;/em&gt; do this, but &lt;a href="https://benfrain.com/converting-divs-into-accessible-pseudo-buttons/"&gt;it will take some work&lt;/a&gt; to ensure that it's truly accessible. And even then, you'll still get HTML validation warnings because you're trying to dress up a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; as something that it's clearly not.&lt;/p&gt;

&lt;p&gt;Use buttons, anchors, and form inputs for interactive elements on your website. These semantic HTML elements already receive mouse and keyboard focus, have widespread browser support, and respond to user input both with the &lt;code&gt;Enter&lt;/code&gt; key and with a traditional mouse click. They are meant to be used as buttons, links, checkboxes, and so on.&lt;/p&gt;

&lt;p&gt;Unfortunately, this rule is broken frequently on the web, mainly because of JavaScript frameworks.&lt;/p&gt;

&lt;p&gt;Twitter's buttons are &lt;em&gt;divs all the way down&lt;/em&gt; (they're using &lt;code&gt;role="button"&lt;/code&gt; here):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iTOuOK5D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/twitter-button.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iTOuOK5D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/twitter-button.png" alt="Inspecting the Twitter heart button"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Gmail also uses divs for its buttons:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1ZbzgZ1u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/gmail.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1ZbzgZ1u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/gmail.png" alt="Inspecting Gmail's refresh button"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Facebook's like button is a div with an image inside it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GsBw59Jy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/facebook-like.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GsBw59Jy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/facebook-like.png" alt="Inspecting Facebook's like button"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But there are sites that do get this right!&lt;/p&gt;

&lt;p&gt;The StackExchange network uses &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; elements with nested SVGs:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oynftXmy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/stackoverflow-buttons.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oynftXmy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/stackoverflow-buttons.png" alt="Inspecting StackOverflow's upvote button"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As does the new Reddit interface (the old one is still using divs):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NcL8gsTC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/reddit.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NcL8gsTC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/reddit.png" alt="Inspecting the Reddit upvote button"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Q: Should I Use an Anchor or a Button?
&lt;/h4&gt;

&lt;p&gt;This is a good (and common!) question, mainly because developers are concerned with how their user interfaces &lt;em&gt;look&lt;/em&gt;. And the answer is simply that &lt;strong&gt;it depends on what the button does&lt;/strong&gt;. If it directs someone to a different page, then that's really an anchor's job; the only way to do it with a button is via JavaScript. So it's perfectly fine to use an anchor in this case and to style it like a button.&lt;/p&gt;

&lt;p&gt;Remember: To an unsighted user navigating your site, it won't be important what an element &lt;em&gt;looks&lt;/em&gt; like, but rather what the element &lt;em&gt;does&lt;/em&gt;. The best that a screen reader can do is to tell you what it is that you've encountered on a page. A screen reader can't possibly infer that a regular old &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; will take you to a different URL—that's the job of an anchor, after all.&lt;/p&gt;

&lt;p&gt;So, if your "button" is supposed to direct users to a different page, using &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; would create a frustrating user experience for unsighted people, especially if the button text doesn't clearly indicate that clicking it will take you to a different page or site. In fact, this would be frustrating for sighted users, too, since anchors show a link preview in the bottom-left of your browser when they receive focus or hover events, whereas a button that "silently" directs a user to a different page will not show any such indicator upon focus/hover.&lt;/p&gt;

&lt;p&gt;Now, on the other hand, if the button doesn't direct a user to a particular site, then it's perfectly fine (and more sensible) to use &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;. Add a JavaScript click listener to dictate what happens when a user clicks that button. Here are some examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Toggle an option or setting.&lt;/li&gt;
&lt;li&gt;Serve as a button in a game.&lt;/li&gt;
&lt;li&gt;Submit a like/upvote on a particular post.&lt;/li&gt;
&lt;li&gt;Submit a comment/post on a site.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that some buttons have inherent functions in HTML. For example, a button with &lt;code&gt;type="submit"&lt;/code&gt; is used in forms to trigger a form submission event. In this particular use case, an anchor or div would be a completely inappropriate and hacky substitute.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use More Lists!
&lt;/h3&gt;

&lt;p&gt;I have to say: &lt;code&gt;&amp;lt;ol&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt; are probably the two most underrated semantic HTML elements out there. Things are &lt;em&gt;listed&lt;/em&gt; are everywhere on the web, yet you rarely see them rendered &lt;em&gt;using&lt;/em&gt; lists!&lt;/p&gt;

&lt;p&gt;A screen reader won't detect that a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; is a collection of ordered or unordered items because divs convey absolutely zero meaning—they're not semantic HTML. Note that a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; has no implicit ARIA role, meaning a screen reader won't narrate anything special when it encounters that &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; (but it will still read its contents). This means that if you have multiple, separate &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;s that each serve as lists, their items will meld together when narrated, and that could get confusing.&lt;/p&gt;

&lt;p&gt;On the other hand, when it encounters an &lt;code&gt;&amp;lt;ol&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt;, a screen reader &lt;em&gt;will&lt;/em&gt; explicitly tell a user that there's a "list with X elements" up ahead. Moreover, the screen reader will narrate when it has exited a list (e.g., NVDA says "out of list"), giving an unsighted user a better sense of where they are on the page.&lt;/p&gt;

&lt;p&gt;Here are a few great use cases for HTML lists:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Navigation links&lt;/strong&gt; in menus and sidebars.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feeds and posts&lt;/strong&gt; (e.g., blog posts, social media feeds, forum posts, replies and comments). In most cases, you'll want to use an ordered list since these items are usually sorted by a given parameter, like date published.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pagination trails&lt;/strong&gt;. A pagination trail is literally a numbered list of pages—it doesn't get any simpler than that!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grouped tags and links&lt;/strong&gt; (e.g., post tags or social media links). Use unordered lists!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Just because lists render with bullet points or numbers by default doesn't mean that they must be reserved for &lt;em&gt;textual&lt;/em&gt; lists. In terms of semantic HTML, a list is the perfect container for a group of related items, ordered or not.&lt;/p&gt;

&lt;p&gt;The best part is that &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; elements, like &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;s, can accept any flow content (block or inline), including &lt;em&gt;more nested lists&lt;/em&gt;. You have nothing to fear with these elements. You should already be resetting margin and padding on your website anyway, so the only thing that remains is resetting &lt;code&gt;list-style&lt;/code&gt; and customizing the appearance of your lists on a case-by-case basis.&lt;/p&gt;

&lt;p&gt;Let's take another look around the web!&lt;/p&gt;

&lt;p&gt;Google renders search results using divs, but an ordered list would probably make more sense here since the top search results are not there by coincidence (i.e., the ordering matters):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Gb3NIX54--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/google.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Gb3NIX54--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/google.png" alt="Inspecting the Google search results page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Google has hidden elements that provide accessibility guidance to users with screen readers and other assistive technologies, so this "violation" isn't really a big deal. That may apply to some of the other sites and apps, too, though I haven't tested them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Twitter uses divs for replies:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VbvDcNKL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/twitter-replies.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VbvDcNKL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/twitter-replies.png" alt="Inspecting Twitter replies"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So does Reddit, both for its old and new interfaces:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7Nyde_7m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/reddit-comments.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7Nyde_7m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/reddit-comments.png" alt="Inspecting Reddit comments"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;StackOverflow gets it right again, using an unordered list for comments (though an ordered list may make more sense here since comments are sorted by the date they're posted):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xoeZvp-F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/stackoverflow-comments.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xoeZvp-F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/stackoverflow-comments.png" alt="Inspecting comments on a StackOverflow post"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And so does Spotify, where songs are rendered in an ordered list:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JjR9_TrD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/spotify.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JjR9_TrD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/spotify.png" alt="Inspecting a list of songs on Spotify"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's another great example of using a list properly, this time from GitHub:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cdG-Hp0y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/github-repo-results.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cdG-Hp0y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/github-repo-results.png" alt="Inspecting repository search results on GitHub"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice from these examples that a "list" is really an abstract concept. You shouldn't view &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; as an element that can only contain text. Clearly, it can also contain links, buttons, more lists, images, and anything else that you can think of.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don't Use Spans for Inline Positioning
&lt;/h3&gt;

&lt;p&gt;Another common mistake is to use &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;s to achieve inline positioning. Developers are taught early on that there's a distinction between block-level and inline elements in HTML; the two classic examples that get brought up are divs and spans, respectively. But while it's true that spans are inline elements, they're not intended to be used for inline &lt;em&gt;positioning&lt;/em&gt;. Spans are used to isolate inline portions of text, typically for one of two reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Styling some of the text differently.&lt;/li&gt;
&lt;li&gt;Injecting content into the text with JavaScript.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A good example of the second case is if you have text with placeholders, like &lt;code&gt;X comments&lt;/code&gt; or &lt;code&gt;X posts&lt;/code&gt;, and those placeholder counts need to get set via JavaScript (e.g., once an API call finishes). You'd isolate the placeholders with spans and give them IDs so their text can get set. Here's a real example of that from GitHub's own UI:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bl_QgTRe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/github-counter.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bl_QgTRe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/github-counter.png" alt="Inspecting a GitHub counter via the Chrome dev tools"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In addition, note again how the tabs themselves are rendered in a list. Yay!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you want inline positioning on block-level elements, &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; is not the right tool for the job. Instead, use CSS to position your elements inline (e.g., with Flexbox).&lt;/p&gt;

&lt;h3&gt;
  
  
  Don't Abuse ARIA
&lt;/h3&gt;

&lt;p&gt;You may have heard the term "ARIA" used in the context of HTML, but what exactly does it mean?&lt;/p&gt;

&lt;p&gt;As defined by the W3 Consortium, ARIA stands for &lt;strong&gt;Accessible Rich Internet Applications&lt;/strong&gt;. It's a set of built-in HTML attributes that developers can use to provide a better user experience to people using assistive technologies like screen readers.&lt;/p&gt;

&lt;p&gt;However, as I mentioned before, just because something is available to you doesn't mean that you should abuse or misuse it. Per W3's &lt;a href="https://www.w3.org/TR/html-aria/"&gt;documentation on ARIA&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Web developers MAY use the ARIA role and aria-* attributes on HTML elements, in accordance with the requirements described in &lt;a href="https://www.w3.org/TR/html-aria/#bib-wai-aria-1.1"&gt;wai-aria-1.1&lt;/a&gt;, except where these conflict with the strong native semantics or are equal to the implicit ARIA semantics of a given HTML element. These constraints are intended to prevent developers from making assistive technology products report nonsensical user interface (UI) information that does not represent the actual UI of the document.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here, "strong native semantics" refers to the fact that semantic HTML elements have intrinsic ARIA roles. You can explore these in the &lt;a href="https://developer.mozilla.org/en-US/"&gt;MDN Web Docs&lt;/a&gt; for a particular element. For example, the &lt;code&gt;&amp;lt;ol&amp;gt;&lt;/code&gt; tag has an implicit ARIA role of &lt;code&gt;list&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bscJPWUD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/mdn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bscJPWUD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/mdn.png" alt="Table describing the various attribute constraints for the ordered list element"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that elements also have a set of &lt;strong&gt;permitted ARIA roles&lt;/strong&gt; and &lt;strong&gt;permitted content&lt;/strong&gt;. For example, the descendant of an &lt;code&gt;&amp;lt;ol&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt; should only ever be one of &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;, or &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt;—anything else, and an &lt;a href="https://validator.w3.org/"&gt;HTML validator&lt;/a&gt; will give you an error. Here's an example of such an error:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Element div not allowed as child of element ol in this context.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;"Permitted ARIA roles" goes back to the whole "don't use divs as buttons" argument, though it encompasses a much wider issue of misusing elements in general or trying to get an element to masquerade as something completely different. HTML has a diverse set of semantic elements that you can use to build most user interfaces that come to mind—don't resort to hacks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use the Right Heading Levels for Your Content
&lt;/h3&gt;

&lt;p&gt;Have you ever used a lower heading level, like &lt;code&gt;h5&lt;/code&gt; or &lt;code&gt;h6&lt;/code&gt;, simply because you needed the text to be a smaller font size? While headings do have default font sizes, you shouldn't just pick a level based on the font size that you need. HTML headings communicate your content's hierarchy to screen readers, search engine crawlers, and HTML validation tools. Basically, don't skip levels and go from an &lt;code&gt;h2&lt;/code&gt; to an &lt;code&gt;h6&lt;/code&gt;. Imagine how confusing it would be for someone using a screen reader to hear that your content jumped from heading level two to six all of a sudden! Without seeing your site, they'd think that something must've gotten lost in translation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use the &lt;code&gt;&amp;lt;time&amp;gt;&lt;/code&gt; Element for Dates
&lt;/h3&gt;

&lt;p&gt;This is another underrated semantic HTML element. Basically, use the &lt;code&gt;&amp;lt;time&amp;gt;&lt;/code&gt; element for dates and times. For example, you can wrap the publication date in a &lt;code&gt;&amp;lt;time&amp;gt;&lt;/code&gt; for a forum post, blog post, article, video, and so on.&lt;/p&gt;

&lt;p&gt;GitHub uses &lt;a href="https://github.com/github/time-elements"&gt;web component extensions for the &lt;code&gt;&amp;lt;time&amp;gt;&lt;/code&gt; element&lt;/a&gt; in its UI:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E4ouox3J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/github-time.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E4ouox3J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/github-time.png" alt="Inspecting a relative date time on GitHub"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;StackOverflow uses &lt;code&gt;&amp;lt;time&amp;gt;&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gci0iTWM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/stackoverflow-time.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gci0iTWM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/stackoverflow-time.png" alt="StackOverflow uses the time element for the dates of posts"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And so does Twitter:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--n2vvxzK0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/twitter-time.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n2vvxzK0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/semantic-html-accessibility/twitter-time.png" alt="Twitter uses the time element for the date a tweet was posted"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's certainly not the end of the world if you don't use &lt;code&gt;&amp;lt;time&amp;gt;&lt;/code&gt;, so long as the date itself is part of some other semantic element (e.g., a paragraph or heading) that will make sense in the context in which it's narrated.&lt;/p&gt;

&lt;h2&gt;
  
  
  General Tips for HTML Accessibility
&lt;/h2&gt;

&lt;p&gt;Semantic HTML is just one piece of the accessibility puzzle—there's a lot more that goes into creating a better user experience on your site. Let's go over some of the finer details.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don't Overuse the &lt;code&gt;title&lt;/code&gt; Attribute
&lt;/h3&gt;

&lt;p&gt;Native tooltips should not be relied upon to give users any indication of what an interactive element represents. Moreover, don't combine it with an &lt;code&gt;aria-label&lt;/code&gt; because both may end up getting narrated by a screen reader, and that can get &lt;em&gt;really&lt;/em&gt; annoying.&lt;/p&gt;

&lt;h3&gt;
  
  
  Give Images a Descriptive &lt;code&gt;alt&lt;/code&gt; Attribute
&lt;/h3&gt;

&lt;p&gt;It helps to close your eyes for a moment and imagine that you're hearing the words that you type. You want to paint a picture without going into excessive detail, like mentioning colors, shapes, and so on (unless those are the central focus of the image). You also don't want to start your &lt;code&gt;alt&lt;/code&gt; attribute with "An image of..." or "A picture showing..." because that's already a given (screen readers will narrate the &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag as a graphic/image).&lt;/p&gt;

&lt;h3&gt;
  
  
  Use &lt;code&gt;aria-hidden&lt;/code&gt; and &lt;code&gt;alt=""&lt;/code&gt; Strategically for Certain Images
&lt;/h3&gt;

&lt;p&gt;Sometimes, you &lt;em&gt;want&lt;/em&gt; to hide content from screen readers to avoid presenting irrelevant information to unsighted users. Examples include blog post thumbnails and user avatars. While these elements are usually visible to the sighted user, they're not essential for an unsighted user and can sometimes confuse screen readers. Imagine how annoying it would be if a screen reader were to say &lt;code&gt;Profile photo for user X&lt;/code&gt; and then immediately follow that up by reading the user's name—it's repetitive. For this reason, you can use the &lt;code&gt;aria-hidden&lt;/code&gt; attribute, or simply set the image's &lt;code&gt;alt&lt;/code&gt; tag to be empty. Alternatively, you can use background images (unless you need lazy loading).&lt;/p&gt;

&lt;h3&gt;
  
  
  Mind Your Color Contrast
&lt;/h3&gt;

&lt;p&gt;So far, the focus has been on making the web a more accessible experience for unsighted users. But that doesn't mean that you should neglect your &lt;em&gt;sighted&lt;/em&gt; users. In particular, you'll want to follow best practices with regard to color usage on the web. Here are some general tips:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Stick to one or two colors for your theme. Shades of a single primary color are usually more than enough and can give your site a more cohesive and branded look.&lt;/li&gt;
&lt;li&gt;Use colors to convey a sense of elevation and content hierarchy. For example, an element that's lighter than its background is typically perceived as being elevated, while a darker element is depressed into the page. This is especially true for dark mode themes.&lt;/li&gt;
&lt;li&gt;Don't use font weights or colors that reduce the contrast between your primary text and its background. You want to maintain at least &lt;a href="https://webaim.org/resources/contrastchecker/"&gt;WCAG AA compliance&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Use Responsive Typography
&lt;/h3&gt;

&lt;p&gt;Smashing Magazine has an excellent guide on &lt;a href="https://www.smashingmagazine.com/2016/05/fluid-typography/"&gt;responsive and fluid typography&lt;/a&gt;, which is about ensuring that your font size scales up and down smoothly (like it does on this site!) depending on the screen width. That way, it's not too large on a mobile device, but it's sufficiently large on a tablet or desktop. Stick to using a minimum font size of 16px for your primary body text and around 12–14px for secondary text. Anything smaller than 12px is going to be terribly difficult to read on a mobile device. At the same time, you don't want your font size to be &lt;em&gt;too&lt;/em&gt; large, especially on mobile.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a More Accessible Web: Next Steps
&lt;/h2&gt;

&lt;p&gt;I highly recommend that you install a screen reader yourself to audit your own site for accessibility issues. Follow along with the narration. If nothing seems to make sense or flow right, then you have a problem. I personally prefer the &lt;a href="https://www.nvaccess.org/download/"&gt;NVDA&lt;/a&gt; screen reader; it's free and easy to use.&lt;/p&gt;

&lt;p&gt;There's also a fantastic tool called &lt;a href="https://wave.webaim.org/"&gt;WAVE&lt;/a&gt; that basically runs an accessibility audit on any given URL and shows the results right there in an interactive session.&lt;/p&gt;

&lt;p&gt;I hope you found this guide helpful! If you have any questions, let me know down below.&lt;/p&gt;

</description>
      <category>html</category>
      <category>ux</category>
      <category>a11y</category>
    </item>
    <item>
      <title>How to Escape Tutorial Purgatory</title>
      <dc:creator>Aleksandr Hovhannisyan</dc:creator>
      <pubDate>Sat, 09 May 2020 14:55:04 +0000</pubDate>
      <link>https://dev.to/aleksandrhovhannisyan/how-to-escape-tutorial-purgatory-53i7</link>
      <guid>https://dev.to/aleksandrhovhannisyan/how-to-escape-tutorial-purgatory-53i7</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This is a syndicated post. If you'd like to, you can &lt;a href="https://www.aleksandrhovhannisyan.com/blog/dev/how-to-escape-tutorial-purgatory/"&gt;view the original on my dev blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We've all been there before: You follow one tutorial after another hoping to find some sense of accomplishment or fulfillment as a developer. Instead, you walk away feeling unsated—hungry for something practical to sink your teeth into. But you never really find it. What you do find is existential panic: Am I cut out for this? When will I actually amount to something as a developer?&lt;/p&gt;

&lt;p&gt;Welcome to &lt;strong&gt;tutorial purgatory&lt;/strong&gt;, friend. It's a bit like being chained to a post—you see a world of opportunity spread before you, teasing your imagination, but you can only travel so far before you're reminded of the cold iron wrapped around your ankles.&lt;/p&gt;

&lt;p&gt;Stuck in tutorial purgatory? Here are my suggestions for how to escape this hell.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Tutorials as a Guide
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"Thou follow me, and I will be thy guide" —Virgil, &lt;em&gt;The Divine Comedy&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Think about whether you do any of these things when watching or reading dev tutorials:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Blindly copying and pasting code from the tutorial into your own environment.&lt;/li&gt;
&lt;li&gt;Cloning starter files from an associated repo that already contain setup code (e.g., HTML or CSS).&lt;/li&gt;
&lt;li&gt;Coding along with the tutorial, and finding yourself bored in the process.&lt;/li&gt;
&lt;li&gt;Simply following the tutorial without doing any coding yourself.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;These are fatal mistakes&lt;/strong&gt; that will only prolong your sentence in tutorial purgatory. If you're looking to learn something new or to find inspiration to start your own projects or sandboxes, then a tutorial should merely be treated like an answer key on an exam: It shows you the answer, but it should only be referenced once you've made an attempt to solve the problem yourself.&lt;/p&gt;

&lt;p&gt;Let's consider &lt;a href="https://javascript30.com/"&gt;WesBos's JavaScript30 course&lt;/a&gt;—it's a great way for JavaScript developers to sharpen their vanilla JS skills. But you shouldn't just watch the videos and code along. And you certainly shouldn't use the starter files that Wes provides, except for assets like audio files that you'd have to obtain yourself.&lt;/p&gt;

&lt;p&gt;What should you do instead? Use the tutorial for inspiration: Watch the first few minutes to understand what you're tasked with building, but pause it as soon as it starts diving into the implementation details. At this point, you have a rough UI "mockup" to work toward building yourself.&lt;/p&gt;

&lt;p&gt;Start from scratch on your own environment and give the problem your best, most creative attempt. If you get stuck, don't immediately give in and watch the video. Instead, research whatever problem you've run into. By now, it's almost guaranteed that whatever issue you're faced with has been documented on StackOverflow or Reddit. Only once you have a working solution should you then resume following the tutorial, comparing your attempt to the solution.&lt;/p&gt;

&lt;p&gt;This approach teaches you a fundamental, invaluable skill: &lt;strong&gt;learning independently&lt;/strong&gt;. You need to be able to solve problems on your own and come up with your own solutions. Failure is perfectly acceptable as long as you reflect on it and learn from it.&lt;/p&gt;

&lt;p&gt;Who knows? Maybe your solution is even better than the tutorial's. And if it's worse, or you overlooked certain edge cases, then you'll learn from those mistakes, and the entire experience will be far more memorable than if you had just blindly followed the tutorial from the beginning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stop Trying to Learn Things That Don't Interest You
&lt;/h2&gt;

&lt;p&gt;I recently came across a &lt;a href="https://gedd.ski/post/when-tech-makes-you-feel-dumb/"&gt;fantastic article by Dave Geddes&lt;/a&gt; about an experience that developers are all too familiar with: Trying to learn a new technology without any particular goal in mind, struggling to understand why that technology is needed in the first place or how it's supposed to be used, and then venting on the internet because the entire experience has made them feel stupid.&lt;/p&gt;

&lt;p&gt;All tools that humans created have one thing in common: &lt;strong&gt;They solve a problem&lt;/strong&gt;. And they're mainly intended to be used by people who have already struggled with said problem. Otherwise, their importance is lost upon the user.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;img src="https://www.aleksandrhovhannisyan.com/assets/img/posts/how-to-escape-tutorial-purgatory/tools.png" alt="xkcd comic about tools"&amp;gt;
&amp;lt;figcaption&amp;gt;Source: &amp;lt;a href="https://xkcd.com/1629/"&amp;gt;xkcd&amp;lt;/a&amp;gt;&amp;lt;/figcaption&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Beginners force themselves to learn X technology because it's been dangled in their face as the Carrot of Career Growth and Endless Financial Opportunities™. They don't exactly know why they need React, but they can sure as hell regurgitate what other people have told them about it—that it has a virtual DOM, and that having virtual DOMs is... well, a really good thing... to have.&lt;/p&gt;

&lt;p&gt;Haven't you ever wondered how things were done &lt;em&gt;without&lt;/em&gt; these fancy new technologies or what problems they actually solve? Imagine how many poor, helpless souls could've saved themselves a few hours of torment on StackOverflow if only they had learned JavaScript before dipping their toes in React. Imagine knowing how to harness the power of vanilla CSS and CSS preprocessors instead of handicapping yourself with bloated CSS frameworks like Bootstrap and Tailwind that make my eyes bleed when I read your HTML.&lt;/p&gt;

&lt;p&gt;You are, of course, free to learn whatever you want and whenever you want. But pace yourself, and understand the utility of whatever you are learning—these are two of the many keys to escaping tutorial purgatory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stop Splurging Money on Courses
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;For just &lt;em&gt;several hundred dollars&lt;/em&gt;, and sometimes &lt;em&gt;thousands&lt;/em&gt; over the course of a year, you too can learn Python, React, everything—&lt;em&gt;all the things&lt;/em&gt;—and land your very first job as a software developer!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Paid subscriptions to courses are, in my honest opinion and personal experience, the absolute worst thing to ever happen to the Learn to Code industry. They're built for instant gratification—to reward buyers with a sense of accomplishment at checkout and to make them feel like they've taken their first step toward mastering a new skill.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--u3lDY9Pn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/how-to-escape-tutorial-purgatory/udemy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--u3lDY9Pn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/how-to-escape-tutorial-purgatory/udemy.png" alt="Software development courses on sale on Udemy."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some people learn best with courses, and that's fine. But there's a certain type of junior developer who doesn't know any better—who equates learning with spending money and earning certifications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/blog/dev/learn-to-code-without-wasting-time-and-money/#stop-wasting-money-on-courses-you-ll-never-finish"&gt;I've written about this before&lt;/a&gt;, and I'll say it again: Don't waste money buying courses when there's such a wealth of free information available online. Price tags don't imply any inherent value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Take a Break
&lt;/h2&gt;

&lt;p&gt;You know what's so great about software development? The fact that there's something in it for everyone. You know what's not so great? It's... really difficult to find that thing.&lt;/p&gt;

&lt;p&gt;I sometimes feel like this industry is a sea of oddly shaped locks, and in my hands I hold a pair of keys that don't appear to fully fit in any of them. Most days, I'm passionate about frontend and everything CSS. Other days, my mind is tempted by the allure of mobile app development, machine learning, networking, game dev, and a host of other distractions that I dabble in for minutes at a time, and then quickly abandon.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--V3wviXn7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/how-to-escape-tutorial-purgatory/distractions.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V3wviXn7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.aleksandrhovhannisyan.com/assets/img/posts/how-to-escape-tutorial-purgatory/distractions.png" alt="Distractions, distractions everywhere."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Does it help that technology is moving so quickly? You've heard this before, so pardon the repetition, but there's a new JavaScript framework born every minute. Will React still be relevant in a few years? What about Vue? Insert X language, framework, etc., and you're confronted with the same problem. Now WebAssembly is the new kid on the block. How do you keep up with all of it?&lt;/p&gt;

&lt;p&gt;Be honest: How many more to-do list app tutorials can you tolerate before you lose your sanity? More importantly, are you going to remember any of these things tomorrow or a week from now, or are you only learning them after someone mentioned that you should &lt;em&gt;because reasons&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;Sometimes, it helps to just step away from it all for a day or two and put your mind at ease. I get that you're passionate about development, but it shouldn't consume your entire existence. Listen to music, read, watch a movie, play video games, write, work out, and do just about anything but dev 24/7/365.&lt;/p&gt;

&lt;p&gt;Tutorial purgatory is a phase—you'll eventually find your calling, work on meaningful projects, and land the job you've dreamed of.&lt;/p&gt;

&lt;p&gt;In the meantime, it certainly doesn't hurt to follow a tutorial now and then to sharpen your skills or learn new things. But don't allow tutorials to become a crutch.&lt;/p&gt;

</description>
      <category>beginners</category>
    </item>
    <item>
      <title>Getting Started with Jekyll and GitHub Pages: Your First Website</title>
      <dc:creator>Aleksandr Hovhannisyan</dc:creator>
      <pubDate>Sun, 01 Mar 2020 16:27:39 +0000</pubDate>
      <link>https://dev.to/aleksandrhovhannisyan/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide-3fje</link>
      <guid>https://dev.to/aleksandrhovhannisyan/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide-3fje</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This is a syndicated post, and a very long one at that! If you'd like to, you can &lt;a href="https://www.aleksandrhovhannisyan.com/blog/dev/getting-started-with-jekyll-and-github-pages/"&gt;view the original on my dev blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Want to make a personal website or blog and share it with the world? Then you've come to the right place! This is the only guide you'll need for getting started with Jekyll. I'll take you from zero to hero with Jekyll and help you understand all the fundamentals.&lt;/p&gt;

&lt;p&gt;I moved my old site from pure HTML and CSS to Jekyll a while back and immediately fell in love. There's very little that Jekyll doesn't allow you to accomplish, so it's a perfect, lightweight option for beginners and veterans alike.&lt;/p&gt;

&lt;p&gt;Note that some parts of this tutorial assume that you'll be hosting your site with GitHub Pages. If instead you're hosting your site with Netlify or another service, the process should be very similar, and the core concepts of building a site with Jekyll certainly won't change.&lt;/p&gt;

&lt;p&gt;All right, enough chit-chat—let's dig in!&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Overview: What Is Jekyll?&lt;/li&gt;
&lt;li&gt;How to Set Up GitHub Pages&lt;/li&gt;
&lt;li&gt;
Getting Started with Jekyll

&lt;ul&gt;
&lt;li&gt;1. Installing Jekyll&lt;/li&gt;
&lt;li&gt;2. Setting Up Your First Jekyll Site&lt;/li&gt;
&lt;li&gt;3. Configuring Jekyll with GitHub Pages&lt;/li&gt;
&lt;li&gt;4. Running Jekyll Locally&lt;/li&gt;
&lt;li&gt;5. Pushing Your Site to GitHub&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Typical Jekyll Directory Structure&lt;/li&gt;
&lt;li&gt;Configuring Your Jekyll Site&lt;/li&gt;
&lt;li&gt;
How to Create Pages in Jekyll

&lt;ul&gt;
&lt;li&gt;What Is Markdown Front Matter?&lt;/li&gt;
&lt;li&gt;Front Matter Defaults&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Where Do I Put My Pages in Jekyll?&lt;/li&gt;
&lt;li&gt;
Jekyll Blog Posts

&lt;ul&gt;
&lt;li&gt;Permalinks to Blog Posts in Jekyll&lt;/li&gt;
&lt;li&gt;You Don't Need an Explicit Date Variable&lt;/li&gt;
&lt;li&gt;Blog Post Front Matter Variables&lt;/li&gt;
&lt;li&gt;Syntax Highlighting&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
Dr. Jekyll and Mr. Liquid

&lt;ul&gt;
&lt;li&gt;Data Types&lt;/li&gt;
&lt;li&gt;Template Tags&lt;/li&gt;
&lt;li&gt;Variables&lt;/li&gt;
&lt;li&gt;Control Flow&lt;/li&gt;
&lt;li&gt;Objects&lt;/li&gt;
&lt;li&gt;Operators&lt;/li&gt;
&lt;li&gt;Filters&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
Using Jekyll Layout Files to Structure Pages

&lt;ul&gt;
&lt;li&gt;Using More Than One Layout&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
Writing CSS in Jekyll Using SASS

&lt;ul&gt;
&lt;li&gt;Modular CSS with SASS Imports&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Creating Reusable Components with Includes&lt;/li&gt;
&lt;li&gt;
Taking Advantage of Jekyll Data Files

&lt;ul&gt;
&lt;li&gt;Example 1: Skills and Abilities&lt;/li&gt;
&lt;li&gt;Example 2: Author Bios&lt;/li&gt;
&lt;li&gt;Example 3: Tag Descriptions&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
Setting Up Google Search Console

&lt;ul&gt;
&lt;li&gt;Is It Safe to Upload the Google Search Console Verification File?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;GitHub Pages Support for Jekyll Plugins&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Overview: What Is Jekyll?
&lt;/h2&gt;

&lt;p&gt;Jekyll is a &lt;strong&gt;static site generator&lt;/strong&gt;. That's just a fancy way of saying that it takes a bunch of HTML, Markdown, CSS, and JavaScript source files, combines them as needed based on layout files that you've specified, processes any template code that you've written, and spits out a build directory (e.g., &lt;code&gt;_site/&lt;/code&gt;) that basically houses all of your website's content, ready for hosting on a web server (like GitHub Pages!).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Hyuqm9ME--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/static-site-generator.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hyuqm9ME--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/static-site-generator.PNG" alt="A static site generator spits out a compiled, well-structured, fully functioning site." width="880" height="263"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In plain English, Jekyll makes it easy for you to create a website—and, more commonly, a blog—with plain old HTML and Markdown, without having to worry about things like how to add tags to posts or make certain static data accessible on all of your pages. It takes care of these things for you so you can focus on doing what you love the most: writing (or, in my case, writing &lt;em&gt;and&lt;/em&gt; dev)!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://help.github.com/en/github/working-with-github-pages/about-github-pages"&gt;GitHub Pages&lt;/a&gt;, on the other hand, is a free hosting service for static sites that's offered by GitHub to all of its users. And since GitHub accounts are practically &lt;em&gt;free real estate&lt;/em&gt;, there's really never been a better time to make your very own website or blog.&lt;/p&gt;

&lt;p&gt;The best part? GitHub Pages supports (&lt;a href="https://help.github.com/en/github/working-with-github-pages/about-github-pages-and-jekyll"&gt;and even recommends&lt;/a&gt;) Jekyll out of the box, meaning you can set up a Jekyll project &lt;em&gt;right now&lt;/em&gt;, push the source code to a GitHub repository, and view the live website!&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Set Up GitHub Pages
&lt;/h2&gt;

&lt;p&gt;If you've already set up your GitHub Pages repo, feel free to skip this section.&lt;/p&gt;

&lt;p&gt;You can create as many GitHub Pages sites as you want. Each user can only create one site whose domain is &lt;code&gt;https://yourUsername.github.io&lt;/code&gt;. All other repo sites go under &lt;code&gt;https://yourUsername.github.io/repoName&lt;/code&gt;. GitHub even &lt;a href="https://help.github.com/en/github/working-with-github-pages/configuring-a-custom-domain-for-your-github-pages-site"&gt;lets you configure your own custom domain&lt;/a&gt; if you have one.&lt;/p&gt;

&lt;p&gt;To get started, visit &lt;a href="https://github.com/"&gt;https://github.com/&lt;/a&gt;, sign in, and click the green &lt;code&gt;New&lt;/code&gt; button to create a new repo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2ZRCjjWA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/new-repo.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2ZRCjjWA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/new-repo.PNG" alt="Click the green new button to create a repository." width="880" height="242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter the name of your repository. It needs to be your GitHub username followed by &lt;code&gt;.github.io&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--725PjmIh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/create-repo.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--725PjmIh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/create-repo.PNG" alt="Type in the name of your new repository." width="880" height="94"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's literally all you have to do to get started with GitHub Pages! As with other repos you own, you'll want to clone it locally and set up your origin remote.&lt;/p&gt;

&lt;p&gt;If you want to use any starter themes, GitHub goes over those &lt;a href="https://guides.github.com/features/pages/"&gt;in its documentation for GitHub Pages&lt;/a&gt;. Disclaimer: I'm not sure how these work with Jekyll, so you're on your own if you take that route.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started with Jekyll
&lt;/h2&gt;

&lt;p&gt;Now that we've set up GitHub Pages, we'll go over everything you need to know to get started with Jekyll. For the remainder of this tutorial, I'll assume you're using Bash as your terminal, either on a Mac/Linux or with the &lt;a href="https://docs.microsoft.com/en-us/learn/modules/get-started-with-windows-subsystem-for-linux/"&gt;Windows Subsystem for Linux (WSL)&lt;/a&gt;. I'm sure there's a reasonably painful way to do this all on a Windows terminal like PowerShell, but I wouldn't advise it... because Windows.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Installing Jekyll
&lt;/h3&gt;

&lt;p&gt;Jekyll has an excellent, in-depth &lt;a href="https://jekyllrb.com/docs/installation/"&gt;installation guide&lt;/a&gt; for each OS, so I'll let you read that instead of copy-pasting it all here. If you follow the Ubuntu guide, which is what I use via WSL, you'll install these three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Ruby&lt;/strong&gt;, the programming language that powers Jekyll.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bundler&lt;/strong&gt;, a Ruby gem (think "module") that lets you manage your project's dependencies with ease.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jekyll&lt;/strong&gt;, obviously.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you're familiar with npm and yarn, Bundler is basically the same idea except for Ruby—it manages your dependencies (gems) via two files called &lt;code&gt;Gemfile&lt;/code&gt; and &lt;code&gt;Gemfile.lock&lt;/code&gt;, which we'll see shortly.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Setting Up Your First Jekyll Site
&lt;/h3&gt;

&lt;p&gt;Assuming that everything went well, it's time to make your first Jekyll site.&lt;/p&gt;

&lt;p&gt;Running this command will set up a folder named &lt;code&gt;mysite&lt;/code&gt; with all of the necessary starter files and directories:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bundle &lt;span class="nb"&gt;exec &lt;/span&gt;jekyll new mysite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you already have existing source files in a project directory for your site, you can instead run this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;mysite
bundle &lt;span class="nb"&gt;exec &lt;/span&gt;jekyll new &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--force&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;: The second option may end up overwriting existing files. Alternatively, you could set up the project in a different directory and copy over the files when it's done so you have more control.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The end result should be this simple directory structure:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iZcUbZpo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/directory-structure.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iZcUbZpo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/directory-structure.JPG" alt="Jekyll starter files." width="880" height="183"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Configuring Jekyll with GitHub Pages
&lt;/h3&gt;

&lt;p&gt;Go ahead and open up the Gemfile at the root of your project. You'll find useful comments in there to help you configure Jekyll with GitHub Pages:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;Gemfile&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="s2"&gt;"https://rubygems.org"&lt;/span&gt;

&lt;span class="c1"&gt;# Hello! This is where you manage which Jekyll version is used to run.&lt;/span&gt;
&lt;span class="c1"&gt;# When you want to use a different version, change it below, save the&lt;/span&gt;
&lt;span class="c1"&gt;# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;#     bundle exec jekyll serve&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# This will help ensure the proper Jekyll version is running.&lt;/span&gt;
&lt;span class="c1"&gt;# Happy Jekylling!&lt;/span&gt;

&lt;span class="c1"&gt;# If you want to use GitHub Pages, remove the "gem "jekyll"" above and&lt;/span&gt;
&lt;span class="c1"&gt;# uncomment the line below. To upgrade, run `bundle update github-pages`.&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s2"&gt;"github-pages"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;group: :jekyll_plugins&lt;/span&gt;

&lt;span class="c1"&gt;# If you have any plugins, put them here!&lt;/span&gt;
&lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="ss"&gt;:jekyll_plugins&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s2"&gt;"jekyll-feed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 0.6"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Windows does not include zoneinfo files, so bundle the tzinfo-data gem&lt;/span&gt;
&lt;span class="c1"&gt;# and associated library.&lt;/span&gt;
&lt;span class="n"&gt;install_if&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;RUBY_PLATFORM&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt; &lt;span class="sr"&gt;%r!mingw|mswin|java!&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s2"&gt;"tzinfo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 1.2"&lt;/span&gt;
  &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s2"&gt;"tzinfo-data"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Performance-booster for watching directories on Windows&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s2"&gt;"wdm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 0.1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:install_if&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Gem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;win_platform?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, remove this line if you intend to publish your site on GitHub Pages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s2"&gt;"jekyll"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 3.8.6"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then uncomment the line specifying the &lt;code&gt;github-pages&lt;/code&gt; gem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# If you want to use GitHub Pages, remove the "gem "jekyll"" above and&lt;/span&gt;
&lt;span class="c1"&gt;# uncomment the line below. To upgrade, run `bundle update github-pages`.&lt;/span&gt;
&lt;span class="c1"&gt;# gem "github-pages", group: :jekyll_plugins&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also recommend removing this line to get rid of the default &lt;code&gt;minima&lt;/code&gt; theme:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# This is the default theme for new Jekyll sites. You may change this to anything you like.&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s2"&gt;"minima"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 2.0"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you do that, you'll also need to remove it from &lt;code&gt;_config.yml&lt;/code&gt; by setting the theme to &lt;code&gt;null&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ...&lt;/span&gt;

&lt;span class="c1"&gt;# Build settings&lt;/span&gt;
&lt;span class="na"&gt;markdown&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kramdown&lt;/span&gt;
&lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;minima&lt;/span&gt; &lt;span class="c1"&gt;# replace minima with null&lt;/span&gt;
&lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;jekyll-feed&lt;/span&gt;

&lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don't use &lt;code&gt;theme: null&lt;/code&gt;, the &lt;code&gt;github-pages&lt;/code&gt; gem will automatically generate a default stylesheet, &lt;code&gt;/_site/assets/css/style.css&lt;/code&gt;, that's about 3k lines long, and that you may not want or need for your site. I recommend setting the theme to &lt;code&gt;null&lt;/code&gt; so you have control over your styling, but this is up to you.&lt;/p&gt;

&lt;p&gt;After doing all of that, run this command to install and update all necessary gems for your site:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bundle &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If all went well, you should see output similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bundle complete! 5 Gemfile dependencies, 85 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should also now see a &lt;code&gt;Gemfile.lock&lt;/code&gt; file at the root of your project. This is like the &lt;code&gt;package-lock.json&lt;/code&gt; that npm generates, if you've ever worked in a Node ecosystem. This lockfile gets created the first time you run &lt;code&gt;bundle install&lt;/code&gt;, ensuring that anyone who runs the same command in the future installs the exact versions specified in there. That way, everyone's on the same page.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Running Jekyll Locally
&lt;/h3&gt;

&lt;p&gt;Let's fire her up and see what we've got:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bundle &lt;span class="nb"&gt;exec &lt;/span&gt;jekyll serve &lt;span class="nt"&gt;--livereload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, this runs your site on &lt;code&gt;localhost:4000&lt;/code&gt; with live-reloading enabled, so if you make changes to your files, Jekyll will regenerate the build directory and automatically refresh your page.&lt;/p&gt;

&lt;p&gt;You can change the port in one of two ways. The first is to specify the &lt;code&gt;--port&lt;/code&gt; argument:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bundle &lt;span class="nb"&gt;exec &lt;/span&gt;jekyll serve &lt;span class="nt"&gt;--livereload&lt;/span&gt; &lt;span class="nt"&gt;--port&lt;/span&gt; 4001
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second is to add this line somewhere inside your project's &lt;code&gt;_config.yml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4001&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: You can leave the port as &lt;code&gt;4000&lt;/code&gt; by default. This is just useful to know in case you want to run two Jekyll sites simultaneously on your local since they can't both be on the same port.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Head on over to &lt;code&gt;localhost:4000&lt;/code&gt; to see the starter page. Note that the appearance of this page depends on how you configured Jekyll in the earlier sections. You may see:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The minima theme, which has the most starter content, if you left &lt;code&gt;theme: minima&lt;/code&gt; as is.&lt;/li&gt;
&lt;li&gt;A mostly blank page with a title placeholder if you deleted the line &lt;code&gt;theme: minima&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A completely blank page, if you set &lt;code&gt;theme: null&lt;/code&gt; explicitly like I recommended.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Pz6fApHC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/themes.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Pz6fApHC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/themes.JPG" alt="The three Jekyll starter themes." width="880" height="322"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The remainder of this tutorial assumes that your theme is set to &lt;code&gt;null&lt;/code&gt;. Some of the screenshots I show may not line up with what you see on your end if you decide to use the minima theme. You may also miss out on learning some useful things about how Jekyll works if you decide to use one of the starter themes instead of writing your own CSS.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Pushing Your Site to GitHub
&lt;/h3&gt;

&lt;p&gt;If you haven't already done so, push your Jekyll site to GitHub Pages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, simply visit &lt;code&gt;https://yourUsername.github.io&lt;/code&gt; to view the live version of your website.&lt;/p&gt;

&lt;p&gt;Congratulations! If you're with me so far, you're done with the hard part. Now, it's time to actually learn how to customize your site. It's important to step out of your comfort zone. Don't worry if you accidentally "break" a file—just undo those changes with Git.&lt;/p&gt;

&lt;h2&gt;
  
  
  Typical Jekyll Directory Structure
&lt;/h2&gt;

&lt;p&gt;The Jekyll starter is a bare-bones site. In reality, you're going to need more Jekyll-supported directories for different kinds of tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;_data&lt;/code&gt;: Where you can store data files for things like skills, projects, work history, and so on.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_drafts&lt;/code&gt;: Add this to your &lt;code&gt;.gitignore&lt;/code&gt; and store your blog post drafts in here (optional).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_includes&lt;/code&gt;: Where you define Jekyll includes, which are sort of like reusable HTML components.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_layouts&lt;/code&gt;: HTML layouts define the structure of your site and can be nested in one another.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_posts&lt;/code&gt;: Where you'll store all of your blog posts as Markdown files.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_sass&lt;/code&gt;: This is where your SASS partials go. You'll then need to import them in &lt;code&gt;_assets/main.scss&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_site&lt;/code&gt;: Jekyll's auto-generated build directory, which houses your final, compiled site. It's not pushed to GitHub because it's in &lt;code&gt;.gitignore&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_assets&lt;/code&gt;: Mainly for storing images and scripts, but it can also house a main CSS file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You may be wondering why all of these directory names are prefixed by an underscore. A directory with a leading underscore is special and won't get processed by Jekyll. As a result, it won't appear in the build directory, &lt;code&gt;_site/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If none of this makes sense to you right now, or if all of this seems overwhelming, don't worry—I'm going to walk you through most of it step by step. Also note that you are free to add any other directories that you need. &lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring Your Jekyll Site
&lt;/h2&gt;

&lt;p&gt;We already saw that you can edit your Jekyll starter theme in &lt;code&gt;_config.yml&lt;/code&gt;, but that's not all that this file allows you to do. In fact, this file houses your entire site's configuration settings. Here's what mine looks like so far:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_config.yml&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Welcome to Jekyll!&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# This config file is meant for settings that affect your whole blog, values&lt;/span&gt;
&lt;span class="c1"&gt;# which you are expected to set up once and rarely edit after that. If you find&lt;/span&gt;
&lt;span class="c1"&gt;# yourself editing this file very often, consider using Jekyll's data files&lt;/span&gt;
&lt;span class="c1"&gt;# feature for the data you need to update frequently.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# For technical reasons, this file is *NOT* reloaded automatically when you use&lt;/span&gt;
&lt;span class="c1"&gt;# 'bundle exec jekyll serve'. If you change this file, please restart the server process.&lt;/span&gt;

&lt;span class="c1"&gt;# Site settings&lt;/span&gt;
&lt;span class="c1"&gt;# These are used to personalize your new site. If you look in the HTML files,&lt;/span&gt;
&lt;span class="c1"&gt;# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on.&lt;/span&gt;
&lt;span class="c1"&gt;# You can create any custom variable you would like, and they will be accessible&lt;/span&gt;
&lt;span class="c1"&gt;# in the templates via {{ site.myvariable }}.&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Your awesome title&lt;/span&gt;
&lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;your-email@example.com&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;-&lt;/span&gt; &lt;span class="c1"&gt;# this means to ignore newlines until "baseurl:"&lt;/span&gt;
  &lt;span class="s"&gt;Write an awesome description for your new site here. You can edit this&lt;/span&gt;
  &lt;span class="s"&gt;line in _config.yml. It will appear in your document head meta (for&lt;/span&gt;
  &lt;span class="s"&gt;Google search results) and in your feed.xml site description.&lt;/span&gt;
&lt;span class="na"&gt;baseurl&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;# the subpath of your site, e.g. /blog&lt;/span&gt;
&lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;# the base hostname &amp;amp; protocol for your site, e.g. http://example.com&lt;/span&gt;
&lt;span class="na"&gt;twitter_username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jekyllrb&lt;/span&gt;
&lt;span class="na"&gt;github_username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;jekyll&lt;/span&gt;

&lt;span class="c1"&gt;# Build settings&lt;/span&gt;
&lt;span class="na"&gt;markdown&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kramdown&lt;/span&gt;
&lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;null&lt;/span&gt;
&lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;jekyll-feed&lt;/span&gt;

&lt;span class="c1"&gt;# Exclude from processing.&lt;/span&gt;
&lt;span class="c1"&gt;# The following items will not be processed, by default. Create a custom list&lt;/span&gt;
&lt;span class="c1"&gt;# to override the default setting.&lt;/span&gt;
&lt;span class="c1"&gt;# exclude:&lt;/span&gt;
&lt;span class="c1"&gt;#   - Gemfile&lt;/span&gt;
&lt;span class="c1"&gt;#   - Gemfile.lock&lt;/span&gt;
&lt;span class="c1"&gt;#   - node_modules&lt;/span&gt;
&lt;span class="c1"&gt;#   - vendor/bundle/&lt;/span&gt;
&lt;span class="c1"&gt;#   - vendor/cache/&lt;/span&gt;
&lt;span class="c1"&gt;#   - vendor/gems/&lt;/span&gt;
&lt;span class="c1"&gt;#   - vendor/ruby/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll understand how all of these settings are used once we cover the Liquid templating language. For now, just keep in mind that you can access most of these settings on all of your pages via a globally exposed &lt;code&gt;site&lt;/code&gt; variable in a language called Liquid: &lt;code&gt;site.title&lt;/code&gt;, &lt;code&gt;site.description&lt;/code&gt;, &lt;code&gt;site.url&lt;/code&gt;, and so on.&lt;/p&gt;

&lt;p&gt;Go ahead and fill in most of these setings (you could also do this later—there's no rush). Additionally, note that you don't need many of the variables that are defined in here, like your email, Twitter username, GitHub username, or your site's base URL, so you can safely delete them. You can also add any other site variables that you'd like.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: If you make any changes to this file, you'll need to stop running your site and restart it to see the changes. This is because Jekyll only processes &lt;code&gt;_config.yml&lt;/code&gt; once when you execute &lt;code&gt;jekyll serve&lt;/code&gt; and doesn't listen for changes. You shouldn't have to change your config too often.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We'll come back to &lt;code&gt;_config.yml&lt;/code&gt; in a later section once we've looked at some other Jekyll basics.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Create Pages in Jekyll
&lt;/h2&gt;

&lt;p&gt;If you have any experience working with plain old HTML to create sites, you should be familiar with creating an &lt;code&gt;index.html&lt;/code&gt; file and placing it at the root of your project directory. This is the page that your web server will send back when the client requests your site's root URL (e.g., &lt;code&gt;https://myawesomesite.github.io/&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;In your project directory, you should see a mostly empty file named &lt;code&gt;index.md&lt;/code&gt; that looks something like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;index.md&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="c1"&gt;# Feel free to add content and custom Front Matter to this file.&lt;/span&gt;
&lt;span class="c1"&gt;# To modify the layout, see https://jekyllrb.com/docs/themes/#overriding-theme-defaults&lt;/span&gt;

&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;home&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Files ending in &lt;code&gt;.md&lt;/code&gt; (or &lt;code&gt;.markdown&lt;/code&gt;) are written in &lt;a href="https://en.wikipedia.org/wiki/Markdown"&gt;Markdown&lt;/a&gt;, a widely used markup language that just gets compiled down to HTML. Since it has such a simple syntax, Markdown is often favored in static site generators like Jekyll, Hugo, and GatsbyJS, especially for writing blog posts.&lt;/p&gt;

&lt;p&gt;You should be familiar with Markdown if you've ever created a &lt;code&gt;README.md&lt;/code&gt; file for your repo or posted anything on StackOverflow, which uses a modified Markdown parser. Note that Markdown is, in a sense, "backwards compatible"—you can still write raw HTML in a Markdown file.&lt;/p&gt;

&lt;p&gt;Jekyll uses a modified Markdown parser called &lt;a href="https://kramdown.gettalong.org/syntax.html"&gt;kramdown&lt;/a&gt;, as noted in &lt;code&gt;_config.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Build settings&lt;/span&gt;
&lt;span class="na"&gt;markdown&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kramdown&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kramdown extends Markdown with some useful features, like adding classes and IDs to elements without having to resort to the HTML syntax.&lt;/p&gt;

&lt;p&gt;Before moving on, let's modify &lt;code&gt;index.md&lt;/code&gt; as follows:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;index.md&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="c1"&gt;# Feel free to add content and custom Front Matter to this file.&lt;/span&gt;
&lt;span class="c1"&gt;# To modify the layout, see https://jekyllrb.com/docs/themes/#overriding-theme-defaults&lt;/span&gt;

&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;home&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gh"&gt;# Hello, Jekyll!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If live-reloading is enabled, you should see your page update automatically to display an &lt;code&gt;h1&lt;/code&gt; tag. Otherwise, you may need to refresh manually to see this change.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DdTzlbme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/hello-jekyll.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DdTzlbme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/hello-jekyll.PNG" alt="Hello, Jekyll" width="880" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As I noted earlier, you can optionally also use plain HTML to get the same result:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;index.md&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="c1"&gt;# Feel free to add content and custom Front Matter to this file.&lt;/span&gt;
&lt;span class="c1"&gt;# To modify the layout, see https://jekyllrb.com/docs/themes/#overriding-theme-defaults&lt;/span&gt;

&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;home&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"hello-jekyll"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Hello, Jekyll!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that we have to specify the ID explicitly with HTML, whereas Markdown does it automatically for us. If you wanted to, you could achieve the same result using Kramdown's ID specifier:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;index.md&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="c1"&gt;# Feel free to add content and custom Front Matter to this file.&lt;/span&gt;
&lt;span class="c1"&gt;# To modify the layout, see https://jekyllrb.com/docs/themes/#overriding-theme-defaults&lt;/span&gt;

&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;home&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gh"&gt;# Hello, Jekyll {#hello-jekyll}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To understand more about what goes on behind the scenes in Jekyll, go ahead and expand your Git-ignored &lt;code&gt;_site&lt;/code&gt; directory. Remember that this is the build directory that Jekyll creates each time you change a file, while &lt;code&gt;jekyll serve&lt;/code&gt; is running. You should see that there's an &lt;code&gt;index.html&lt;/code&gt; in there. Open that up to see its contents:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_site/index.html&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"hello-jekyll"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Hello, Jekyll!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This reveals an interesting point that will become important later: Where a file ends up in &lt;code&gt;_site/&lt;/code&gt; depends on where it is placed in your project directory. In our case, the &lt;code&gt;index.md&lt;/code&gt; at the root of our project directory becomes &lt;code&gt;index.html&lt;/code&gt; at the root of &lt;code&gt;_site/&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Is Markdown Front Matter?
&lt;/h3&gt;

&lt;p&gt;Notice that the comments at the top of &lt;code&gt;index.md&lt;/code&gt; mention that you can add custom "front matter" to the file. What exactly does that mean?&lt;/p&gt;

&lt;p&gt;This is once again a common feature in static site generators. Anything between the triple-hyphen block at the top of a page is known as &lt;strong&gt;YAML front matter&lt;/strong&gt;, which is just a fancy way of saying it defines certain metadata that you can later use to customize your pages, using YAML as the language. Note that you can add front matter to HTML files, too, not just to Markdown files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;home&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Currently, &lt;code&gt;index.md&lt;/code&gt; defines a variable named &lt;code&gt;layout&lt;/code&gt; that's assigned a value of &lt;code&gt;home&lt;/code&gt;. This doesn't actually do anything yet because we haven't created any layout files (don't worry—we'll learn how to do that in a later section). We even get build warnings for this and a few of our other files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Build Warning: Layout 'post' requested in _posts/2020-02-14-welcome-to-jekyll.markdown does not exist.
Build Warning: Layout 'default' requested in 404.html does not exist.      
Build Warning: Layout 'page' requested in about.md does not exist.
Build Warning: Layout 'home' requested in index.md does not exist.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that there are &lt;strong&gt;predefined front matter variables&lt;/strong&gt; (like &lt;code&gt;layout&lt;/code&gt;) that Jekyll recognizes by default and uses to change how a page looks or behaves, without you having to explicitly define what it should do with those variables. In this case, Jekyll uses the &lt;code&gt;layout&lt;/code&gt; variable to structure your page's HTML according to a layout file, if you've defined one (more on that later). Check out the official Jekyll docs for the full list of &lt;a href="https://jekyllrb.com/docs/variables/"&gt;predefined variables&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can also define any number of &lt;strong&gt;custom front matter variables&lt;/strong&gt; for your own use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;myAwesomeVariable&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;42&lt;/span&gt;
&lt;span class="na"&gt;majorKey&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Success&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since these are not among the predefined front matter variables that Jekyll recognizes, it doesn't know what to do with them, so you'll have to use them yourself via Liquid to achieve your desired result (whatever that may be). We'll learn more about this once we get to the section on Liquid.&lt;/p&gt;

&lt;p&gt;While we're on the topic of front matter, go ahead and open up the starter blog post that Jekyll created for us. On my end, it's located under &lt;code&gt;_posts/2020-02-14-welcome-to-jekyll.markdown&lt;/code&gt; and has this content:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_posts/2020-02-14-welcome-to-jekyll.markdown&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;post&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Welcome&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Jekyll!"&lt;/span&gt;
&lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;   &lt;span class="s"&gt;2020-02-14 07:40:59 -0500&lt;/span&gt;
&lt;span class="na"&gt;categories&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jekyll update&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
You’ll find this post in your &lt;span class="sb"&gt;`_posts`&lt;/span&gt; directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run &lt;span class="sb"&gt;`jekyll serve`&lt;/span&gt;, which launches a web server and auto-regenerates your site when a file is updated.

To add new posts, simply add a file in the &lt;span class="sb"&gt;`_posts`&lt;/span&gt; directory that follows the convention &lt;span class="sb"&gt;`YYYY-MM-DD-name-of-post.ext`&lt;/span&gt; and includes the necessary front matter. Take a look at the source for this post to get an idea about how it works.

Jekyll also offers powerful support for code snippets:

{% highlight ruby %}
def print_hi(name)
  puts "Hi, #{name}"
end
print_hi('Tom')
&lt;span class="gh"&gt;#=&amp;gt; prints 'Hi, Tom' to STDOUT.&lt;/span&gt;
{% endhighlight %}

Check out the &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Jekyll docs&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="ss"&gt;jekyll-docs&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; for more info on how to get the most out of Jekyll. File all bugs/feature requests at &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Jekyll’s GitHub repo&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="ss"&gt;jekyll-gh&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;. If you have questions, you can ask them on &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Jekyll Talk&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="ss"&gt;jekyll-talk&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;.

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;jekyll-docs&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="sx"&gt;https://jekyllrb.com/docs/home&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;jekyll-gh&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;   &lt;span class="sx"&gt;https://github.com/jekyll/jekyll&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;jekyll-talk&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="sx"&gt;https://talk.jekyllrb.com/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's a lot of useful information in this template, so give that a read if you're interested. But note once again the front matter block at the top of the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;post&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Welcome&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Jekyll!"&lt;/span&gt;
&lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;   &lt;span class="s"&gt;2020-02-14 07:40:59 -0500&lt;/span&gt;
&lt;span class="na"&gt;categories&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jekyll update&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time, we define variables for the title of the post, the date when the post was published, and any categories that this post belongs to. We've also declared its layout (but again, that layout file does not yet exist, so it has no effect). All of these variables can be used later on to customize our post pages, like showing the post title in the browser tab. You can learn more about how to use front matter in the &lt;a href="https://jekyllrb.com/docs/front-matter/"&gt;Jekyll docs&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Front Matter Defaults
&lt;/h4&gt;

&lt;p&gt;So far, we've seen two pages that have used the &lt;a href="https://jekyllrb.com/docs/front-matter/#predefined-global-variables"&gt;predefined global variable&lt;/a&gt; named &lt;code&gt;layout&lt;/code&gt;, even though we don't yet know what this does or what layouts are in Jekyll.&lt;/p&gt;

&lt;p&gt;The starter post that we saw earlier has a layout of &lt;code&gt;post&lt;/code&gt;. Surely all of our other posts should have it too, right? If a layout defines the structure of a page, then we'd ideally want all of our blog posts to have the same structure or "skeleton." But do we really have to repeat &lt;code&gt;layout: post&lt;/code&gt; in each post's front matter block?&lt;/p&gt;

&lt;p&gt;Nope! Open up your &lt;code&gt;_config.yml&lt;/code&gt;, and add this YAML somewhere (anywhere):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;defaults&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt;
    &lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;posts&lt;/span&gt;
      &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;_posts&lt;/span&gt;
    &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;isPost&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;post&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt;
    &lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pages&lt;/span&gt;
      &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;_pages&lt;/span&gt;
    &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;isPost&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
      &lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then restart your server.&lt;/p&gt;

&lt;p&gt;Jekyll allows you to define &lt;strong&gt;front matter defaults&lt;/strong&gt; like we've done here by scope, which you can narrow down using either a path or file type. The above defaults are equivalent to doing this manually in each post that we create under &lt;code&gt;_posts/&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_posts/2020-02-14-an-awesome-post.md&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;isPost&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;post&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And doing this manually for each page—like our home page, experience page, contact page, and so on—that we create under a directory named &lt;code&gt;_pages/&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_pages/contact.md&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;isPost&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a common pattern that you'll run into in Jekyll: If you find yourself repeating something tediously, there's probably a better, less redundant way to do it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Do I Put My Pages in Jekyll?
&lt;/h2&gt;

&lt;p&gt;This is one of the first questions I asked when I was just getting started with Jekyll, and it's one that I hope to answer here in as much detail as possible.&lt;/p&gt;

&lt;p&gt;We've already seen that our posts go under &lt;code&gt;_posts/&lt;/code&gt;. So where do our files go for things like the landing page, an experience page, a blog page, or a contact page?&lt;/p&gt;

&lt;p&gt;By default, Jekyll looks for all of your site's pages at the root of your project directory. This is to ensure that, for example, &lt;code&gt;index.html&lt;/code&gt; appears under &lt;code&gt;_site/index.html&lt;/code&gt; once your site is built, as we saw in the previous section.&lt;/p&gt;

&lt;p&gt;The Jekyll starter already comes with two such files at the root of the project: &lt;code&gt;index.md&lt;/code&gt; (which gets compiled to &lt;code&gt;index.html&lt;/code&gt;) and &lt;code&gt;about.md&lt;/code&gt; (which gets compiled to &lt;code&gt;about.html&lt;/code&gt;). However, as you can imagine, dumping all of your non-post page files into the root of the project directory is not ideal if you want to keep things organized, especially if you end up having lots of pages. So instead, we can store our pages in a custom &lt;code&gt;_pages/&lt;/code&gt; directory and tell Jekyll where to look for them.&lt;/p&gt;

&lt;p&gt;First, create this directory, either via a UI or Bash:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;_pages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After doing that, go ahead and move &lt;code&gt;index.md&lt;/code&gt; and &lt;code&gt;about.md&lt;/code&gt; into this directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── _pages      
│   ├── about.md
│   └── index.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you should see the following page instead of the &lt;code&gt;index.html&lt;/code&gt; from earlier:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zb3G26-n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/webrick.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zb3G26-n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/webrick.PNG" alt="The WEBrick server for our Jekyll site." width="880" height="319"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hmm... Our &lt;code&gt;index.html&lt;/code&gt; and &lt;code&gt;about.html&lt;/code&gt; pages have vanished! Plus, our newly created &lt;code&gt;_pages/&lt;/code&gt; directory is nowhere to be found. The latter behavior is expected because the directory has a leading underscore—and if you'll recall, Jekyll doesn't process those kinds of directories unless you tell it to.&lt;/p&gt;

&lt;p&gt;It's not Jekyll's fault that our two pages disappeared—we didn't tell it where to look for those files after we moved them to our custom &lt;code&gt;_pages/&lt;/code&gt; directory. So when we request &lt;code&gt;index.html&lt;/code&gt; by visiting our localhost's root, we're just given the &lt;code&gt;_site/&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;Open up your &lt;code&gt;_config.yml&lt;/code&gt; and add this line somewhere:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;_pages&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command defines an array of directories that Jekyll should process when it goes to build your site. In this case, we've defined an array of just one directory: &lt;code&gt;_pages/&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The opposite of &lt;code&gt;include&lt;/code&gt; is, as expected, &lt;code&gt;exclude&lt;/code&gt;. Check out the commented block at the very bottom of your &lt;code&gt;_config.yml&lt;/code&gt;, and you'll see that some files, like &lt;code&gt;Gemfile&lt;/code&gt; and others, are excluded from processing by default. You can exclude other files by explicitly defining an &lt;code&gt;exclude&lt;/code&gt; list.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now let's restart the server:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5zV2VvWn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/webrick2.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5zV2VvWn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/webrick2.PNG" alt="The WEBrick server for our Jekyll site." width="880" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Okay, it looks like that added &lt;code&gt;_pages/&lt;/code&gt; to our build directory, and we can now see an &lt;code&gt;about/&lt;/code&gt; directory that presumably stores our about page. But it's still not serving our index properly when we visit &lt;code&gt;localhost:4000&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The final step is to &lt;a href="https://jekyllrb.com/docs/permalinks/"&gt;specify permalinks to our pages&lt;/a&gt; using a predefined front matter variable named &lt;code&gt;permalink&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_pages/index.md&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;permalink&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gh"&gt;# Hello, Jekyll!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you open up &lt;code&gt;about.md&lt;/code&gt;, you'll notice that it already had a relative permalink defined in its front matter block:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_pages/about.md&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;page&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;About&lt;/span&gt;
&lt;span class="na"&gt;permalink&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/about/&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

This is the base Jekyll theme. You can find out more info about customizing your Jekyll theme, as well as basic Jekyll usage documentation at &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;jekyllrb.com&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://jekyllrb.com/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

You can find the source code for Minima at GitHub:
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;jekyll&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="ss"&gt;jekyll-organization&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; /
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;minima&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://github.com/jekyll/minima&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

You can find the source code for Jekyll at GitHub:
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;jekyll&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="ss"&gt;jekyll-organization&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; /
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;jekyll&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://github.com/jekyll/jekyll&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="sb"&gt;


&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;jekyll-organization&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="sx"&gt;https://github.com/jekyll&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This explains why we saw the &lt;code&gt;about/&lt;/code&gt; directory in an earlier screenshot.&lt;/p&gt;

&lt;p&gt;Save your changes, and Jekyll will rebuild the &lt;code&gt;_site/&lt;/code&gt; directory. If you refresh &lt;code&gt;localhost:4000&lt;/code&gt;, you should see the &lt;code&gt;Hello, Jekyll&lt;/code&gt; heading that we created before.&lt;/p&gt;

&lt;p&gt;If you want to navigate to the About page, simply add &lt;code&gt;/about/&lt;/code&gt; to the end of &lt;code&gt;localhost:4000&lt;/code&gt; in your browser's navigation bar. Or you can use navigation links on your page:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_pages/index.md&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;permalink&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gh"&gt;# Hello, Jekyll!&lt;/span&gt;

Check out these other pages:
&lt;span class="p"&gt;
-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;About&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;/about/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Bs0h9WYS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/about.GIF" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Bs0h9WYS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/about.GIF" alt="Navigating to the About page." width="880" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Awesome! To make sure you understand how all of this works under the hood, let's take a peek at the &lt;code&gt;_site/&lt;/code&gt; directory that Jekyll generated for us automatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_site
├── 404.html
├── about
│   └── index.html
├── feed.xml
├── index.html
└── jekyll
    └── update
        └── 2020
            └── 02
                └── 14
                    └── welcome-to-jekyll.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Interesting! Now you can continue creating other pages using Markdown under &lt;code&gt;_pages/&lt;/code&gt;, remembering to add permalinks to each one—like &lt;code&gt;/experience/&lt;/code&gt;, &lt;code&gt;/contact/&lt;/code&gt;, and so on. Jekyll will generate separate directories for each of these pages under &lt;code&gt;_site/&lt;/code&gt; using your specified permalinks, just like it did with &lt;code&gt;about/&lt;/code&gt;, and plop in an &lt;code&gt;index.html&lt;/code&gt; with your compiled Markdown. You'll then be able to navigate to each page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Jekyll Blog Posts
&lt;/h2&gt;

&lt;p&gt;I want to take a second to demystify some things about blog posts in Jekyll. Most of the lessons here carry over from what we learned about pages; we're just building on what we already know.&lt;/p&gt;

&lt;h3&gt;
  
  
  Permalinks to Blog Posts in Jekyll
&lt;/h3&gt;

&lt;p&gt;We can give each blog post a permalink, too, just like we did with our pages above. But again, we don't want to have to repeat this every single time we create a post. Let's add a permalink to the defaults in our &lt;code&gt;_config.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;defaults&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt;
    &lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;posts&lt;/span&gt;
      &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;_posts&lt;/span&gt;
    &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;isPost&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;post&lt;/span&gt;
      &lt;span class="na"&gt;permalink&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/blog/:categories/:title/&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt;
    &lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pages&lt;/span&gt;
      &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;_pages&lt;/span&gt;
    &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;isPost&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
      &lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the first instance where we see other front matter variables being referenced. In this case, we reference the &lt;code&gt;categories&lt;/code&gt; and &lt;code&gt;title&lt;/code&gt; variables defined by each post and use those to create a permalink to each blog post:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;permalink&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/blog/:categories/:title/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recall that the starter blog post defines two categories, &lt;code&gt;jekyll&lt;/code&gt; and &lt;code&gt;update&lt;/code&gt;, plus the title &lt;code&gt;Welcome to Jekyll!&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_posts/2020-02-14-welcome-to-jekyll.markdown&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;post&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Welcome&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Jekyll!"&lt;/span&gt;
&lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;   &lt;span class="s"&gt;2020-02-14 07:40:59 -0500&lt;/span&gt;
&lt;span class="na"&gt;categories&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jekyll update&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So now, if we navigate to &lt;code&gt;localhost:4000/blog/jekyll/update/welcome-to-jekyll&lt;/code&gt;, we should see the blog post:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--isxy7crb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/post.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--isxy7crb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/post.PNG" alt="A sample blog post." width="880" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Below is the updated &lt;code&gt;_site/&lt;/code&gt; directory. Notice that now, instead of creating subdirectories for the year, month, and day when a post was published, Jekyll creates subdirectories by nesting categories, then creating one more directory with the post title, and finally placing &lt;code&gt;index.html&lt;/code&gt; in there:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_site
├── 404.html
├── about
│   └── index.html
├── blog
│   └── jekyll
│       └── update
│           └── welcome-to-jekyll
│               └── index.html
├── feed.xml
└── index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  You Don't Need an Explicit Date Variable
&lt;/h3&gt;

&lt;p&gt;The example blog post that Jekyll created for us has this date in its front matter block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="c1"&gt;#...&lt;/span&gt;
&lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;   &lt;span class="s"&gt;2020-02-14 07:40:59 -0500&lt;/span&gt;
&lt;span class="c1"&gt;#...&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even though you are free to define a date explicitly like this, you don't actually &lt;em&gt;need&lt;/em&gt; to. By default, Jekyll expects your blog post files to use this naming convention and extracts the date information from it, using that date to sort your posts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yyyy-mm-dd-title-of-the-post-slugged.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: A "slugged" title is in all lowercase, with all special characters removed, and with hyphens in place of whitespace. Jekyll extracts the title information from your file name. But you often want to define the title explicitly in the post's front matter block because it may contain special characters, like colons, exclamation marks, question marks, apostrophes, and so on.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So the &lt;code&gt;date&lt;/code&gt; front matter variable is in fact redundant because we already have &lt;code&gt;2020-02-14&lt;/code&gt; in the file name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2020-02-14-welcome-to-jekyll.markdown
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's try an experiment. Remove the date from the post's front matter, and replace the file with this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_posts/2020-02-14-welcome-to-jekyll.markdown&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Welcome&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Jekyll!"&lt;/span&gt;
&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;post&lt;/span&gt;
&lt;span class="na"&gt;categories&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jekyll update&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

Welcome to my post! This was published on {{ page.date }}.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open up the post on your local to see the result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2onRKUQi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/date.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2onRKUQi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/date.PNG" alt="A sample blog post showing its date in the body." width="880" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is our first look at the syntax of Liquid, the templating language that Jekyll uses to make development easier. You'll see that &lt;code&gt;page.date&lt;/code&gt; is among the list of &lt;a href="https://jekyllrb.com/docs/variables/#page-variables"&gt;page variables in Jekyll&lt;/a&gt;, among many others that you can use.&lt;/p&gt;

&lt;h3&gt;
  
  
  Blog Post Front Matter Variables
&lt;/h3&gt;

&lt;p&gt;There are three predefined variables unique to Jekyll blog posts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;date&lt;/code&gt;: The date when the post was published. If you set this variable, it will override the date in your file name. As we saw earlier, you don't have to specify this if your file name already has the date in it.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;category&lt;/code&gt; and &lt;code&gt;categories&lt;/code&gt;: Specify the category or categories, respectively, to which the blog post belongs. Categories can be used for grouping related blog posts in Jekyll.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tags&lt;/code&gt;: Tags are very similar to categories in Jekyll. In fact, there's barely any difference between the two.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, this blog post that you're reading was written in Markdown and uses the following front matter variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Creating&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Static&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Site&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Jekyll&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;GitHub&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Pages:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;A&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Comprehensive&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Beginner's&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Guide"&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Jekyll is a static site generator that makes it easy for you to create a website and blog. If you're interested in getting started with Jekyll, this in-depth guide is for you.&lt;/span&gt;
&lt;span class="na"&gt;keywords&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;jekyll and github pages&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;getting started with jekyll&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;dev&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;jekyll&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;frontend&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;github&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of these four variables, only &lt;code&gt;tags&lt;/code&gt; is a predefined one that Jekyll recognizes and processes. The rest—like &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;description&lt;/code&gt;, and &lt;code&gt;keywords&lt;/code&gt;—are for SEO and allow me to customize my page's &lt;code&gt;head&lt;/code&gt; block using some Liquid templating. If you scroll to the top of this post, you'll see that I've used the &lt;code&gt;tags&lt;/code&gt; variable to create some clickable tag elements under the post's title.&lt;/p&gt;

&lt;h3&gt;
  
  
  Syntax Highlighting
&lt;/h3&gt;

&lt;p&gt;Since blog posts use Markdown, and Markdown has support for code blocks, you get syntax highlighting support out of the box with Jekyll.&lt;/p&gt;

&lt;p&gt;Older versions of Jekyll used Pygments as the primary syntax highlighter, but now Jekyll uses Rouge. Since Rouge themes are fully compatible with Pygments stylesheets, you can use &lt;a href="https://github.com/jwarby/jekyll-pygments-themes"&gt;any of the pre-existing Pygments themes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Alternatively, you can define your own syntax highlighting theme like I did. Actually, my theme uses the same colors as VS Code for consistency with my screenshots. You can define this theme anywhere in your CSS, as long as it eventually gets linked to the page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dr. Jekyll and Mr. Liquid
&lt;/h2&gt;

&lt;p&gt;We now arrive at the long-awaited topic that I've been teasing: Liquid. Fluids. &lt;em&gt;H2O&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://help.shopify.com/en/themes/liquid"&gt;Liquid&lt;/a&gt; is a &lt;em&gt;template language&lt;/em&gt; developed by Shopify with Ruby. Since Jekyll was also written in Ruby, the two are practically a match made in heaven. Here's how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You write Liquid template code in an HTML or Markdown file.&lt;/li&gt;
&lt;li&gt;When Jekyll builds your site, it processes the Liquid templates and substitutes them with actual content.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it! Liquid is super simple to use and understand. If you've ever worked with Vue, the two are fairly similar, except Liquid doesn't involve JavaScript. It's also obviously more limited.&lt;/p&gt;

&lt;p&gt;While it's technically not a "programming" language, Liquid has many familiar programming constructs. Let's review some of the features of the Liquid templating language so you know what's available to you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Types
&lt;/h3&gt;

&lt;p&gt;Strings? &lt;code&gt;"Check"&lt;/code&gt;. Numbers? &lt;code&gt;1&lt;/code&gt;. You also get Booleans, Nil, and arrays.&lt;/p&gt;

&lt;p&gt;Arrays are really powerful in Liquid because they allow you to write more reusable markup—more on that later!&lt;/p&gt;

&lt;p&gt;It's a bit tricky to give examples of any of these because they require an understanding of other Liquid concepts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Template Tags
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Template tags&lt;/strong&gt; (&lt;code&gt;{% ... %}&lt;/code&gt;) allow you to declare variables, evaluate conditions, loop over arrays, and do lots of other essential things in Liquid without any of that code actually showing up on the rendered HTML page. In other words, tags are how you embed template logic into your markup.&lt;/p&gt;

&lt;p&gt;Here's an exampe of a template tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
    &amp;lt;!-- exude awesomeness --&amp;gt;
&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;endif&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Like HTML tags, most template tags in Liquid have a matching end tag, often explicitly prefixed with &lt;code&gt;end&lt;/code&gt;. There are a few exceptions, though, like for assigning values to variables.&lt;/p&gt;

&lt;p&gt;Speaking of which...&lt;/p&gt;

&lt;h3&gt;
  
  
  Variables
&lt;/h3&gt;

&lt;p&gt;Yup, Liquid has variables! Declare them, modify them, reassign them—usual variable stuff.&lt;/p&gt;

&lt;p&gt;You use the &lt;code&gt;assign&lt;/code&gt; tag to declare, or assign a value to, a variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;assign&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;identifier&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As I mentioned in the previous section, the &lt;code&gt;assign&lt;/code&gt; tag doesn't need an explicit end tag. This is similar to self-closing vs. explicitly closed tags in HTML.&lt;/p&gt;

&lt;h3&gt;
  
  
  Control Flow
&lt;/h3&gt;

&lt;p&gt;If and case statements? You bet!&lt;/p&gt;

&lt;p&gt;For loops? Yup! Check it out:&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
{% raw %}&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;element&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;someArray&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
    &amp;lt;!-- do stuff here --&amp;gt;
&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endfor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Looping is really powerful in Liquid, and there are &lt;em&gt;lots&lt;/em&gt; of things you can do.&lt;/p&gt;

&lt;p&gt;You can limit the number of iterations, like to show only the three most recent blog posts in a teaser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;post&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;site.posts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
    &amp;lt;!-- do stuff here --&amp;gt;
&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endfor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Offset a loop at a specified index:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;element&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;someArray&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;offset&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
    &amp;lt;!-- do stuff here --&amp;gt;
&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endfor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Define a range of numbers to loop over (sort of like in Python):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;(1..3)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
    &amp;lt;h&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&amp;gt;This is an h&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; tag!&amp;lt;/h&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&amp;gt;
&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endfor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And &lt;a href="https://shopify.github.io/liquid/tags/iteration/"&gt;lots of other neat tricks&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;By the way, what's up with those double curly braces in the last example? You're about to find out!&lt;/p&gt;

&lt;h3&gt;
  
  
  Objects
&lt;/h3&gt;

&lt;p&gt;No, not like the "objects" in other types of languages.&lt;/p&gt;

&lt;p&gt;An &lt;strong&gt;object&lt;/strong&gt; in Liquid is anything &lt;code&gt;{{ in double curly braces }}&lt;/code&gt;. Objects allow you to &lt;em&gt;evaluate&lt;/em&gt; whatever expression you place inside the braces so that it renders on the page when processed, unlike anything in tags.&lt;/p&gt;

&lt;p&gt;Here's an example of looping through all of the posts in a website and rendering their titles with a Liquid object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;post&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;site.posts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
    &amp;lt;h2&amp;gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&amp;lt;/h2&amp;gt;
&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endfor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now, the earlier example should make sense:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;(1..3)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
    &amp;lt;h&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&amp;gt;This is an h&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; tag!&amp;lt;/h&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&amp;gt;
&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endfor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since objects evaluate their contents, the output will be the following HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;This is an h1 tag!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;This is an h2 tag!&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;This is an h3 tag!&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Operators
&lt;/h3&gt;

&lt;p&gt;Liquid has many of your standard comparison operators, like &lt;code&gt;==&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;=&lt;/code&gt;, and so on, as well as logical operators like &lt;code&gt;and&lt;/code&gt; and &lt;code&gt;or&lt;/code&gt;. You also have access to some special operators, like &lt;code&gt;contains&lt;/code&gt;, for operating on strings, as well as &lt;code&gt;in&lt;/code&gt; for iterating over arrays (which we've already seen).&lt;/p&gt;

&lt;h3&gt;
  
  
  Filters
&lt;/h3&gt;

&lt;p&gt;Liquid also has &lt;strong&gt;filters&lt;/strong&gt;, which allow you to mutate or process data. They're like the built-in functions you get in many other languages. First comes the data you want to modify, then the piping operator (&lt;code&gt;|&lt;/code&gt;), and finally the filter itself, which may or may not take an argument.&lt;/p&gt;

&lt;p&gt;For example, you can capitalize the first character of a string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&amp;lt;li&amp;gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;capitalize&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&amp;lt;/li&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that this doesn't require any arguments.&lt;/p&gt;

&lt;p&gt;Or split one string into an array of strings, using a specified delimiter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;assign&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;names&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Billy, Bob, Joel"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;', '&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&amp;lt;ul&amp;gt;
    &lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;names&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
    &amp;lt;li&amp;gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&amp;lt;/li&amp;gt;
    &lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endfor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, we put a colon after the filter name and provide an argument: the delimiter for splitting the string.&lt;/p&gt;

&lt;p&gt;We can also sort an array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;assign&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;sortedPosts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;site&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;posts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"popularity"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;popularity&lt;/code&gt; is a valid front matter variable on your posts, then this would use that attribute to sort &lt;code&gt;site.posts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Or append elements to an array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;assign&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;myArray&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Billy"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bob"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Joe"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Brittany"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And much, &lt;em&gt;much&lt;/em&gt; more. You get the idea.&lt;/p&gt;

&lt;p&gt;Seriously, Liquid is &lt;strong&gt;fantastic&lt;/strong&gt;. I highly recommend that you &lt;a href="https://shopify.github.io/liquid/"&gt;check out Shopify's documentation&lt;/a&gt; to learn more about it. Shopify has tons of code samples for every item in its API, so you can get pretty far with those alone.&lt;/p&gt;

&lt;p&gt;Just be aware that when Googling for certain things, you may need to append "shopify" to your query to avoid seeing physics results for actual &lt;em&gt;liquids&lt;/em&gt; :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Jekyll Layout Files to Structure Pages
&lt;/h2&gt;

&lt;p&gt;I mentioned layouts several times in the section on front matter variables. Now that we've covered the basics, it's time to finally understand what layouts are all about!&lt;/p&gt;

&lt;p&gt;First, let's remind ourselves of these build warnings that Jekyll has been giving us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Build Warning: Layout 'post' requested in _posts/2020-02-14-welcome-to-jekyll.markdown does not exist.
Build Warning: Layout 'default' requested in 404.html does not exist.
Build Warning: Layout 'page' requested in _pages/about.md does not exist.
Build Warning: Layout 'default' requested in _pages/index.md does not exist.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Layout files&lt;/strong&gt; are like the skeletons of your website—they define an HTML structure that's common to a group of related pages so they all look consistent, minimizing the amount of repetition that goes into developing your site. Think of a layout file as a placeholder template into which you can plug your content (or potentially nest another layout!).&lt;/p&gt;

&lt;p&gt;For example, each page needs to have a &lt;code&gt;head&lt;/code&gt; block with certain metadata, a &lt;code&gt;body&lt;/code&gt; for the content, a top (or side) navigation bar, and a sticky footer at the bottom. Many of these components remain the same as you navigate from one page to another, perhaps with slight visual differences to indicate where you currently are on the site (e.g., highlighting the current link on the navigation bar).&lt;/p&gt;

&lt;p&gt;This is a perfect use case for layouts—instead of copy-pasting the shared HTML structure each time you create a page, simply assign a layout to the pages that need it!&lt;/p&gt;

&lt;p&gt;Layout files in Jekyll are housed under the &lt;code&gt;_layouts/&lt;/code&gt; directory. Recall that this is one of those directories that Jekyll looks for automatically, assuming it exists. When you specify a &lt;code&gt;layout&lt;/code&gt; variable in a page's or blog post's front matter block, the value that you assign it needs to be the name of an existing layout file (e.g., &lt;code&gt;layout: default&lt;/code&gt; if you have a file named &lt;code&gt;_layouts/default.html&lt;/code&gt;). If that layout file in fact exists, Jekyll will take your HTML or Markdown file and plug it into the layout file's structure.&lt;/p&gt;

&lt;p&gt;It's easier to understand this with an example. If we go back to &lt;code&gt;_pages/about.md&lt;/code&gt;, we'll find a layout declared in its front matter block:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_pages/about.md&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;page&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;About&lt;/span&gt;
&lt;span class="na"&gt;permalink&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/about/&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's rename the layout to &lt;code&gt;default&lt;/code&gt;. Functionally, it doesn't make a difference what we name it, as long as there's a layout file with the same name. It's just that &lt;code&gt;default&lt;/code&gt; is more idiomatic—it's our website's "default layout."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_pages/about.md&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;About&lt;/span&gt;
&lt;span class="na"&gt;permalink&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/about/&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's do the same for &lt;code&gt;_pages/index.md&lt;/code&gt; and give the page a title as well, while we're at it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_pages/index.md&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Home&lt;/span&gt;
&lt;span class="na"&gt;permalink&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gh"&gt;# Hello, Jekyll!&lt;/span&gt;

This is the home page.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's also create two other pages, &lt;code&gt;blog.md&lt;/code&gt; and &lt;code&gt;contact.md&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_pages/blog.md&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Blog&lt;/span&gt;
&lt;span class="na"&gt;permalink&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/blog&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gu"&gt;## My Blog Posts&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
  {% for post in site.posts %}
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{ post.url }}"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"post-preview"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ post.title }}&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  {% endfor %}
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;_pages/contact.md&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Contact&lt;/span&gt;
&lt;span class="na"&gt;permalink&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/contact&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gu"&gt;## Contact&lt;/span&gt;

Get in touch!

&lt;span class="nt"&gt;&amp;lt;form&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- Form stuff --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, create the &lt;code&gt;_layouts/&lt;/code&gt; directory and add a file to it named &lt;code&gt;default.html&lt;/code&gt; with these contents:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_layouts/default.html&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;{{ page.title }} - {{ site.title }}&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;nav&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-links"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="err"&gt;{%&lt;/span&gt; &lt;span class="na"&gt;if&lt;/span&gt; &lt;span class="na"&gt;page.title =&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt; &lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="na"&gt;Home&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt; &lt;span class="err"&gt;%}&lt;/span&gt;&lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"active-page"&lt;/span&gt;&lt;span class="err"&gt;{%&lt;/span&gt; &lt;span class="na"&gt;endif&lt;/span&gt; &lt;span class="err"&gt;%}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/about"&lt;/span&gt; &lt;span class="err"&gt;{%&lt;/span&gt; &lt;span class="na"&gt;if&lt;/span&gt; &lt;span class="na"&gt;page.title =&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt; &lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="na"&gt;About&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt; &lt;span class="err"&gt;%}&lt;/span&gt;&lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"active-page"&lt;/span&gt;&lt;span class="err"&gt;{%&lt;/span&gt; &lt;span class="na"&gt;endif&lt;/span&gt; &lt;span class="err"&gt;%}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;About&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/blog"&lt;/span&gt; &lt;span class="err"&gt;{%&lt;/span&gt; &lt;span class="na"&gt;if&lt;/span&gt; &lt;span class="na"&gt;page.title =&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt; &lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="na"&gt;Blog&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt; &lt;span class="err"&gt;%}&lt;/span&gt;&lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"active-page"&lt;/span&gt;&lt;span class="err"&gt;{%&lt;/span&gt; &lt;span class="na"&gt;endif&lt;/span&gt; &lt;span class="err"&gt;%}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Blog&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/contact"&lt;/span&gt; &lt;span class="err"&gt;{%&lt;/span&gt; &lt;span class="na"&gt;if&lt;/span&gt; &lt;span class="na"&gt;page.title =&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt; &lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="na"&gt;Contact&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt; &lt;span class="err"&gt;%}&lt;/span&gt;&lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"active-page"&lt;/span&gt;&lt;span class="err"&gt;{%&lt;/span&gt; &lt;span class="na"&gt;endif&lt;/span&gt; &lt;span class="err"&gt;%}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Contact&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;main&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"page-content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        {{ content }}
    &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;footer&amp;gt;&lt;/span&gt;
        Proudly made with Jekyll
    &lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's your typical HTML file. Let's check it out:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8KOlmjA6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/default-layout.GIF" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8KOlmjA6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/default-layout.GIF" alt="The default layout." width="880" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice how we take advantage of Liquid several times to customize our pages. For example, the layout file customizes the title bar of each page using front matter variables we defined. The navigation bar applies a class of &lt;code&gt;active-page&lt;/code&gt; selectively, depending on what page we're currently on. You can then select this element with CSS and style it accordingly to make it more prominent than the other links.&lt;/p&gt;

&lt;p&gt;The most important part is &lt;code&gt;{{ content }}&lt;/code&gt;, which you should recognize to be a Liquid object. This is a reserved variable that refers to the literal contents of whatever file Jekyll is currently processing that has its &lt;code&gt;layout&lt;/code&gt; set to this layout's name. So, when Jekyll goes to process &lt;code&gt;_pages/index.md&lt;/code&gt;, encounters the layout variable, and goes to process &lt;code&gt;_layouts/default.html&lt;/code&gt;, the &lt;code&gt;content&lt;/code&gt; variable will refer to the contents of &lt;code&gt;index.md&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;One final note: If you want to change the site title that appears after the dash in the address bar, then simply change that variable in your &lt;code&gt;_config.yml&lt;/code&gt; as I mentioned before:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_config.yml&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Site settings&lt;/span&gt;
&lt;span class="c1"&gt;# These are used to personalize your new site. If you look in the HTML files,&lt;/span&gt;
&lt;span class="c1"&gt;# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on.&lt;/span&gt;
&lt;span class="c1"&gt;# You can create any custom variable you would like, and they will be accessible&lt;/span&gt;
&lt;span class="c1"&gt;# in the templates via {{ site.myvariable }}.&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Your awesome title&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using More Than One Layout
&lt;/h3&gt;

&lt;p&gt;If we open up the starter blog post that we saw earlier, you'll notice that it has a different layout set:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_posts/2020-02-14-welcome-to-jekyll.markdown&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;post&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Welcome&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Jekyll!"&lt;/span&gt;
&lt;span class="na"&gt;categories&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jekyll update&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The blog post collapses to a "flat" layout and doesn't have the same HTML structure as the other pages:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bdgTysl_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/collapsed-layout.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bdgTysl_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/collapsed-layout.PNG" alt="The starter blog post has a collapsed layout." width="880" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is because the &lt;code&gt;post&lt;/code&gt; layout doesn't exist. Let's go ahead and create this layout file. This time around, you'll notice that a layout file can itself specify a layout:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_layouts/post.html&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;---
layout: default
---

&lt;span class="nt"&gt;&amp;lt;article&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"post"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;header&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"post-header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"post-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ page.title }}&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"post-date"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ page.date | date: "%b %-d, %Y" }}&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"post-categories"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            {% for category in page.categories %}
            &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"post-category"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ category }}&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
            {% endfor %}
        &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
    {{ content }}
&lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open up the post, and you'll now see that it has the same base layout as all your other pages, but it also has a nested layout specific to blog posts:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qRbDfWOI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/post-layout.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qRbDfWOI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/post-layout.PNG" alt="The post layout." width="880" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Awesome!&lt;/p&gt;

&lt;p&gt;You've essentially mastered 90% of Jekyll at this point. Only a few topics remain!&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing CSS in Jekyll Using SASS
&lt;/h2&gt;

&lt;p&gt;What's a great site without some CSS to make it look pretty?&lt;/p&gt;

&lt;p&gt;Jekyll has &lt;a href="https://jekyllrb.com/docs/assets/"&gt;built-in support for SASS&lt;/a&gt;, a CSS preprocessor that allows you to take advantage of things like variables, mixins, functions, selector nesting, and lots more, making it easier to write maintainable stylesheets.&lt;/p&gt;

&lt;p&gt;If you don't want to use SASS, you're more than welcome to use plain CSS. The only downside is that you won't be able to take advantage of the many great features that SASS brings to the table.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modular CSS with SASS Imports
&lt;/h3&gt;

&lt;p&gt;Like pure CSS, SASS allows you to use &lt;code&gt;@import&lt;/code&gt; directives to assemble your stylesheets in a modular manner. But it's actually better because it doesn't trigger an additional HTTP call—it's merely for your convenience so you can split up your styles across well-named, more manageable files. The contents of those imports will be plugged in as-is and &lt;em&gt;then&lt;/em&gt; transpiled to CSS.&lt;/p&gt;

&lt;p&gt;It's worth noting that there are two places where it's suitable to place CSS files in Jekyll: &lt;code&gt;_sass/&lt;/code&gt; and &lt;code&gt;assets/&lt;/code&gt;. Notice that the former directory has a leading underscore, whereas the latter does not. If you'll recall, any directory in Jekyll that's preceded by an underscore will not be processed or included in the build output directory, &lt;code&gt;_site/&lt;/code&gt;. This means that if you put all of your modular stylesheets under &lt;code&gt;assets/&lt;/code&gt;, they'll get transpiled into a bunch of disjoint CSS stylesheets, whereas you really want a single stylesheet.&lt;/p&gt;

&lt;p&gt;With this in mind, a typical SASS workflow in Jekyll is to create a single file named &lt;code&gt;/assets/styles/main.scss&lt;/code&gt; (known as a &lt;strong&gt;SASS manifest&lt;/strong&gt;), store your modular stylesheets under &lt;code&gt;_sass/&lt;/code&gt;, and then consolidate all of those imports in the manifest for transpilation. The result is a single, transpiled CSS stylesheet containing all of the styles that you imported.&lt;/p&gt;

&lt;p&gt;For example, on my site, I keep my SASS manifest under &lt;code&gt;assets/styles/main.scss&lt;/code&gt;. When Jekyll compiles my site, this file becomes &lt;code&gt;_site/assets/styles/main.css&lt;/code&gt;. Then, as long as you include this stylesheet in the head of your &lt;code&gt;default&lt;/code&gt; layout, it will load on the page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/css"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/assets/styles/main.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that we reference the compiled version (&lt;code&gt;.css&lt;/code&gt;) that's going to live under &lt;code&gt;_site/&lt;/code&gt; once your site is built, not the &lt;code&gt;.scss&lt;/code&gt; version that we have access to only in the precompiled source.&lt;/p&gt;

&lt;p&gt;Meanwhile, this is what my manifest looks like:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;/assets/styles/main.scss&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nt"&gt;---&lt;/span&gt;
&lt;span class="nt"&gt;---&lt;/span&gt;

&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="nt"&gt;import&lt;/span&gt; &lt;span class="s1"&gt;'components/topnav'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;'general/themes'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;'general/general'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;'pages/index'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;'pages/experience'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;'components/cardGrid'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;'components/card'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;'pages/contact'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;'blog/posts'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;'components/button'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;'components/collapsible'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;'components/tag'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;'components/tooltip'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;'general/highlight'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;'components/footer'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The empty front matter block at the top is crucial&lt;/strong&gt;—if you don't include it, Jekyll won't process this file, and we &lt;em&gt;need&lt;/em&gt; Jekyll to process the file so that it generates &lt;code&gt;/assets/styles/main.css&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And here's what my &lt;code&gt;_sass/&lt;/code&gt; directory looks like, in case you're curious:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_sass
├── blog
│   └── posts.scss
├── components
│   ├── button.scss
│   ├── card.scss
│   ├── cardGrid.scss
│   ├── collapsible.scss
│   ├── footer.scss
│   ├── tag.scss
│   ├── tooltip.scss
│   └── topnav.scss
├── general
│   ├── general.scss
│   ├── highlight.scss
│   └── themes.scss
├── pages
│   ├── contact.scss
│   ├── experience.scss
│   └── index.scss
├── colors.scss
├── mixins.scss
└── settings.scss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creating modular stylesheets and importing them into a SASS manifest makes it much easier to find a particular style that you need to tweak. For example, if I need to adjust a style related to cards, I know I just need to open up &lt;code&gt;_sass/components/_card.scss&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's give this a shot. Create a file named &lt;code&gt;_sass/_general.scss&lt;/code&gt; with this styling (or really anything you want):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_sass/_general.scss&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;box-sizing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;border-box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;18px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Arial&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then create this file:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;assets/styles/main.scss&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nt"&gt;---&lt;/span&gt;
&lt;span class="nt"&gt;---&lt;/span&gt;

&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="nt"&gt;import&lt;/span&gt; &lt;span class="s1"&gt;'general'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once your site rebuilds, you'll find this new file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_site/assets/styles
└── main.css
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what the transpiled, minified stylesheet looks like:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_site/assets/styles/main.css&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;box-sizing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;border-box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;18px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Arial&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;Finally, don't forget to link the stylesheet to your &lt;code&gt;default.html&lt;/code&gt; layout. Just add this to your &lt;code&gt;head&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/css"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/assets/styles/main.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what your site should now look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ryse0gD0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/styled.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ryse0gD0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/styled.PNG" alt="The styled version of the site." width="880" height="266"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Need to add more styles? Simply create a new SASS stylesheet under &lt;code&gt;_sass/&lt;/code&gt;, possibly in a nested subdirectory to keep things organized, and then just import it into your manifest. It's that easy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Reusable Components with Includes
&lt;/h2&gt;

&lt;p&gt;With other static site generators like Gatsby, you can take advantage of frameworks such as React to create reusable components. But what if I told you that you can still create components in Jekyll?&lt;/p&gt;

&lt;p&gt;I'm talking about &lt;strong&gt;Jekyll includes&lt;/strong&gt;. They're a simple way to reduce repetition in your markup and to create reusable "components" that you can plug in wherever they're needed. Jekyll literally takes the contents of an include file and dumps them wherever the file was included. It's a bit more involved than that, though, because Jekyll includes can take arguments (sort of like props in React!).&lt;/p&gt;

&lt;p&gt;Includes are created under the &lt;code&gt;_includes/&lt;/code&gt; directory. An include file is simply an HTML or Markdown file like any other. The only difference is that an include file has access to a special variable named &lt;code&gt;include&lt;/code&gt;. The arguments ("props") that you pass in to an include are then accessible under &lt;code&gt;include.nameOfVariable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example, let's say you want to use tooltips on your site but don't want to have to copy-paste the same HTML each time you want to use one on a page. This is a perfect use case for includes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_includes/tooltip.html&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tooltip tooltip-{{ include.position }}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tooltip-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        {{ include.text }}
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's how we might include a tooltip in another file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;tooltip.html&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"top"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"This is a tooltip!"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The processed HTML will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tooltip tooltip-top"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tooltip-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        This is a tooltip!
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that if &lt;code&gt;var&lt;/code&gt; is not provided, &lt;code&gt;include.var&lt;/code&gt; will default to Nil (undefined).&lt;/p&gt;

&lt;p&gt;One last thing worth noting is that includes can be nested, just like layouts can be. So that means you can include as many includes as you want... in your includes 😅.&lt;/p&gt;

&lt;p&gt;Here are some example use cases for Jekyll includes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inlined SVGs&lt;/strong&gt;: You can use something like &lt;a href="https://github.com/encharm/Font-Awesome-SVG-PNG"&gt;Font-Awesome-SVG-PNG&lt;/a&gt; to find SVG icons that you want to use on your site and stick those in an include file. That include could take two arguments: the name of the SVG and an optional class name to apply to it. You can then insert SVGs into any of your pages, without having to copy-paste a huge chunk of HTML.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lazily loaded, WebP-compatible images and thumbnails&lt;/strong&gt;. On my website, I have an include that allows me to conveniently insert images into my blog posts with just a single, legible line of markup. You can learn more about how I do this in my blog post on &lt;a href="https://aleksandrhovhannisyan.github.io/blog/dev/improve-page-load-speed-in-jekyll-using-the-webp-image-format/"&gt;using WebP images in Jekyll&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Post statistics&lt;/strong&gt;. On my blog, each post shows the date when it was published and a measure of its reading length. This appears on both the preview cards for the posts as well as in the posts themselves. I &lt;em&gt;could&lt;/em&gt; copy-paste the same markup in both locations, but if I need to change something later on, I'd need to remember to update it in both pages. Instead, I just create an include file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fair use disclosures&lt;/strong&gt;. Some of my blogs use images from the web for which I do not own the rights. Even though I always disclose the source of these images, Wikipedia still advises that you add a fair-use disclosure to your site as an additional protection against any copyright strikes. I don't find myself needing to use this very often, but when I do, I can simply drop in the include without having to copy-paste a wall of text.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project cards&lt;/strong&gt;. My projects appear in two locations on this site: Once on the landing page, with a limited set of featured projects, and again on the Experience page, with the full set of projects. Once again, I can abstract away this component in its own include file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Linked headings&lt;/strong&gt;. I wrote an article on how you can &lt;a href="https://aleksandrhovhannisyan.github.io/blog/dev/create-heading-links-in-jekyll-without-any-javascript-using-includes/"&gt;create linked headings in Jekyll&lt;/a&gt; that goes into this in more depth. But basically, you can set up a simple include file that takes the name of a heading you want to create and the level of the heading and turns it into an anchor heading that users can click.&lt;/p&gt;

&lt;p&gt;There's a &lt;em&gt;lot&lt;/em&gt; more you can do with includes, but hopefully this gives you a good idea of what's possible!&lt;/p&gt;

&lt;h2&gt;
  
  
  Taking Advantage of Jekyll Data Files
&lt;/h2&gt;

&lt;p&gt;Consider your online resume or personal website: You likely want to have a page, or at least a section of a page, dedicated to your projects, skills, education, work history, and any relevant hobbies or interests. &lt;em&gt;Within&lt;/em&gt; each of those categories, you'll probably have multiple entries, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lots of different skills, possibly grouped into distinct categories.&lt;/li&gt;
&lt;li&gt;Open-source (or not) projects and other samples of work that you'd like to showcase.&lt;/li&gt;
&lt;li&gt;(Possibly) multiple degrees, specializations, or certifications.&lt;/li&gt;
&lt;li&gt;(Most likely) multiple jobs as part of your work history.&lt;/li&gt;
&lt;li&gt;Social media links, each with an icon, the platform name, and a URL to your profile.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's a mockup for two of those:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bUummobp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/mockup.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bUummobp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/mockup.PNG" alt="Mockups of project cards and skills" width="880" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You get the general idea—all websites have static, mostly unchanging data that is often repeated in slightly different ways while retaining the same underlying &lt;em&gt;structure&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I'll refer to all of these examples, and any others that fit the bill, as your &lt;strong&gt;site data&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The naive approach to represent site data on a page involves manually defining the markup for every single skill, project, and so on. Got multiple skills? Create a div for one and copy-paste it to create the others. You could certainly minimize some of the repetition here with an include, but you'd still have to copy-paste the include directive itself, and that's not ideal.&lt;/p&gt;

&lt;p&gt;This approach has two glaring problems: repetition and poor legibility. Instead of defining the structure once with a template and simply plugging in the data, you end up copy-pasting the same structure and &lt;em&gt;manually&lt;/em&gt; changing the data. Suppose you need to update a skill and increase its rating—you now have to track down that particular skill in a sea of HTML and copy-paste some SVGs to get the job done.&lt;/p&gt;

&lt;p&gt;This issue is fundamentally about a &lt;strong&gt;separation of concerns&lt;/strong&gt;—your data exists independently of however you decide to structure it at the end of the day. So why marry the two inextricably and make your life more difficult than it needs to be? Keep your data separate from the UI that displays it—you'll be happy that you did.&lt;/p&gt;

&lt;p&gt;You do that in Jekyll by creating &lt;strong&gt;data files&lt;/strong&gt; under the aptly named &lt;code&gt;_data/&lt;/code&gt; directory. Data files can use YAML, JSON, or CSV to define just that—your website's raw data, &lt;em&gt;without&lt;/em&gt; the associated HTML markup.&lt;/p&gt;

&lt;p&gt;Once you've created a data file in Jekyll, it becomes accessible under &lt;code&gt;site.data.fileName&lt;/code&gt; across your entire site, in all HTML and Markdown files. But obviously, you're most likely only going to use it on a single page, like an Experience page for projects and skills.&lt;/p&gt;

&lt;p&gt;You can then loop over that data using Liquid tags and finally give the data its structure. The key benefit here is that you only need to &lt;strong&gt;define the structure once&lt;/strong&gt;; the data merely gets plugged into your templates when Jekyll goes to process your HTML or Markdown files. You can combine data files with includes to take your experience with Jekyll to a whole new level.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 1: Skills and Abilities
&lt;/h3&gt;

&lt;p&gt;Let's say you have a simple file named &lt;code&gt;_data/skills.yml&lt;/code&gt;. Suppose it looks something like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_data/skills.yml&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Writing&lt;/span&gt;
  &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Jekyll&lt;/span&gt;
  &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Frontend&lt;/span&gt;
  &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can access this data using &lt;code&gt;site.data.skills&lt;/code&gt;. If your YAML defines an array of skills like above, you can iterate over it and define template markup for each element:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_pages/experience.md&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&amp;lt;ul&amp;gt;
    &lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;skill&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;site.data.skills&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
    &amp;lt;li class="skill"&amp;gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;skill&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; - &lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;skill&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;rating&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&amp;lt;/li&amp;gt;
    &lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endfor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a fairly simple example—in reality, you'd probably want to do more than just render a simple list of elements. But you get the idea—once you have access to the array, you can let your creative juices flow and create all kinds of neat stuff.&lt;/p&gt;

&lt;p&gt;Also, note that you can nest arrays in YAML and in Liquid, so you could—like I do on this site—define skill &lt;em&gt;categories&lt;/em&gt; and nest the actual skills within them:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_data/skills.yml&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Blogging&lt;/span&gt;
  &lt;span class="na"&gt;skills&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Writing&lt;/span&gt;
      &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SEO&lt;/span&gt;
      &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;

&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Languages&lt;/span&gt;
  &lt;span class="na"&gt;skills&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;English&lt;/span&gt;
      &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Spanish&lt;/span&gt;
      &lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And again, we can give this data more structure:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_pages/experience.md&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;site.data.skills&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&amp;lt;h4&amp;gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;category&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&amp;lt;/h4&amp;gt;
&amp;lt;ul&amp;gt;
    &lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;skill&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;item.skills&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
    &amp;lt;li class="skill"&amp;gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;skill&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; - &lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;skill&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;rating&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&amp;lt;/li&amp;gt;
    &lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endfor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&amp;lt;/ul&amp;gt;
&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endfor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example 2: Author Bios
&lt;/h3&gt;

&lt;p&gt;Now let's suppose you run a blog that has multiple authors, not just you.&lt;/p&gt;

&lt;p&gt;You can create a data file for each author and define the path to their profile photo, their name, their bio, and a fixed set of social media links, like Twitter, GitHub, and whatnot:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_data/authors.yml&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;John Doe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;photo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;john-doe.JPG&lt;/span&gt;
  &lt;span class="na"&gt;bio&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;John is a... Well, we don't actually know what he does. Actually, we're not even sure we know who he is.&lt;/span&gt;
  &lt;span class="na"&gt;socials&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Twitter&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://twitter.com/realJohnDoe&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GitHub&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/JohnDoe&lt;/span&gt;

&lt;span class="na"&gt;Jane Doe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;photo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jane-doe.JPG&lt;/span&gt;
  &lt;span class="na"&gt;bio&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Jane enjoys long walks on the beach and remaining anonymous on the internet, like 100% of the human population.&lt;/span&gt;
  &lt;span class="na"&gt;socials&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Twitter&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://twitter.com/datJaneDoeDoe&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GitHub&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/JaneDoe&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how your Jekyll data files can be as complex as you need, with nested arrays.&lt;/p&gt;

&lt;p&gt;Let's assume each post defines an author in its front matter:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_posts/2020-02-13-a-really-awesome-post.md&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;A Really Awesome Post&lt;/span&gt;
&lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Jane Doe&lt;/span&gt;
&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;post&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

Usual lorem ipsum stuff.

The end!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now add a bio at the end of each post, ideally in the &lt;code&gt;post.html&lt;/code&gt; layout file so we don't have to repeat it for every single post that we publish:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_layouts/post.html&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;---
layout: default
---

&lt;span class="nt"&gt;&amp;lt;article&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"post"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    {{ content }}
&lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;

{% assign authorData = site.data.authors[page.author] %}
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"author-bio"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/assets/img/authors/{{ authorData.image }}"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"{{ page.author }}'s profile picture."&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"author-name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ page.author }}&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bio"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ authorData.bio }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    {% for social in authorData.socials %}
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{ social.url }}"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"social-link {{ social.type }}-link"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ social.type }}&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    {% endfor %}
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jekyll will process these templates, use the author's name as a key into the &lt;code&gt;authors.yml&lt;/code&gt; data file, retrieve the relevant information about that author, and substitute it into the template. How cool is that?&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 3: Tag Descriptions
&lt;/h3&gt;

&lt;p&gt;Let's say each post on your site has tags, like the ones on my blog:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Jekyll Is Amazing&lt;/span&gt;
&lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;dev&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;jekyll&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you want to assign descriptions to each tag to dynamically update a page's description based on which tag a user selected. This is what I currently do on my website for the four primary topics I like to write about (dev, CS theory, gaming, and music).&lt;/p&gt;

&lt;p&gt;Create a data file named &lt;code&gt;tagDescriptions.yml&lt;/code&gt; (or something else) and define key-value pairs in the YAML, where the key is the tag name and the value is the description for that particular tag:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_data/tagDescriptions.yml&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;dev&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Technical posts. Yay dev!&lt;/span&gt;
&lt;span class="na"&gt;life&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;As in, the thing I like to pretend to have...&lt;/span&gt;
&lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;This is a tag. How exciting!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, you can once again take advantage of YAML's associative data nature to assign descriptions to each tag:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;_layouts/blog.html&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;site.tags&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&amp;lt;a 
    class="tag" 
    href="/tag/&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;"
    title="&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;site&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;tagDescriptions&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;"&amp;gt;
    &lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&amp;lt;/a&amp;gt;
&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endfor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neat, right? You can extend this to a lot of other use cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up Google Search Console
&lt;/h2&gt;

&lt;p&gt;So you've started blogging with Jekyll. Awesome work!&lt;/p&gt;

&lt;p&gt;But how do you know if you're getting any traffic, or what pages people are clicking, or what queries they're using to find you? What devices are being used? Are most of your users on mobile or desktop? What about your impressions, click count, click-through rate, and overall ranking on Google?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EUULqlTN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/google-search-console.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EUULqlTN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/google-search-console.PNG" alt="Google Search Console statistics for my site." width="880" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're a complete beginner getting started with Jekyll and don't yet have much (or any) traffic to your website, this should be the least of your concerns. Focus first and foremost on creating quality content, and then go ahead and set this up so you can grow your blog.&lt;/p&gt;

&lt;p&gt;If you want to track these metrics so you can work on your blog's SEO, then you'll need to set up a Google Search Console account, claim your website as a property, and push a tracking file to your project that Google will provide you. &lt;strong&gt;This entire process is free&lt;/strong&gt;, so there's no good reason not to set it up!&lt;/p&gt;

&lt;p&gt;First, head on over to the &lt;a href="https://search.google.com/search-console/welcome"&gt;Google Search Console&lt;/a&gt; website and log in with your Google account.&lt;/p&gt;

&lt;p&gt;Once you've done that, click &lt;code&gt;Add property&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--elxDUir7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/add-property.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--elxDUir7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/add-property.PNG" alt="Adding a Google Search Console property." width="880" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When prompted to select a property type, choose the &lt;code&gt;URL prefix&lt;/code&gt; option and enter the full URL of your site on GitHub Pages:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--n6g9WO-7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/property-type.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n6g9WO-7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/property-type.PNG" alt="Selecting the type of property in Google Search Console." width="880" height="691"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll be asked to verify that you are in fact the owner of this website. Google generates a unique file that you'll need to download, add to your website's repo, and push to GitHub:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gE1MJckw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/verify-ownership.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gE1MJckw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/creating-a-personal-website-with-jekyll-and-github-pages-a-comprehensive-guide/verify-ownership.PNG" alt="Verify ownership of your Google Search Console property." width="880" height="842"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub Pages will then build your site and make this file accessible to Google for verification. Once you've uploaded the file, click &lt;code&gt;Verify&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is It Safe to Upload the Google Search Console Verification File?
&lt;/h3&gt;

&lt;p&gt;Don't worry—&lt;a href="https://stackoverflow.com/questions/57384269/github-pages-blog-and-google-search-console-is-it-safe-to-follow-these-steps-fo"&gt;there's no security risk associated with doing this&lt;/a&gt;. The file can only be used for verifying ownership, not authentication. So if someone downloads your file and tries to use it, they won't be able to access your Google Search Console statistics or anything else associated with your Google Account.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Pages Support for Jekyll Plugins
&lt;/h2&gt;

&lt;p&gt;The great thing about Jekyll is that it has a large open-source community of creators who publish &lt;strong&gt;Jekyll plugins&lt;/strong&gt;. These are just Ruby gems that extend the functionality of Jekyll and make your life easier.&lt;/p&gt;

&lt;p&gt;The bad news? GitHub Pages &lt;a href="https://pages.github.com/versions/"&gt;only supports a limited set of plugins&lt;/a&gt;. This means that if you decide to use Jekyll plugins that are not supported by GitHub Pages, they'll work on your localhost but not when you push your site to GitHub.&lt;/p&gt;

&lt;p&gt;If you absolutely need to use a plugin for a feature on your Jekyll website, then you'll need to push just the &lt;code&gt;_site/&lt;/code&gt; directory to GitHub instead of pushing your source files. Basically, you'd bypass the build step on GitHub Pages and just publish your static site directly on the web server.&lt;/p&gt;

&lt;p&gt;Understandably, this may not be ideal if you want people (e.g., recruiters or other developers) to see your site's source and how you organized your project. So sometimes, you may need to reinvent the wheel to add a new feature to your site.&lt;/p&gt;

&lt;p&gt;You can learn more about this issue and its workarounds in &lt;a href="https://stackoverflow.com/a/31871892/5323344"&gt;this StackOverflow thread&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  You're All Set!
&lt;/h2&gt;

&lt;p&gt;Give yourself a big pat on the back—if you made it to the end of this post, then you have a working website and a solid understanding of some Jekyll (and liquid) fundamentals 🎉.&lt;/p&gt;

&lt;p&gt;We covered a &lt;em&gt;lot&lt;/em&gt; in this tutorial—all the way from installing Jekyll and setting up GitHub Pages to creating pages, blog posts, layouts, includes, stylesheets, data files... Oh my!&lt;/p&gt;

&lt;p&gt;If there's anything that this post didn't cover that you'd like to learn more about, you'll most certainly find info about it in the official Jekyll documentation.&lt;/p&gt;

&lt;p&gt;I hope you found this tutorial helpful! If you notice any bugs or typos, or if you have any suggestions for improving this post, please do let me know!&lt;/p&gt;

</description>
      <category>jekyll</category>
      <category>github</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Finite State Machine (FSM) Tutorial: Implementing an FSM in C++</title>
      <dc:creator>Aleksandr Hovhannisyan</dc:creator>
      <pubDate>Sun, 23 Feb 2020 13:36:26 +0000</pubDate>
      <link>https://dev.to/aleksandrhovhannisyan/finite-state-machine-fsm-tutorial-implementing-an-fsm-in-c-2cgo</link>
      <guid>https://dev.to/aleksandrhovhannisyan/finite-state-machine-fsm-tutorial-implementing-an-fsm-in-c-2cgo</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This is a syndicated post. If you'd like to, you can &lt;a href="https://www.aleksandrhovhannisyan.com/blog/dev/finite-state-machine-fsm-tutorial-implementing-an-fsm-in-c/" rel="noopener noreferrer"&gt;view the original on my dev blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Finite state machines (FSMs) are used in lots of different situations to model complex entity state. They're especially relevant in game dev for modeling dynamic AI behavior and decision-making. Here's a very rough sketch of what a finite state machine might look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Faleksandrhovhannisyan.github.io%2Fassets%2Fimg%2Fposts%2Ffinite-state-machine-fsm-tutorial-implementing-an-fsm-in-c%2Ffsm.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Faleksandrhovhannisyan.github.io%2Fassets%2Fimg%2Fposts%2Ffinite-state-machine-fsm-tutorial-implementing-an-fsm-in-c%2Ffsm.JPG" alt="A finite state machine representation."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An entity may transition from one state to another, or it may remain in its current state. The arrows denote transitions. The conditions under which a transition should take place will need to be coded into the FSM itself.&lt;/p&gt;

&lt;p&gt;In this finite state machine tutorial, I'll help you understand the state design pattern by building an FSM from the ground up for a simple problem, using C++ as the primary development language. However, note that you could just as well use a different object-oriented language, like Java or Python. Let's get started!&lt;/p&gt;

&lt;h2&gt;
  
  
  Finite State Machine Use Case: Modeling a Lightbulb
&lt;/h2&gt;

&lt;p&gt;Suppose we have a lightbulb that can have the following states:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Off&lt;/li&gt;
&lt;li&gt;Low&lt;/li&gt;
&lt;li&gt;Medium&lt;/li&gt;
&lt;li&gt;High&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can model this using an enum.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;LightState.h&lt;/code&gt;:&lt;/p&gt;

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

&lt;span class="cp"&gt;#pragma once
&lt;/span&gt;
&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LightState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Off&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Medium&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;High&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Every light is initially off. Calling a light's &lt;code&gt;toggle&lt;/code&gt; method should advance it to the next state. A light that is off goes to low when toggled. A light that is low goes to medium. And so on. When we toggle a light that is high, it cycles back to off. How would you implement this?&lt;/p&gt;

&lt;p&gt;This is actually a question I once encountered during an interview. It's a really great problem because there isn't just a single solution—you can do this in many creative ways. The most basic solution uses the modulo operator and cycles through an array of states, using an index to keep track of the current state.&lt;/p&gt;

&lt;p&gt;However, I'd like to use this problem to introduce something called the &lt;strong&gt;finite state design pattern&lt;/strong&gt;. It's not &lt;em&gt;needed&lt;/em&gt; to solve this particular problem, but it's definitely useful. And it's also a good way to understand how finite state machines work. In practice, they are used to model more complex situations than just a lightbulb.&lt;/p&gt;

&lt;p&gt;We'll look at two approaches to this problem. Let's get to it!&lt;/p&gt;

&lt;h2&gt;
  
  
  Approach #1: Using a State Transition Table (Map)
&lt;/h2&gt;

&lt;p&gt;Usually, whenever you can model a scenario with finite state machines, you can also model it with a simple &lt;strong&gt;state transition table&lt;/strong&gt; that literally just maps the current state to the next state.&lt;/p&gt;

&lt;p&gt;So, we'll model our light's state transitions with an actual map data structure, where the key is the current state and the value is the next state.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;LightState.h&lt;/code&gt;:&lt;/p&gt;

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

&lt;span class="cp"&gt;#pragma once
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;map&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LightState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Off&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Medium&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;High&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;lightTransitions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Off&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Low&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Medium&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Medium&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;High&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;High&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Off&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Let's also create our simple &lt;code&gt;Light&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Light.h&lt;/code&gt;:&lt;/p&gt;

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

&lt;span class="cp"&gt;#pragma once
#include&lt;/span&gt; &lt;span class="cpf"&gt;"LightState.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Light&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
    &lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="n"&gt;LightState&lt;/span&gt; &lt;span class="n"&gt;getCurrentState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;currentState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;LightState&lt;/span&gt; &lt;span class="n"&gt;currentState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;Light.cpp&lt;/code&gt;:&lt;/p&gt;

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

&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"Light.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;currentState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Off&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;currentState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lightTransitions&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;currentState&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;As I mentioned earlier, a Light starts in the off state. Calling the &lt;code&gt;toggle&lt;/code&gt; method advances the light to its next state, using the &lt;code&gt;lightTransitions&lt;/code&gt; transition table.&lt;/p&gt;

&lt;p&gt;Easy enough, right?&lt;/p&gt;

&lt;h3&gt;
  
  
  State Transition Table Drawbacks
&lt;/h3&gt;

&lt;p&gt;Now, we arrive at one of the limitations of a state transition table: What if we want to perform a certain action when we arrive at the next state, or before we leave the current state?&lt;/p&gt;

&lt;p&gt;For example, maybe we want to toggle the intensity of the lightbulb with each state transition, play a sound, or use some other effects unique to a state.&lt;/p&gt;

&lt;p&gt;We could certainly do this—just add some code before and after the line where we're changing the state.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Light.cpp&lt;/code&gt;:&lt;/p&gt;

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

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;toggle&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 here before the transition&lt;/span&gt;
    &lt;span class="n"&gt;currentState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lightTransitions&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;currentState&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="c1"&gt;// ... do something here after the transition&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;But usually, the actions that we want to take before and after a state transition are &lt;em&gt;state dependent&lt;/em&gt;. This means that we'll need to use a &lt;code&gt;switch&lt;/code&gt; statement, or a bunch of conditionals, to check what state we're currently in so we can act accordingly. That will become very difficult to maintain if the number of states increases!&lt;/p&gt;

&lt;p&gt;Hmm... There's got to be a better way. (If there weren't, I wouldn't be writing this post!)&lt;/p&gt;

&lt;h2&gt;
  
  
  Approach #2: Implementing a Finite State Machine
&lt;/h2&gt;

&lt;p&gt;Now that we've looked at how to create a state transition table, we can implement a finite state machine.&lt;/p&gt;

&lt;p&gt;Here's a bit of a thought exercise before we get to the actual implementation details:&lt;/p&gt;

&lt;p&gt;Instead of using a state transition table, what if we could delegate the task of determining the next state to the &lt;em&gt;current state&lt;/em&gt; that our light is in? In other words, I'm proposing that we do something like this, where invoking a light's &lt;code&gt;toggle&lt;/code&gt; method in turn invokes the current state's &lt;code&gt;toggle&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Light.h&lt;/code&gt;:&lt;/p&gt;

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

&lt;span class="cp"&gt;#pragma once
#include&lt;/span&gt; &lt;span class="cpf"&gt;"LightState.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Light&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
    &lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// Same as before&lt;/span&gt;
    &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;getCurrentState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;currentState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// In here, we'll delegate the state transition to the currentState&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// This will get called by the current state&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;newState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;// LightState here is now a class, not the enum that we saw earlier&lt;/span&gt;
    &lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;currentState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;



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

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;Light.cpp&lt;/code&gt;:&lt;/p&gt;

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

&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"Light.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="c1"&gt;// TODO: set the initial state here&lt;/span&gt;
&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Light&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="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;newState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;currentState&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// do stuff before we change state&lt;/span&gt;
    &lt;span class="n"&gt;currentState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;newState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;currentState&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;enter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// do stuff after we change state&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Delegate the task of determining the next state to the current state&lt;/span&gt;
    &lt;span class="n"&gt;currentState&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Then, somewhere inside the current state's &lt;code&gt;toggle&lt;/code&gt; method, we call the light's &lt;code&gt;setState&lt;/code&gt; method and pass in the new state that we want to go to:&lt;/p&gt;

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

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;SomeLightState&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SomeOtherLightState&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;getInstance&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;If none of that code makes sense right now, don't worry—I'm about to break it all down step by step.&lt;/p&gt;

&lt;p&gt;This is known as the &lt;strong&gt;finite state design pattern&lt;/strong&gt;. Per this pattern, each state is modeled as a concrete class. So we'll need need the following four states for our lightbulb:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;LightOff&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LowIntensity&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MediumIntensity&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HighIntensity&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's model this finite state machine with a simple diagram:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Faleksandrhovhannisyan.github.io%2Fassets%2Fimg%2Fposts%2Ffinite-state-machine-fsm-tutorial-implementing-an-fsm-in-c%2Flight-fsm.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Faleksandrhovhannisyan.github.io%2Fassets%2Fimg%2Fposts%2Ffinite-state-machine-fsm-tutorial-implementing-an-fsm-in-c%2Flight-fsm.JPG" alt="Modeling our lightbulb's FSM."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each class implements a common &lt;code&gt;LightState&lt;/code&gt; interface that provides the following three methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;enter(Light*)&lt;/code&gt;: What should happen as we enter this state?&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;toggle(Light*)&lt;/code&gt;: What should happen when we're in this state?&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;exit(Light*)&lt;/code&gt;: What should happen as we're exiting this state?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All three methods accept a pointer to the &lt;code&gt;Light&lt;/code&gt; object with which the state is associated.&lt;/p&gt;

&lt;p&gt;How do they gain access to this pointer? Well, recall that we invoked &lt;code&gt;toggle&lt;/code&gt; in our &lt;code&gt;Light&lt;/code&gt; class like so:&lt;/p&gt;

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

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;currentState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Basically, we pass in a pointer to ourselves (&lt;code&gt;this&lt;/code&gt;). While doing so may seem pointless, it becomes more important in game development because it allows the state to ask the entity certain questions, like how much health it currently has and so on. The state can then use that information to decide what state the entity should transition to. Clearly, in the case of a lightbulb, there isn't really any information to poll.&lt;/p&gt;

&lt;p&gt;One final note: Each state class typically follows the &lt;a href="https://refactoring.guru/design-patterns/singleton" rel="noopener noreferrer"&gt;singleton design pattern&lt;/a&gt; to avoid unnecessary memory allocations and deallocations as we transition from one state to another, and then potentially back to a state that we were already in at one point. With our lights, if we didn't use singletons, we'd have to recreate our states every time we made a transition, and that would be wasteful.&lt;/p&gt;

&lt;p&gt;To understand how this all works in practice, we'll implement everything from scratch.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The &lt;code&gt;LightState&lt;/code&gt; Interface
&lt;/h3&gt;

&lt;p&gt;Let's first define the abstract &lt;code&gt;LightState&lt;/code&gt; class. You'll notice some forward declarations that are necessary to resolve circular includes that would otherwise throw off the C++ linker.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;LightState.h&lt;/code&gt;:&lt;/p&gt;

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

&lt;span class="cp"&gt;#pragma once
#include&lt;/span&gt; &lt;span class="cpf"&gt;"Light.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="c1"&gt;// Forward declaration to resolve circular dependency/include&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Light&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LightState&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
    &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;enter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;LightState&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;Since this is a &lt;strong&gt;pure abstract class&lt;/strong&gt;, we cannot create an instance of it. The &lt;code&gt;LightState&lt;/code&gt; interface allows us to take advantage of polymorphism so we can refer to a generic "state" without having to specify the true type of state that we're working with.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: In practice, you would often take this a step further and create an abstract &lt;code&gt;Entity&lt;/code&gt; class. You'd also create an abstract &lt;code&gt;EntityState&lt;/code&gt; class that accepts this generic entity in its method signatures. So, instead of having &lt;code&gt;Light*&lt;/code&gt; like we do above, we would have &lt;code&gt;Entity*&lt;/code&gt;, and &lt;code&gt;Light&lt;/code&gt; would simply extend &lt;code&gt;Entity&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2. Concrete State Classes
&lt;/h3&gt;

&lt;p&gt;Next, we'll declare all of our concrete state classes. We'll force each one to be a singleton by doing the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Defining a static &lt;code&gt;getInstance&lt;/code&gt; method that returns a pointer to the singleton.&lt;/li&gt;
&lt;li&gt;Declaring all constructors, copy constructors, and assignment operators as private.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;ConcreteLightStates.h&lt;/code&gt;:&lt;/p&gt;

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

&lt;span class="cp"&gt;#pragma once
#include&lt;/span&gt; &lt;span class="cpf"&gt;"LightState.h"&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;"Light.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LightOff&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;LightState&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;enter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;LightOff&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;LightOff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;LightOff&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;LightOff&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;operator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;LightOff&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LowIntensity&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;LightState&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;enter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;LowIntensity&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;LowIntensity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;LowIntensity&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;LowIntensity&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;operator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;LowIntensity&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MediumIntensity&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;LightState&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;enter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;MediumIntensity&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;MediumIntensity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;MediumIntensity&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;MediumIntensity&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;operator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;MediumIntensity&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HighIntensity&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;LightState&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;enter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;HighIntensity&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;HighIntensity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;HighIntensity&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;HighIntensity&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;operator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;HighIntensity&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;other&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 created inlined, empty definitions for the &lt;code&gt;enter&lt;/code&gt; and &lt;code&gt;exit&lt;/code&gt; methods, as these are not essential for our purposes. They are merely there as placeholders, to show that you could fill those in if you wanted to. For example, you could fill these with print statements, or you could invoke some method on the light object that got passed in, such as &lt;code&gt;light-&amp;gt;increaseGlow()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's also create definitions for all of the &lt;code&gt;toggle&lt;/code&gt; and &lt;code&gt;getInstance&lt;/code&gt; methods, to make things clearer:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ConcreteLightStates.cpp&lt;/code&gt;:&lt;/p&gt;

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

&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"ConcreteLightStates.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;LightOff&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Off -&amp;gt; Low&lt;/span&gt;
    &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LowIntensity&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;LightOff&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;LightOff&lt;/span&gt; &lt;span class="n"&gt;singleton&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;singleton&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;LowIntensity&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Low -&amp;gt; Medium&lt;/span&gt;
    &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MediumIntensity&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;LowIntensity&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;LowIntensity&lt;/span&gt; &lt;span class="n"&gt;singleton&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;singleton&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;MediumIntensity&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Medium -&amp;gt; High&lt;/span&gt;
    &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HighIntensity&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;MediumIntensity&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;MediumIntensity&lt;/span&gt; &lt;span class="n"&gt;singleton&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;singleton&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;HighIntensity&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// High -&amp;gt; Low&lt;/span&gt;
    &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LightOff&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;HighIntensity&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;HighIntensity&lt;/span&gt; &lt;span class="n"&gt;singleton&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;singleton&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'm taking advantage of static variables to create my singletons in a legible manner. Moreover, note that I'm returning references, and not pointers, &lt;a href="https://gamedev.stackexchange.com/questions/141884/can-this-singleton-class-cause-a-memory-leak" rel="noopener noreferrer"&gt;to avoid leaking memory&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Notice how each &lt;code&gt;toggle&lt;/code&gt; method initiates the appropriate state transition by invoking &lt;code&gt;light-&amp;gt;setState(...)&lt;/code&gt; and passing in a singleton, via a call to the next state's &lt;code&gt;getInstance&lt;/code&gt; method.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The &lt;code&gt;Light&lt;/code&gt; Class
&lt;/h3&gt;

&lt;p&gt;The final piece of the puzzle is the &lt;code&gt;Light&lt;/code&gt; class, particularly the &lt;code&gt;setState&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Light.h&lt;/code&gt;:&lt;/p&gt;

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

&lt;span class="cp"&gt;#pragma once
#include&lt;/span&gt; &lt;span class="cpf"&gt;"LightState.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="c1"&gt;// Forward declaration to resolve circular dependency/include&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LightState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Light&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;public:&lt;/span&gt;
    &lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;getCurrentState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;currentState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// This is where the magic happens&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;newState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;currentState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;Light.cpp&lt;/code&gt;:&lt;/p&gt;

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

&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"Light.h"&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;"ConcreteLightStates.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// All lights are initially turned off&lt;/span&gt;
    &lt;span class="n"&gt;currentState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;LightOff&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;newState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;currentState&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// do stuff before we change state&lt;/span&gt;
    &lt;span class="n"&gt;currentState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;newState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// actually change states now&lt;/span&gt;
    &lt;span class="n"&gt;currentState&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;enter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// do stuff after we change state&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Delegate the task of determining the next state to the current state&lt;/span&gt;
    &lt;span class="n"&gt;currentState&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;This is where the &lt;code&gt;enter&lt;/code&gt; and &lt;code&gt;exit&lt;/code&gt; methods come into play. Before we change states, we call the exit method on the previous state. Then, we set the current state to the new state and invoke the enter method. But again, since we haven't defined the behavior for these two methods, they won't really do anything; they're just here to show you that you &lt;em&gt;could&lt;/em&gt; do those things if you wanted to.&lt;/p&gt;

&lt;p&gt;And we're done! This is a pretty standard finite state machine implementation, and you can easily extend this to any other object-oriented language, or even to JavaScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing Our Code
&lt;/h2&gt;

&lt;p&gt;I use Visual Studio whenever I work with C++, so naturally, I'm also going to use the &lt;a href="https://docs.microsoft.com/en-us/visualstudio/test/how-to-use-microsoft-test-framework-for-cpp?view=vs-2019" rel="noopener noreferrer"&gt;Microsoft Unit Testing Framework for C++&lt;/a&gt; to verify that my finite state machine works as intended. This framework is built into Visual Studio 2017 and 2019. If you're not using Visual Studio, feel free to use a different IDE and whatever framework is available to you; the logic should be similar.&lt;/p&gt;

&lt;p&gt;Below is my test file. Note that you may need to change some of your includes if you named your primary project differently:&lt;/p&gt;

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

&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"stdafx.h"&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;"CppUnitTest.h"&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;"../LightbulbFSM/Light.h"&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;"../LightbulbFSM/Light.cpp"&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;"../LightbulbFSM/ConcreteLightStates.h"&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;"../LightbulbFSM/ConcreteLightStates.cpp"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LightState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;Microsoft&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;VisualStudio&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;CppUnitTestFramework&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;wstring&lt;/span&gt; &lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LightState&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&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="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;LightOff&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;L"Off"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;LowIntensity&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;L"Low"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;MediumIntensity&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;L"Medium"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;HighIntensity&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;L"High"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;

                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;L"nullptr"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;TestLightbulbFSM&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;TEST_CLASS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TestLightbulbFSM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nl"&gt;public:&lt;/span&gt;
                    &lt;span class="n"&gt;TEST_METHOD_INITIALIZE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Initialize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;light&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;

                    &lt;span class="n"&gt;TEST_METHOD_CLEANUP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Cleanup&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;

                    &lt;span class="n"&gt;TEST_METHOD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InitialStateIsOff&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;AreEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;LightOff&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getCurrentState&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;

                    &lt;span class="n"&gt;TEST_METHOD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OffGoesToLow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;AreEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;LowIntensity&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getCurrentState&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;

                    &lt;span class="n"&gt;TEST_METHOD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LowGoesToMedium&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                        &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;AreEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;MediumIntensity&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getCurrentState&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;

                    &lt;span class="n"&gt;TEST_METHOD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MediumGoesToHigh&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                        &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                        &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;AreEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;HighIntensity&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getCurrentState&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;

                    &lt;span class="n"&gt;TEST_METHOD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HighGoesToOff&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                        &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                        &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                        &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;AreEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;LightOff&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getCurrentState&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;

                &lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;Light&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;};&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Notice how I defined a test method for each state transition:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initially Off&lt;/li&gt;
&lt;li&gt;Off to Low&lt;/li&gt;
&lt;li&gt;Low to Medium&lt;/li&gt;
&lt;li&gt;Medium to High&lt;/li&gt;
&lt;li&gt;High back to Low&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The &lt;code&gt;ToString&lt;/code&gt; method at the top is needed to resolve a pretty common error that you'll run into with this unit testing framework.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If we run our test suite, we can verify that all of the tests passed:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Faleksandrhovhannisyan.github.io%2Fassets%2Fimg%2Fposts%2Ffinite-state-machine-fsm-tutorial-implementing-an-fsm-in-c%2Ftests.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Faleksandrhovhannisyan.github.io%2Fassets%2Fimg%2Fposts%2Ffinite-state-machine-fsm-tutorial-implementing-an-fsm-in-c%2Ftests.JPG" alt="All tests passed successfully in Visual Studio."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Awesome!&lt;/p&gt;

&lt;h2&gt;
  
  
  More Finite State Machine Examples
&lt;/h2&gt;

&lt;p&gt;As I mentioned earlier, this was a pretty trivial use case for finite state machines. In fact, you don't really need the finite state design pattern to solve this particular problem. However, because the problem itself is so simple—a lightbulb that simply changes from one state to another—I felt it was a perfect way to introduce FSMs without overcomplicating things.&lt;/p&gt;

&lt;p&gt;That said, I'd like to briefly mention some other situations where you may wany to use a finite state machine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://stackoverflow.com/questions/14676709/c-code-for-state-machine" rel="noopener noreferrer"&gt;Modeling a vending machine&lt;/a&gt;. This StackOverflow thread offers a pretty good discussion of some design approaches to a real-world interview problem. The accepted answer suggests using the finite state design pattern because of how extensible it is. Interestingly, the second highest rated answer suggests using a state transition table as an alternative.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://gameprogrammingpatterns.com/state.html" rel="noopener noreferrer"&gt;Modeling AI in a game&lt;/a&gt;. This post goes into great detail in the context of game dev. In particular, it highlights one advantage of finite state machines in game dev that I mentioned earlier in this post: The ability to query or "poll" the entity from the state in order to determine what state transition should take place.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;p&gt;To gain a better understanding of finite state machines, I encourage you to reference the book titled &lt;em&gt;Programming Game AI by Example&lt;/em&gt;, by Mat Buckland. Chapter 2 covers the state-driven agent design pattern, which is essentially just another name for the FSM design pattern. You can &lt;a href="https://github.com/wangchen/Programming-Game-AI-by-Example-src" rel="noopener noreferrer"&gt;download the companion code&lt;/a&gt; and run it yourself as you work through the chapter explanations. This is how I initially learned about finite state machines.&lt;/p&gt;

&lt;p&gt;I hope you found this tutorial helpful! If you notice any bugs or typos, please let me know in the comments.&lt;/p&gt;

</description>
      <category>designpatterns</category>
      <category>cpp</category>
    </item>
    <item>
      <title>Add a Free Contact Form to Your Website with Formspree</title>
      <dc:creator>Aleksandr Hovhannisyan</dc:creator>
      <pubDate>Mon, 27 Jan 2020 15:25:16 +0000</pubDate>
      <link>https://dev.to/aleksandrhovhannisyan/add-a-free-contact-form-to-your-website-with-formspree-3i49</link>
      <guid>https://dev.to/aleksandrhovhannisyan/add-a-free-contact-form-to-your-website-with-formspree-3i49</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Note: This is a syndicated post. If you'd like to, you can &lt;a href="https://www.aleksandrhovhannisyan.com/blog/dev/add-a-contact-form-to-your-website-for-free-with-formspree/"&gt;view the original on my dev blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://formspree.io/"&gt;Formspree&lt;/a&gt; is an online platform that makes it easy for you to add a free contact form to your website. It even has paid plans and integrations with other apps, like Slack, Mailchimp, and more. Setting it up takes no more than a few minutes, so let's get started!&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview: How Does Formspree Work?
&lt;/h2&gt;

&lt;p&gt;It's actually really simple! Here's a quick rundown of how Formspree works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;You specify a Formspree endpoint with your email address (e.g., &lt;code&gt;https://formspree.io/your-email&lt;/code&gt;) in your form's markup. More specifically, this URL will be the &lt;code&gt;action&lt;/code&gt; attribute of your form.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You make a mock submission once through the form on your live website. Formspree receives your submission and sends you a one-time registration email to activate the form.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once the form has been activated, all future form submissions on your website will trigger a Formspree notification that's sent to your email address, with the form's contents and any other details.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How to Set Up Formspree 📧
&lt;/h2&gt;

&lt;p&gt;To get started, all you need to do is add a &lt;code&gt;form&lt;/code&gt; like this to your site:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;action=&lt;/span&gt;&lt;span class="s"&gt;"https://formspree.io/your-email"&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"POST"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"hidden"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"_subject"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Someone sent you a message!"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"_replyto"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;textarea&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"body"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/textarea&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Send message"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's clarify some of the input attributes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;_subject&lt;/code&gt;: This will be the subject line for the email that you receive from Formspree; it's a hidden field.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_replyto&lt;/code&gt;: Used to auto-fill the address line with the user's email if you respond to the notification email.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;body&lt;/code&gt;: The message from your user.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The form's &lt;code&gt;action&lt;/code&gt; attribute is the &lt;strong&gt;Formspree endpoint&lt;/strong&gt; that I mentioned earlier; it's where the form data is going to be sent when it's submitted. As I noted earlier, to associate this endpoint with your email address, you just have to make a one-time mock submission from your live website (not from your local). Once you do that, you'll be notified that this form needs to be activated:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sqss5yVf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/add-a-contact-form-to-your-website-for-free-with-formspree/activation-required.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sqss5yVf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/add-a-contact-form-to-your-website-for-free-with-formspree/activation-required.webp" alt="Formspree activation required."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Don't use your personal email address, as you'll have to expose that to the public in your form's markup. Instead, set up a dedicated email address for your website if you don't already have one.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And here's the email you'll receive from Formspree:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iBDfcg2S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/add-a-contact-form-to-your-website-for-free-with-formspree/activation-email.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iBDfcg2S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/add-a-contact-form-to-your-website-for-free-with-formspree/activation-email.webp" alt="Acivation email from Formspree."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Again, it's important to make the mock submission from your &lt;em&gt;live&lt;/em&gt; website and not from your local. It's not like doing it from your local will break anything—it's just that you'll still need to activate the form on the live website in order for it to work properly.&lt;/p&gt;

&lt;p&gt;When a user submits a message, they'll have to pass a reCAPTCHA test. You'll then get an email from Formspree with a summary of the user's submission:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LDhVDIBt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/add-a-contact-form-to-your-website-for-free-with-formspree/email.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LDhVDIBt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/add-a-contact-form-to-your-website-for-free-with-formspree/email.webp" alt="A sample user submission to Formspree."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that the subject line of this email is whatever I specified for the hidden &lt;code&gt;_subject&lt;/code&gt; input. In this case, that's "Someone sent you a message!"&lt;/p&gt;

&lt;p&gt;There are two useful links down at the bottom:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can mark the email as spam if needed.&lt;/li&gt;
&lt;li&gt;You can unsubscribe your email from that particular Formspree endpoint.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, as I mentioned earlier, if you reply, the recipient's address will be filled in automatically:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7yM_4z1N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/add-a-contact-form-to-your-website-for-free-with-formspree/reply.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7yM_4z1N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/add-a-contact-form-to-your-website-for-free-with-formspree/reply.webp" alt="Replying to the email auto-fills the recipient's email address."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up a Honeypot Trap for Bots 🍯
&lt;/h2&gt;

&lt;p&gt;While the reCAPTCHA test already provides a solid defense against spam, Formspree also &lt;a href="https://help.formspree.io/hc/en-us/articles/360013580813-Honeypot-spam-filtering"&gt;recommends adding a honeypot input field&lt;/a&gt; to your form for safe measure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"_gotcha"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a bot comes along and sticks its head where it doesn't belong, it'll be stuck. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5o3I0ueJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/add-a-contact-form-to-your-website-for-free-with-formspree/honeypot.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5o3I0ueJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/add-a-contact-form-to-your-website-for-free-with-formspree/honeypot.webp" alt="Pooh Bear with his head stuck in a honey pot."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should give this a class and set the display to none so it doesn't confuse your human users:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"_gotcha"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"honeypot"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="nc"&gt;.honeypot&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Formspree Free Plan Limitations
&lt;/h2&gt;

&lt;p&gt;The free Formspree plan is a good option for most personal websites that don't expect more than &lt;strong&gt;50 submissions per month&lt;/strong&gt;. If you need more than that for your site, you can opt for one of their &lt;a href="https://formspree.io/plans"&gt;paid plans&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  That's It!
&lt;/h2&gt;

&lt;p&gt;You're all set to receive messages from your website's visitors.&lt;/p&gt;

&lt;p&gt;(Or to hear crickets chirping in your inbox... 🦗)&lt;/p&gt;

</description>
      <category>forms</category>
      <category>html</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Create Invulnerability Frames in Unity</title>
      <dc:creator>Aleksandr Hovhannisyan</dc:creator>
      <pubDate>Sat, 11 Jan 2020 14:23:20 +0000</pubDate>
      <link>https://dev.to/aleksandrhovhannisyan/invincibility-frames-in-unity-how-to-make-a-player-flash-when-taking-damage-4nkm</link>
      <guid>https://dev.to/aleksandrhovhannisyan/invincibility-frames-in-unity-how-to-make-a-player-flash-when-taking-damage-4nkm</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This is a syndicated post. If you'd like to, you can &lt;a href="https://www.aleksandrhovhannisyan.com/blog/dev/invulnerability-frames-in-unity/"&gt;view the original on my dev blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I learned a lot of neat tricks while working on developing one of my first "real" games, &lt;a href="https://github.com/cap4053-cheeky-pixels/EmbodyGame"&gt;Embody&lt;/a&gt;, with some classmates. So I figured why not share some of those tips to help other game devs?&lt;/p&gt;

&lt;p&gt;In this post, we'll look at how you can make a player flash when they take damage. This is the notion of &lt;strong&gt;invincibility frames&lt;/strong&gt;, also known as i-frames. You'll find this in many retro games, as well as in games like The Binding of Isaac.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_KGo2j4l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/invincibility-frames-in-unity-how-to-make-a-player-flash-when-taking-damage/isaac.GIF" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_KGo2j4l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/invincibility-frames-in-unity-how-to-make-a-player-flash-when-taking-damage/isaac.GIF" alt="Invincibility frames in the Binding of Isaac"&gt;&lt;/a&gt;&lt;br&gt;&lt;a href="https://braintrash83.tumblr.com/post/93502135046"&gt;GIF source&lt;/a&gt;
    &lt;/p&gt;

&lt;p&gt;To keep this tutorial simple, I'll assume that you already have:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A way to detect collisions between projectiles/mobs and the player.&lt;/li&gt;
&lt;li&gt;A way to hurt the player. Let's call this method &lt;code&gt;LoseHealth(int amount)&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How to Make a Player Flash When Taking Damage (with Coroutines!)
&lt;/h2&gt;

&lt;p&gt;The naive approach is to run a &lt;code&gt;for&lt;/code&gt; loop, with an intentional delay between each iteration using deltatime, in your main &lt;code&gt;Update&lt;/code&gt; loop, and to try to make the player flash in each iteration. But if you do this, you won't actually observe any flashing. Why is that?&lt;/p&gt;

&lt;p&gt;In game development, you have to keep in mind that everything happens within a &lt;strong&gt;frame update&lt;/strong&gt;. What this means is that most game engines have an &lt;code&gt;Update&lt;/code&gt; method that runs the entire game's logic in "ticks." So, if you have a &lt;code&gt;for&lt;/code&gt; loop inside the update loop, it'll complete all of its iterations in a single frame. Thus, any oascillating UI changes that were intended to be gradual—like the player model flashing—will be (almost) immediate, and therefore imperceptible.&lt;/p&gt;

&lt;p&gt;Instead, we want to use &lt;a href="https://docs.unity3d.com/Manual/Coroutines.html"&gt;coroutines&lt;/a&gt; to implement invincibility frames in Unity. A coroutine is simply a method that will run in parallel to the main update loop and resume where it left off in the next update.&lt;/p&gt;

&lt;h3&gt;
  
  
  Invincibility Frames in Unity
&lt;/h3&gt;

&lt;p&gt;We'll start by adding this method somewhere in our Player script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;IEnumerator&lt;/span&gt; &lt;span class="nf"&gt;BecomeTemporarilyInvincible&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// logic goes here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that this method returns an &lt;code&gt;IEnumerator&lt;/code&gt;; all coroutines in Unity do that.&lt;/p&gt;

&lt;p&gt;We'll use a flag to keep track of whether the player is invincible. Add this member variable to your script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;isInvincible&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, when the player becomes invincible, we flip this flag to true:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;IEnumerator&lt;/span&gt; &lt;span class="nf"&gt;BecomeTemporarilyInvincible&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Debug&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Player turned invincible!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;isInvincible&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&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;Of course, this doesn't do anything (yet!). You're probably wondering:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How do we start the coroutine in the first place?&lt;/li&gt;
&lt;li&gt;How do we keep the coroutine running for a set amount of time?&lt;/li&gt;
&lt;li&gt;How do we make the player flash while they're invulnerable to damage?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All great questions! We'll address each one in turn.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Losing Health and Becoming Invincible (Starting the Coroutine)
&lt;/h2&gt;

&lt;p&gt;Ready for this? It's actually stupidly simple.&lt;/p&gt;

&lt;p&gt;Again, I'll assume that you're using something like &lt;code&gt;LoseHealth(int amount)&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;LoseHealth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&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="n"&gt;isInvincible&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="n"&gt;Health&lt;/span&gt; &lt;span class="p"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// The player died&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Health&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Health&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="c1"&gt;// Broadcast some sort of death event here before returning&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;StartCoroutine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;BecomeTemporarilyInvincible&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;First, we &lt;a href="https://softwareengineering.stackexchange.com/a/230460/333842"&gt;fail-fast&lt;/a&gt; if the player is already invincible. If they're not invincible, the player loses health. If the player died as a result of losing health, we set their health to zero, potentially fire off a death event, and return. Finally, if the player took damage but is still alive, we use &lt;code&gt;StartCoroutine&lt;/code&gt; to initiate the coroutine that grants the player temporary invincibility.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: Is your Player script checking for collisions with hostile entities in the world and self-inflicting damage? If so, rethink your approach. Instead, try having your damage sources check for collision with a designated "enemy" layer. This makes your logic much easier to follow.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  2. Keep the Coroutine Running for a Set Amount of Time
&lt;/h2&gt;

&lt;p&gt;Here's what we want:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Invincibility should only last for a set period of time.&lt;/li&gt;
&lt;li&gt;There should be a fixed delay after each invincibility frame.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Add these two private members at the top of your script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;SerializeField&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;invincibilityDurationSeconds&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;SerializeField&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;delayBetweenInvincibilityFlashes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;SerializeField&lt;/code&gt; lets you edit private members through the Unity inspector without having to make them public.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You'll need to initialize these two members via the Inspector pane:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XaNOo-6J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/invincibility-frames-in-unity-how-to-make-a-player-flash-when-taking-damage/inspector.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XaNOo-6J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/invincibility-frames-in-unity-how-to-make-a-player-flash-when-taking-damage/inspector.PNG" alt="Initializing serialized fields via the inspector pane in Uniy."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you've done that, use them in the coroutine to run a simple loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;IEnumerator&lt;/span&gt; &lt;span class="nf"&gt;BecomeTemporarilyInvincible&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Debug&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Player turned invincible!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;isInvincible&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Flash on and off for roughly invincibilityDurationSeconds seconds&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;invincibilityDurationSeconds&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;delayBetweenInvincibilityFlashes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// TODO: add flashing logic here&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WaitForSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delayBetweenInvincibilityFlashes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;Debug&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Player is no longer invincible!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;isInvincible&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&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 find that a duration of &lt;code&gt;1.5 s&lt;/code&gt; works best, with the delay set to &lt;code&gt;0.15 s&lt;/code&gt;. This means the loop will run &lt;code&gt;1.5 / 0.15 = 10&lt;/code&gt; times. Since the player model transitions between two states (visible/invisible) across 10 iterations, you'll observe that there are &lt;code&gt;10 / 2 = 5&lt;/code&gt; flashes in total:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--efu39cfB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/invincibility-frames-in-unity-how-to-make-a-player-flash-when-taking-damage/flashes.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--efu39cfB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/invincibility-frames-in-unity-how-to-make-a-player-flash-when-taking-damage/flashes.PNG" alt="The number of flashes that occur with those settings."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The key part here is the loop, especially the following line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WaitForSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delayBetweenInvincibilityFlashes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We pause coroutines in Unity using &lt;code&gt;WaitForSeconds&lt;/code&gt; and pass in the number of seconds to wait. In this case, that's the delay beween each flash, which you've hopefully set in your inspector by now.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Make the Player Flash While Invincible
&lt;/h2&gt;

&lt;p&gt;The easiest way to simulate flashing is to repeatedly scale the player's model (or sprite, for 2D) between &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt; during each iteration of the loop. So first, we need to actually get ahold of the player model. We'll add a member for it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;SerializeField&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;GameObject&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: For this tutorial to work, the Player should consist of a root object (e.g., &lt;code&gt;MainPlayer&lt;/code&gt;) that has a collision box and the Player script attached to it. Nested under that object should be the player's model (e.g., &lt;code&gt;Model&lt;/code&gt;) as a separate object:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2WkvIBGB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/invincibility-frames-in-unity-how-to-make-a-player-flash-when-taking-damage/model.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2WkvIBGB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/invincibility-frames-in-unity-how-to-make-a-player-flash-when-taking-damage/model.PNG" alt="The object hierarchy of the player."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is important&lt;/strong&gt;! You should not use the root player object as the model. If you do, this could lead to some very game-breaking bugs, as scaling the root object would also scale the player's collider.&lt;/p&gt;

&lt;p&gt;In your editor, go ahead and drag the model object into the appropriate slot in the Player script, like so:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cxUBA1am--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/invincibility-frames-in-unity-how-to-make-a-player-flash-when-taking-damage/add-model.GIF" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cxUBA1am--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/invincibility-frames-in-unity-how-to-make-a-player-flash-when-taking-damage/add-model.GIF" alt="Adding the model object to the player script."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, we'll add a method that lets us easily scale this model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ScaleModelTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Vector3&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;localScale&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally, we'll actually do the scaling in our coroutine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;IEnumerator&lt;/span&gt; &lt;span class="nf"&gt;BecomeTemporarilyInvincible&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Debug&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Player turned invincible!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;isInvincible&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Flash on and off for roughly invincibilityDurationSeconds seconds&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;invincibilityDurationSeconds&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;delayBetweenInvincibilityFlashes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Alternate between 0 and 1 scale to simulate flashing&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;localScale&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;Vector3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;one&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;ScaleModelTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Vector3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zero&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;ScaleModelTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Vector3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;one&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WaitForSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delayBetweenInvincibilityFlashes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;Debug&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Player is no longer invincible!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;ScaleModelTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Vector3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;one&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;isInvincible&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&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;Depending on the numbers you select for &lt;code&gt;invincibilityDurationSeconds&lt;/code&gt; and &lt;code&gt;delayBetweenInvincibilityFlashes&lt;/code&gt;, you could end up in a situation where the player's invincibility runs out on the loop iteration where we set its scale to zero. Thus, we forcibly scale the model to one at the very end for safe measure.&lt;/p&gt;

&lt;p&gt;And that's it—you're all set to use invincibility frames in your game!&lt;/p&gt;

&lt;h2&gt;
  
  
  Can I Use This Approach in Other Game Engines?
&lt;/h2&gt;

&lt;p&gt;Yes and no.&lt;/p&gt;

&lt;p&gt;In game engines like Unreal, there is unfortunately no support for coroutines. As an alternative to this approach, you can keep track of the time that has elapsed since invulnerability was initiated using simple deltatime calculations.&lt;/p&gt;

&lt;p&gt;Godot, on the other hand, &lt;a href="https://docs.godotengine.org/en/3.1/getting_started/scripting/gdscript/gdscript_basics.html#coroutines-with-yield"&gt;does have them&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I hope you found this tutorial helpful!&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>unity3d</category>
    </item>
    <item>
      <title>Improve Page Load Speed in Jekyll with the WebP Image Format</title>
      <dc:creator>Aleksandr Hovhannisyan</dc:creator>
      <pubDate>Sun, 05 Jan 2020 20:34:31 +0000</pubDate>
      <link>https://dev.to/aleksandrhovhannisyan/improve-page-load-speed-in-jekyll-with-the-webp-image-format-1e2a</link>
      <guid>https://dev.to/aleksandrhovhannisyan/improve-page-load-speed-in-jekyll-with-the-webp-image-format-1e2a</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This is a syndicated post. If you'd like to, you can &lt;a href="https://www.aleksandrhovhannisyan.com/blog/dev/improve-page-load-speed-in-jekyll-using-the-webp-image-format/"&gt;view the original on my dev blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eoXHpSjQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/improve-page-load-speed-in-jekyll-using-the-webp-image-format/pagespeed-insights.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eoXHpSjQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/improve-page-load-speed-in-jekyll-using-the-webp-image-format/pagespeed-insights.PNG" alt="The PageSpeed Insights score for one of my blog posts."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run the blog posts on my personal website through Google's &lt;a href="https://developers.google.com/speed/pagespeed/insights/"&gt;PageSpeed Insights&lt;/a&gt; or &lt;a href="https://webspeedtest.cloudinary.com/"&gt;Cloudinary's Image Analysis tool&lt;/a&gt;, and you'll find that most of them (with the exception of a few that load iframes) get around 99 on mobile and 100 on desktop. &lt;a href="https://aleksandrhovhannisyan.github.io/blog/gaming/outer-wilds-review-stop-and-smell-the-pine-trees/"&gt;Some of these&lt;/a&gt; are packed full of images.&lt;/p&gt;

&lt;p&gt;Why does that matter? Because speed is an important factor to consider alongside SEO to improve your site's ranking. Google considers page load speed when determining whether your site provides a positive experience for new and returning visitors. If your site is using too much data—by loading expensive images, iframes, or scripts—your page will load slowly, and users will be more likely to ditch your site in favor of one that doesn't slow them to a crawl.&lt;/p&gt;

&lt;p&gt;It's only when I began running my posts through the former tool, PageSpeed Insights, that I discovered a useful optimization: &lt;a href="https://developers.google.com/speed/webp"&gt;using the WebP image format&lt;/a&gt;. Here's how Google describes WebP:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;WebP is a modern image format that provides superior lossless and lossy compression for images on the web. Using WebP, webmasters and web developers can create smaller, richer images that make the web faster.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Google even provides a useful command-line tool, &lt;code&gt;cwebp&lt;/code&gt;, that allows you to convert images from other formats—like PNG, JPEG, and so on—to WebP. In this post, we'll consider Jekyll specifically and take a look at how you can improve your page load speed by using the WebP image format with just a single include.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started with WebP in Jekyll
&lt;/h2&gt;

&lt;p&gt;Now, you actually have two options here:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Use a plugin
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://github.com/sverrirs/jekyll-webp"&gt;jekyll-webp&lt;/a&gt; plugin generates WebP versions of your images and serves them on demand whenever they're requested; it does &lt;em&gt;not&lt;/em&gt; create actual WebP image files under your &lt;code&gt;assets&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;The downside to this approach is that some plugins—including this one—are &lt;a href="https://help.github.com/en/github/working-with-github-pages/about-github-pages-and-jekyll#plugins"&gt;not supported by GitHub Pages&lt;/a&gt;, so you'll have to run &lt;code&gt;jekyll build&lt;/code&gt; and push your &lt;code&gt;_site/&lt;/code&gt; to GitHub, instead of pushing your source.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Use Google's CLI utility
&lt;/h3&gt;

&lt;p&gt;Install the &lt;code&gt;cwebp&lt;/code&gt; CLI utility yourself and use it to manually convert images to WebP as you add them to your site. &lt;strong&gt;This is my preferred option&lt;/strong&gt;, and it's the one that I'll use in this blog post.&lt;/p&gt;

&lt;p&gt;To get started, head on over to &lt;a href="https://developers.google.com/speed/webp/docs/precompiled"&gt;Google's installation instructions page&lt;/a&gt; for the &lt;code&gt;libwebp&lt;/code&gt; executables and libraries. The process is actually really straightforward.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The installation will also come with &lt;code&gt;gif2webp&lt;/code&gt;, which can be used to convert GIFs to a WebP equivalent.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Converting an Image to WebP Format with &lt;code&gt;cwebp&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Assuming the previous step worked just fine for you and that &lt;code&gt;cwebp&lt;/code&gt; is now accessible from the command-line, it's time to try it out on an actual image. Here's the general syntax for the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cwebp &lt;span class="o"&gt;[&lt;/span&gt;options] input_file &lt;span class="nt"&gt;-o&lt;/span&gt; output_file.webp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can specify a number of options, including the compression factor for converting to WebP; this dictates the quality of the resulting image. By default, this factor is set to 75%.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can learn more about the available options in &lt;a href="https://developers.google.com/speed/webp/docs/cwebp"&gt;Google's documentation for cwebp&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example, let's say you have an image under &lt;code&gt;/assets/img/posts&lt;/code&gt;. To convert that to WebP, simply switch to the target directory and execute this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cwebp img.png &lt;span class="nt"&gt;-o&lt;/span&gt; img.webp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! Here's a quick demo of that in action:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q6klG3lT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/improve-page-load-speed-in-jekyll-using-the-webp-image-format/demo.GIF%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q6klG3lT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/improve-page-load-speed-in-jekyll-using-the-webp-image-format/demo.GIF%3F" alt="Converting a traditional image format to a webp image."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can ignore the output from the tool, as it's not too important.&lt;/p&gt;

&lt;p&gt;In this case, notice that the image size was cut in a half—from 16 KB to 8 KB—&lt;em&gt;without a significant loss of quality&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: You don't have to switch to the target directory to run the command. You could also just feed it a relative or absolute path from any directory. That said, I prefer to run it from the target directory to make my life easier.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  How Do You Use the WebP Image Format?
&lt;/h2&gt;

&lt;p&gt;The good news is that &lt;a href="https://caniuse.com/#feat=webp"&gt;browser support for WebP&lt;/a&gt; is high, excluding Internet Explorer (of course 😒) and Safari:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pHMqMY_f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/improve-page-load-speed-in-jekyll-using-the-webp-image-format/caniuse.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pHMqMY_f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/improve-page-load-speed-in-jekyll-using-the-webp-image-format/caniuse.PNG" alt="The caniuse results for WebP"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Assuming you want to cover all your bases and ensure that your images are displaying properly, you can use a &lt;code&gt;picture&lt;/code&gt; element with a &lt;code&gt;source&lt;/code&gt; for the WebP version and a backup &lt;code&gt;img&lt;/code&gt; for the regular format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;picture&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;source&lt;/span&gt; &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"/path/to/image.webp"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"image/webp"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/path/to/image.jpg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Your alt text"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/picture&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basically, browsers that don't support WebP will fall back to the plain old &lt;code&gt;img&lt;/code&gt; element, while those that do support WebP will use the &lt;code&gt;source&lt;/code&gt; element. Awesome!&lt;/p&gt;

&lt;p&gt;Except... Do we really have to copy-paste this every time we want to create an image? We also want to avoid having to specify an absolute path to our image every single time we want to insert one in a blog post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Jekyll Includes and Liquid to the Rescue
&lt;/h2&gt;

&lt;p&gt;Time to make this reusable! Create a file named &lt;code&gt;_includes/picture.html&lt;/code&gt; and add this markup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;{% assign img = include.img %}
&lt;span class="nt"&gt;&amp;lt;picture&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;source&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"image/webp"&lt;/span&gt; &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"/assets/img/posts/{{ page.slug }}/{{ img }}.webp"&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/assets/img/posts/{{ page.slug }}/{{ img }}.{{ include.ext }}"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"{{ include.alt }}"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/picture&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's try to understand this part specifically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;source&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"image/webp"&lt;/span&gt; &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"/assets/img/posts/{{ page.slug }}/{{ img }}.webp"&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before I explain why this works, you need to know how I like to structure my blog:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All blog post images are under &lt;code&gt;/assets/img/posts/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Under that directory, each post has its own folder whose name matches the slugged version of the post's title.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's a screenshot to make that clearer:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jeoBRGza--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/improve-page-load-speed-in-jekyll-using-the-webp-image-format/assets.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jeoBRGza--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/improve-page-load-speed-in-jekyll-using-the-webp-image-format/assets.PNG" alt="My assets/img/posts folder."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That allows us to get away with this simple and legible include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;picture.html&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;img&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"my-image"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;ext&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"png"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"My alt text"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that we don't have to worry about explicitly stating the path! That will be filled in by Liquid when it goes to evaluate &lt;code&gt;{{ page.slug }}&lt;/code&gt;. To top that off, we get to take advantage of WebP behind the scenes, with little effort beyond converting the images.&lt;/p&gt;

&lt;h2&gt;
  
  
  And That's It!
&lt;/h2&gt;

&lt;p&gt;Of course, it would be even more convenient if there were a Jekyll plugin that generates output files from &lt;code&gt;cwebp&lt;/code&gt; and dumps them in your assets folder. That way, you don't have to use the CLI tool manually.&lt;/p&gt;

&lt;p&gt;If you wanted to, you could automate this with a script that converts all images in a directory to WebP using the installed CLI. In the process of writing this blog post, I went ahead and &lt;a href="https://github.com/AleksandrHovhannisyan/webp"&gt;created that script&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;One final improvement is to add lazy-loading to your images with JavaScript to ensure that your content loads even more quickly.&lt;/p&gt;

&lt;p&gt;I hope you found this helpful!&lt;/p&gt;

</description>
      <category>jekyll</category>
      <category>blogging</category>
    </item>
    <item>
      <title>Learn to Code Without Wasting Time &amp; Money</title>
      <dc:creator>Aleksandr Hovhannisyan</dc:creator>
      <pubDate>Sat, 04 Jan 2020 15:15:54 +0000</pubDate>
      <link>https://dev.to/aleksandrhovhannisyan/learn-to-code-without-wasting-time-money-2k0e</link>
      <guid>https://dev.to/aleksandrhovhannisyan/learn-to-code-without-wasting-time-money-2k0e</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Note: This is a syndicated post. If you'd like to, you can &lt;a href="https://www.aleksandrhovhannisyan.com/blog/dev/learn-to-code-without-wasting-time-and-money/"&gt;view the original on my dev blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I remember reading a short story in high school about an aspiring writer who invested a great deal of time and money in procuring a fancy pen and an ornately bound notebook, purchasing a desk only a serious writer would sit at, furnishing his study with shelves full of old books he'd never read, and daydreaming about the prospect of writing. What was missing from this picture was any ink touching paper—he did anything but actually write.&lt;/p&gt;

&lt;p&gt;The same thing often happens with beginners who want to get into software development—they install an assortment of IDEs and tools whose purpose they don't really understand, scour through listicles on the best programming languages for beginners to learn, and generally spend most of their time contemplating programming and trying to come up with ideas for projects instead of... well, &lt;em&gt;programming&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pick a Language, Any Language
&lt;/h2&gt;

&lt;p&gt;Instead of wasting your time comparing different languages, just pick one and start coding. It really doesn't matter. Learn Java. Learn Python. Learn PHP, JavaScript, Go, Scratch, or any language you want. Anything will do when you're a beginner as long as you actually start somewhere. What you &lt;em&gt;shouldn't&lt;/em&gt; do is waste time debating the merits and drawbacks of various languages when you don't even have experience yet—that's what you really need, after all; the language is just a means to an end.&lt;/p&gt;

&lt;p&gt;YouTuber Michael Reeves puts it well in &lt;a href="https://www.youtube.com/watch?v=bZDE6I5B9-E"&gt;one of his videos&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Just pick one and start learning programming... All modern programming languages are wildly powerful, and they can do all kinds of shit.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I recall my programming fundamentals teacher imparting some very wise words in the second semester of my undergraduate studies when he heard me complain about us learning C++, which at the time was completely foreign to me and came with a boatload of frustrations. He said that the degree wasn't intended to teach us how to program in any particular language, and that languages are merely tools for doing a programmer's job. The hope was that we'd be able to pick up any language on demand after graduating from the program. Our goal was to learn how to think like computer scientists instead of confining ourselves to the narrow context of any particular language.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Languages are merely tools for doing a programmer's job.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, there is a caveat here worth mentioning: The language you select as a beginner will influence your initial perception of software development and dictate whether you actually end up enjoying coding or if you walk away disappointed.&lt;/p&gt;

&lt;p&gt;There's a reason why many university courses expose beginners to Java, C++, or, &lt;a href="https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-0001-introduction-to-computer-science-and-programming-in-python-fall-2016/"&gt;in the case of MIT&lt;/a&gt;, Python: These three languages are very popular and span a number of software development domains, making them practical and useful to know. They're also more accessible to beginners because they're general-purpose languages.&lt;/p&gt;

&lt;p&gt;Here's my advice: Don't pick a single language and refuse to part ways with it. The most obvious reason for this is because not every language is suitable for every problem. But in addition, limiting your worldview to just a single language paradigm can seriously stunt your growth as a developer.&lt;/p&gt;

&lt;p&gt;Instead, I recommend using your favorite language as a way to learn programming fundamentals, algorithms, and data structures, and to gradually step out of your comfort zone. All of those things are language agnostic and easily transferable. Once you master those skills, you'll find that learning new programming languages will be a matter of getting used to a new syntax (and maybe a new way of thinking, like going from an OOP language to a functional one).&lt;/p&gt;

&lt;h2&gt;
  
  
  Stop Wasting Money on Courses You'll Never Finish
&lt;/h2&gt;

&lt;p&gt;Udemy, Udacity, Lynda, Vertabelo Academy, Codeacademy Pro, et al. What do these things have in common? They're online platforms that target beginners who feel overwhelmed or disillusioned working professionals who are looking to make a career change as quickly as possible. These platforms are everywhere, but I consider them detrimental to learning how to actually code because they rarely ever provide materials that are of a higher quality than free content that's readily available online.&lt;/p&gt;

&lt;p&gt;The biggest problem with these courses is the constant &lt;strong&gt;hand-holding&lt;/strong&gt;—it's a disservice. Doing your own research, making mistakes, breaking your code, and learning how to debug all incredibly valuable experiences that will stick with you forever and ultimately make you a better programmer. Simply copying what an instructor does may help you develop muscle memory, but it won't provide you with the deep level of understanding that only first-hand experience can bring.&lt;/p&gt;

&lt;p&gt;Have you ever noticed how Udemy's courses are always on sale? Or that these platforms have hints on practically every problem, or that the instructors outright tell you how to do X thing, or that they even do a Google search right there in the video instead of encouraging students to research these things for themselves? These are all red flags.&lt;/p&gt;

&lt;p&gt;Many of these courses involve &lt;strong&gt;passive learning&lt;/strong&gt;, even if they encourage you to type along and do things on your own machine as you watch them done on the instructor’s end. Why? Because you’re not actually discovering problems yourself and then searching for ways to solve those problems. That’s how people learn—through experience, curiosity, and failure.&lt;/p&gt;

&lt;p&gt;With many of these platforms, there’s a thin veil of active learning. In reality, you’re doing one of three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Typing out everything the instructor wrote by hand.&lt;/li&gt;
&lt;li&gt;Straight up copy-pasting their code or cloning a repo from their GitHub.&lt;/li&gt;
&lt;li&gt;Not even coding—just listening and hoping it all sticks (spoiler: it won't).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then, a week later, you find yourself having to revisit a past exercise (or even the associated video) to recall how to do something. If that's the case, then you clearly didn’t learn anything.&lt;/p&gt;

&lt;p&gt;Reality: Developers have to constantly search for things online, sifting through Stack Overflow posts, Reddit, YouTube tutorials, articles, and—dare I say it?—&lt;em&gt;official documentation&lt;/em&gt; to find answers to their questions. But why bother to seek out these answers on your own when you can pay for an instructor to &lt;em&gt;tell you&lt;/em&gt; how it’s done? That makes you feel all nice and safe inside.&lt;/p&gt;

&lt;p&gt;In a similar vein, these platforms also shield you from the somewhat tricky (yet valuable) process of &lt;strong&gt;setting up a technology on your own machine&lt;/strong&gt;. Instead, they offer you a nice little sandbox environment where you can code to your heart's content without ever understanding what happens between you writing your code and the computer interpreting and understanding that code. If you plan on seriously investing your time in learning and using a technology in the real world, why not take the time to understand how you can use it on your own computer?&lt;/p&gt;

&lt;p&gt;I'll admit: I do understand the appeal of a sandbox environment. It allows you to focus on the important thing—learning the language—without getting bogged down in any of the impediments. Med students don't practice surgery on real patients, after all. But you also can't expect to operate on cadavers forever.&lt;/p&gt;

&lt;p&gt;Here are two Udemy course I once purchased thinking that they were the key to achieving whatever goals I had at the time (web development and game development, apparently):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JBPWpb9P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/learn-to-code-without-wasting-time-and-money/udemy-courses.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JBPWpb9P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/learn-to-code-without-wasting-time-and-money/udemy-courses.webp" alt="Two of the Udemy courses I once purchased but never finished."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I quit about 10% through both of them because I was bored out of my mind. I am not the type of person who can tolerate sitting in front of lecture after lecture, followed by intermittent "now you try it" exercises that, for the most part, are very trivial. I need a context for anything I do—a genuinely relevant, interesting, and challenging project that I want to work on. To-do list apps don't cut it for me because they're not something I actually want to build. Making games &lt;em&gt;your&lt;/em&gt; way isn't what I want to do when I'm learning game dev.&lt;/p&gt;

&lt;p&gt;For example, I learned just about everything I know about HTML, CSS, and (some) JavaScript by making &lt;a href="https://aleksandrhovhannisyan.github.io/"&gt;my personal website&lt;/a&gt;—having a vision for what I wanted and then researching all the necessary parts to bring it to life. I learned both web development and game development on my own time, on my own terms.&lt;/p&gt;

&lt;p&gt;Going into the Artificial Intelligence for Games class at the University of Florida, I had absolutely zero knowledge of the Unity game engine or C#—the main technologies we'd be using. How did I learn them in such a short period of time? By &lt;a href="https://github.com/cap4053-cheeky-pixels/EmbodyGame"&gt;working on a game that I came up with&lt;/a&gt; and that actually interested me. By Googling, reading tutorials, and actually going through the painstaking process of trying to make something work but hitting roadblocks along the way. And by working with other developers—something that online courses will rarely ever expose you to.&lt;/p&gt;

&lt;p&gt;What do you want to make? Figure that out, and just start Googling. If you decide that taking a course is the right path for you, at least don't waste your money on purchasing one—there are plenty of free resources online to get you where you need to go.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn to Code by Reading Code
&lt;/h2&gt;

&lt;p&gt;Becoming comfortable with reading other people's code is an essential skill for any developer. Much like how reading books can help you become a better writer by exposing you to different literary styles, techniques, genres, and overarching themes, reading code can make you a better programmer by exposing you to different solutions, architectures, design patterns, and language paradigms.&lt;/p&gt;

&lt;p&gt;I distinctly remember my fear of reading other people's code when I only had about a year of experience with programming. You're not familiar with the code, so everything naturally seems foreign to you, and you become frustrated and question why the author used certain naming conventions or design patterns. If you feel like this, you may be diving head-first into a complex project instead of dipping your toes in the water.&lt;/p&gt;

&lt;p&gt;Here are my recommendations for how to improve your code reading skills:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Join a site like &lt;a href="https://codereview.stackexchange.com/"&gt;Code Review&lt;/a&gt; on the Stack Exchange network. Beginners (and even advanced programmers) often post their code here for more experienced developers to review. This is an incredibly valuable resource for a budding programmer. I recommend that you read an original poster's code in its entirety, as slowly as you need to. Then, review the responses to see what kinds of feedback other developers provided. Understanding &lt;em&gt;why&lt;/em&gt; they made those recommendations can help you avoid making similar mistakes in your own code. If you need to, you can compile a list of common errors that you see and the corresponding recommendations that are provided. With time, though, you shouldn't need such a reference—it will all become second nature through repeated exposure to the same kinds of problems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Read tutorials. But with a caveat: Never ever follow just a &lt;em&gt;single&lt;/em&gt; tutorial blindly, copy-pasting things without understanding what the code is really doing. Instead, open a few (2–3) tutorials on a single topic and review them thoroughly. This is good for two reasons: 1) You're less likely to be misled by inexperienced developers who are actually imparting bad practices, and 2) if there are any discrepancies between the two tutorials, you can research those differences to gain a better understanding of why certain decisions were made in one snippet of code but not in another.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I found the second tip to be especially useful when learning CSS from scratch. Initially, I was quite afraid to read other people's stylesheets because I never really understood what their rules were doing. So what did I do? I read &lt;a href="https://www.w3schools.com/"&gt;W3Schools&lt;/a&gt;, &lt;a href="https://developer.mozilla.org/en-US/"&gt;MDN&lt;/a&gt;, &lt;a href="https://css-tricks.com/"&gt;CSS-Tricks&lt;/a&gt;, and other sites to find multiple ways to do the same thing in front-end. Then, for each line of CSS that was presented to me, I would enter the code locally, refresh my browser, and make a mental note of the visual change that occurred. If something was unclear, I would stop right then and Google that particular CSS property to see what exactly it does. All of this involved reading, and reading, and... more reading. It never stops—and it's an important skill to develop if you're serious about dev, regardless of what specialization you choose to pursue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Comfortable with Setting up a Dev Environment
&lt;/h2&gt;

&lt;p&gt;When it comes to working on large code bases, especially ones that are not your own, it's important that you know how to set up your local dev environment correctly, with all the right tools and dependencies. If you're new to this, consider the following exercise: Find an interesting project using &lt;a href="https://github.com/explore"&gt;GitHub's Explore section&lt;/a&gt; and clone it onto your own machine. Then, follow whatever directions they have in their README to set up your dev environment and successfully build the project locally.&lt;/p&gt;

&lt;p&gt;There's immense value to be found in this exercise because it's something that all developers need to know how to do on the job. If you run into any problems, do a bit of digging around online; it's likely that others have encountered the same problem before and that they've reported it either on GitHub, StackOverflow, or Reddit. If you have absolutely no luck, then you can consider opening an issue in the repo asking for help.&lt;/p&gt;

&lt;p&gt;A big part of this is learning how to ease your way into a terminal environment and relying less on traditional GUIs. In particular, knowing how to work with the Bash shell and its most popular commands will make your life a whole lot easier as a developer. If you want the best of both worlds, consider using &lt;a href="https://code.visualstudio.com/"&gt;Visual Studio Code&lt;/a&gt; as your IDE—it's free, has built-in support for terminals, features a marketplace of free extensions, and provides fluid integration with version control software like Git. All of these are things you'll eventually need to use as a programmer.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Note on Git
&lt;/h3&gt;

&lt;p&gt;Speaking of version control, if you're feeling lost with Git, then know this: There's no better way to "study" or learn Git than to actually use it for a real project. There are tons of online tutorials and videos that claim to help you understand Git in as little as 15 minutes, but they all ironically miss the key point: Git is an &lt;em&gt;applied technology&lt;/em&gt; that's difficult to understand or appreciate when it's used in isolation. Things may appear to click when you watch a video, but unless you use Git yourself, you'll forget it the next day.&lt;/p&gt;

&lt;p&gt;You absolutely need to associate Git with a hands-on project—ideally one that involves multiple collaborators—to understand why the &lt;a href="https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow"&gt;feature branch workflow&lt;/a&gt; is the commonly accepted standard, or why you should &lt;a href="https://www.atlassian.com/git/tutorials/merging-vs-rebasing"&gt;never rebase public branches&lt;/a&gt;. This will also help you to get comfortable with stashing your work, switching branches, amending commits, and checking out specific commits. These are all things that used to scare me when I had little to no experience with Git, but once you master them, you'll appreciate why they're so important.&lt;/p&gt;

&lt;p&gt;I also highly recommend that you avoid using a GUI client for Git, as they prevent you from mastering and remembering common Git commands. The command-line is your friend, not your enemy. If you struggle to remember what a certain command does, or how to achieve something in Git, feel free to reference &lt;a href="https://www.atlassian.com/git"&gt;the Atlassian docs&lt;/a&gt;—they're very well written. You'll also find many excellent answers to common Git questions on StackOverflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Know that Leetcode Is Not the Answer
&lt;/h2&gt;

&lt;p&gt;Remember the SATs and ACTs? Most people would rather not. It's a time when you're cramming material and vocabulary that you'll likely never need to use in your future, just for the sake of validating your intelligence so you can get into college. I hated the entire process and only appreciated one or two math tricks I learned along the way.&lt;/p&gt;

&lt;p&gt;Leetcode is the same. There's this pervasive (and arguably harmful) practice in the hiring industry where a programmer's aptitude is measured by their ability to &lt;a href="https://twitter.com/mxcl/status/608682016205344768?lang=en"&gt;solve coding puzzles on a whiteboard&lt;/a&gt;, and that has spawned a number of platforms like Leetcode, Hackerrank, and others dedicated to helping developers master the art of solving obscure puzzles. I've personally been fortunate enough to not have to go through this ordeal in my interviews, and I hope you don't either.&lt;/p&gt;

&lt;p&gt;Have people told you that you should cram Leetcode if you want to get a good job in tech? Stop listening to them. That may be the case if you want to get into elite unicorns, but it's not for the majority of developer positions. The best thing you can do is to work on personal projects and gain a deeper understanding of the technologies you want to work with in the future, as well as a solid grasp of CS fundamentals (which will most certainly come up during an interview). If you find yourself memorizing things, then you're going about this the wrong way.&lt;/p&gt;

&lt;p&gt;With all that said, I will admit that there are some rather interesting Leetcode problems that actually get you thinking and test your understanding of fundamental CS data structures. Here are my personal favorites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://leetcode.com/problems/reverse-linked-list/"&gt;Reversing a linked list&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://leetcode.com/problems/merge-two-sorted-lists/"&gt;Merging two sorted linked lists&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://leetcode.com/problems/implement-trie-prefix-tree/"&gt;Implementing a prefix tree from scratch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://leetcode.com/problems/validate-stack-sequences/"&gt;Validating stack sequences&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://leetcode.com/problems/map-sum-pairs/"&gt;Map sum pairs (prefix trees)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, if you're curious about solving these problems, do give them a shot. But don't waste your time &lt;em&gt;exclusively&lt;/em&gt; practicing Leetcode thinking that will somehow make you a better programmer (or a more qualified candidate for whatever position you're seeking). It's a very minor part of the overall picture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stop Beating Yourself Up
&lt;/h2&gt;

&lt;p&gt;Failure sucks. &lt;em&gt;A lot&lt;/em&gt;. But you need to get used to the feeling of frustration that programming generally brings because it's inevitable.&lt;/p&gt;

&lt;p&gt;This is where online programming courses tend to disappoint—once the training wheels come off, and as soon as you’re confronted with an unfamiliar problem, the panic sets in. Because up until now, every problem you'd ever encountered had a solution: an instructor who would happily tell you exactly how to do something.&lt;/p&gt;

&lt;p&gt;And then what happens? People turn to Quora, Reddit, or whatever other forums they frequent to vent and seek reassurance, to be told that coding isn’t that difficult and that they're not stupid and that they'll get better with time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VbXvN9y6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/learn-to-code-without-wasting-time-and-money/programming-woes.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VbXvN9y6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://aleksandrhovhannisyan.github.io/assets/img/posts/learn-to-code-without-wasting-time-and-money/programming-woes.webp" alt="Posts on r/programming from people who feel discouraged and overwhelmed."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The truth? You’re not stupid. Learning to code is literally learning to speak a new language—there's a rough transition period at the start where you're mostly doing things by rote memorization and repetition, and when few things actually make intuitive sense. But there eventually comes that moment of enlightenment where you look back and realize what it is that you were doing this entire time. It does eventually click and become second nature.&lt;/p&gt;

&lt;p&gt;Make no mistake, though: The process of &lt;em&gt;getting&lt;/em&gt; there won't be easy. And once you do get there, you'll realize that you're not a programming wizard (is anyone?) and that you still have many knowledge gaps. Unfortunately, people are misled into believing that programming is somehow easier to pick up than any other skill that pays well, or that spending money on courses will guarantee their success. In reality, becoming a good developer requires years of practice, self-motivation, and hard work.&lt;/p&gt;

&lt;p&gt;And, of course, you never stop learning.&lt;/p&gt;

</description>
      <category>learntocode</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Create Heading Links in Jekyll Without Any JavaScript (Using Includes)</title>
      <dc:creator>Aleksandr Hovhannisyan</dc:creator>
      <pubDate>Wed, 01 Jan 2020 13:29:19 +0000</pubDate>
      <link>https://dev.to/aleksandrhovhannisyan/create-heading-links-in-jekyll-without-any-javascript-using-includes-328h</link>
      <guid>https://dev.to/aleksandrhovhannisyan/create-heading-links-in-jekyll-without-any-javascript-using-includes-328h</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This is a syndicated post. If you'd like to, you can &lt;a href="https://aleksandrhovhannisyan.github.io/blog/dev/heading-links-in-jekyll/"&gt;view the original on my dev blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's a common practice in blogs to make a heading a link; this makes it easier for users to share a specific part of your content without linking to the entire post.&lt;/p&gt;

&lt;p&gt;How can we create heading links in Jekyll without losing our sanity and with zero lines of JavaScript?&lt;/p&gt;

&lt;p&gt;Answer: with the power of Jekyll includes!&lt;/p&gt;

&lt;h2&gt;
  
  
  Jekyll Heading Anchors with Includes
&lt;/h2&gt;

&lt;p&gt;Create a file named &lt;code&gt;linkedHeading.html&lt;/code&gt; in your &lt;code&gt;_includes&lt;/code&gt; folder. Here's what we want to do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a dynamic heading that can be any level we want.&lt;/li&gt;
&lt;li&gt;Give the heading an ID that we can reference.&lt;/li&gt;
&lt;li&gt;Nest an anchor inside that heading that references the ID from above.&lt;/li&gt;
&lt;li&gt;Fill the heading itself with some text.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With Liquid and Jekyll includes, it's super simple to create linked headings. Here's the markup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;assign&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;heading&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;include&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;heading&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&amp;lt;h&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;include&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; id="&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;heading&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;slugify&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;" class="linked-heading"&amp;gt;
    &amp;lt;a href="#&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;heading&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;slugify&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;"&amp;gt;#&amp;lt;/a&amp;gt; &lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;heading&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&amp;lt;/h&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;include&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simply use the following in your markdown to create a heading anchor in Jekyll:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight liquid"&gt;&lt;code&gt;&lt;span class="p"&gt;{%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;linkedHeading.html&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;heading&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"My Heading"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;someNumber&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Short and sweet! And much more legible than copy-pasting a bunch of heading tags and anchors. Plus, you don't have to introduce any unnecessary dependencies, JavaScript, or gems to get this done.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: If instead you want to link the entire heading, simply move &lt;code&gt;{{ heading }}&lt;/code&gt; into the anchor itself.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you're curious, here's how that works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;We pass in a string to &lt;code&gt;heading&lt;/code&gt;, which we access via &lt;code&gt;include.heading&lt;/code&gt;. We assign this to a local variable so we don't have to keep repeating &lt;code&gt;include.heading&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using Liquid objects, we specify the level of the heading dynamically with &lt;code&gt;h{{ include.level }}&lt;/code&gt;. So if we pass in &lt;code&gt;level=2&lt;/code&gt;, then we'll get &lt;code&gt;h2&lt;/code&gt;. Do this for both the opening and closing tags.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Give the h tag an ID. The ID will be the string we passed in, but &lt;a href="https://jekyllrb.com/docs/liquid/filters/"&gt;slugged&lt;/a&gt;. You can also give it a class name if you want to style it later.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a nested anchor that points to the same slug: &lt;code&gt;href="#{{ heading | slugify }}"&lt;/code&gt;. The anchor text can be anything you want. I was inspired by the &lt;a href="https://css-tricks.com/"&gt;CSS Tricks website&lt;/a&gt; and used a hashtag.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then, after the anchor, we simply put a space followed by our unformatted heading string.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sticky Navbar and Linked Headings
&lt;/h2&gt;

&lt;p&gt;If you have a sticky/fixed navbar like I do on my personal site, you may run into a problem where your heading anchors get stuck under the navbar when you click them.&lt;/p&gt;

&lt;p&gt;Fortunately, the fix is a neat little trick: a negative top margin combined with a positive top padding. I like to leave about a &lt;code&gt;40px&lt;/code&gt; difference between the two for spacing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-50px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;90px&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;My navbar is &lt;code&gt;64px&lt;/code&gt; tall, so I found that these two numbers work best. Feel free to play around with them. And of course, you can also apply this to other heading levels in case you want to link to them as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  And That's It!
&lt;/h2&gt;

&lt;p&gt;The best part is that you can pick which headings you want to link to.&lt;/p&gt;

&lt;p&gt;I hope you found this post helpful 🙂&lt;/p&gt;

</description>
      <category>jekyll</category>
      <category>html</category>
      <category>css</category>
      <category>blogging</category>
    </item>
  </channel>
</rss>
