<?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>Forem: Sergii Kirianov</title>
    <description>The latest articles on Forem by Sergii Kirianov (@skirianov).</description>
    <link>https://forem.com/skirianov</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%2F708812%2Ff6d3db1c-d9db-4291-a0e3-634ea678f2e0.png</url>
      <title>Forem: Sergii Kirianov</title>
      <link>https://forem.com/skirianov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/skirianov"/>
    <language>en</language>
    <item>
      <title>Building Reactive CLIs with Ink - React CLI library</title>
      <dc:creator>Sergii Kirianov</dc:creator>
      <pubDate>Fri, 03 Nov 2023 15:35:45 +0000</pubDate>
      <link>https://forem.com/skirianov/building-reactive-clis-with-ink-react-cli-library-4jpa</link>
      <guid>https://forem.com/skirianov/building-reactive-clis-with-ink-react-cli-library-4jpa</guid>
      <description>&lt;p&gt;As I said in the &lt;a href="https://codecryrepeat.hashnode.dev/learn-how-to-create-a-beautiful-cli-application-with-the-oclif-and-clackprompts" rel="noopener noreferrer"&gt;previous article&lt;/a&gt; about building CLIs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I'm in love with CLIs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But, I'm also in love with React, somehow it just clicks with me and even though it has received a lot of hate lately (if you haven't noticed it - you're not on &lt;a href="https://twitter.com/SergiiKirianov" rel="noopener noreferrer"&gt;Twitter X&lt;/a&gt;) I still love it 🤷‍♂️&lt;/p&gt;

&lt;p&gt;But did you know that you can build CLI apps with React?!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffik9pt3qbr8czuwqpzrp.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffik9pt3qbr8czuwqpzrp.gif" alt="Hell Yeaah!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article, let's learn how to build reactive CLIs with React Ink library 🫰&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Before we start though, let's take a look at the result CLI app that we will build together 👀&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawkb19lv73s48rldhxdk.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawkb19lv73s48rldhxdk.gif" alt="Result CLI app - Simplified File Explorer GIF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looks cool, right? Building a similar UI in the terminal without any library would be quite hard, though, thanks to &lt;a href="https://github.com/vadimdemedes/ink" rel="noopener noreferrer"&gt;Ink&lt;/a&gt; it's almost as easy as building any frontend UI with React.&lt;/p&gt;

&lt;h3&gt;
  
  
  Starting a project
&lt;/h3&gt;

&lt;p&gt;First, we will need to create a new project, for this, we will use the Ink command to generate a new project.&lt;/p&gt;

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

npx create-ink-app &lt;span class="nt"&gt;--typescript&lt;/span&gt; my-ink-cli


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

&lt;/div&gt;

&lt;p&gt;I'm going to use TypeScript, but it's not necessary and you can simply follow this guide omitting types.&lt;/p&gt;

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

&lt;p&gt;Let's open the project in the IDE and investigate the project structure.&lt;/p&gt;

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

&lt;p&gt;The project structure looks familiar if you have experience with React applications, the only significant difference is the &lt;code&gt;cli.tsx&lt;/code&gt; file. Let's take a look at both the &lt;code&gt;cli.tsx&lt;/code&gt; and &lt;code&gt;app.tsx&lt;/code&gt; files closely:&lt;/p&gt;

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

&lt;span class="c1"&gt;//app.tsx&lt;/span&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="s1"&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;Text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ink&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Stranger&lt;/span&gt;&lt;span class="dl"&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="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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green&lt;/span&gt;&lt;span class="dl"&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;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&lt;/span&gt;&lt;span class="err"&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;If you ever worked with React Native, this will look very similar to what you do in there. Instead of HTML elements, we are using built-in components that use Terminal APIs under the hood to render them. Ink provides a set of &lt;a href="https://github.com/vadimdemedes/ink#components" rel="noopener noreferrer"&gt;Components&lt;/a&gt; to use in your application. On top of the components, you can also observe that they receive props - &lt;code&gt;color&lt;/code&gt; in this example. Every component has a bunch of available props that mimic known CSS variables, you can find more about style props in the &lt;a href="https://github.com/vadimdemedes/ink#components" rel="noopener noreferrer"&gt;Ink's documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;app.tsx&lt;/code&gt; simply exports &lt;code&gt;App&lt;/code&gt; component, that receives &lt;code&gt;name&lt;/code&gt; prop.&lt;/p&gt;

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

&lt;span class="c1"&gt;// cli.tsx&lt;/span&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="s1"&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;render&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ink&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;meow&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;meow&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;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app.js&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;cli&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;meow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`
    Usage
      $ my-ink-cli

    Options
        --name  Your name

    Examples
      $ my-ink-cli --name=Jane
      Hello, Jane
`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;importMeta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&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="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;cli&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;

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

&lt;/div&gt;

&lt;p&gt;As you can see, &lt;code&gt;cli.tsx&lt;/code&gt; also looks pretty similar to React's root file, but, it has something more to offer using &lt;a href="https://github.com/sindresorhus/meow" rel="noopener noreferrer"&gt;&lt;code&gt;meow&lt;/code&gt; library&lt;/a&gt;. &lt;code&gt;meow&lt;/code&gt; is a popular library that helps you build nice CLI applications gives you access to create usage docs and handles args and flags.&lt;/p&gt;

&lt;p&gt;At the end of the file, you can find &lt;code&gt;render&lt;/code&gt; method, similar to what Web React does - renders top &lt;code&gt;App.tsx&lt;/code&gt; file.&lt;/p&gt;

&lt;h3&gt;
  
  
  First CLI application with Ink
&lt;/h3&gt;

&lt;p&gt;Let's get to the fun part and create our first tiny CLI app. First, we will remove unnecessary flags, props and replace everything inside &lt;code&gt;App&lt;/code&gt; component with a simple "Hello, World!" text.&lt;/p&gt;

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

&lt;span class="c1"&gt;//cli.tsx&lt;/span&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="s1"&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;render&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ink&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;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&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 typescript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;//app.tsx&lt;/span&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="s1"&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;Text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ink&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;World&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&lt;/span&gt;&lt;span class="err"&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;This will simply print the text in the console.&lt;/p&gt;

&lt;p&gt;Let's try it out! Remember, after every change in the CLI source code - you need to run &lt;code&gt;npm run build&lt;/code&gt; to create an executable file.&lt;/p&gt;

&lt;p&gt;After you build an application, you need to run it. To do that, you can run &lt;code&gt;cli.js&lt;/code&gt; file inside &lt;code&gt;dist&lt;/code&gt; folder 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp0nby3aj607xr2akqxxi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp0nby3aj607xr2akqxxi.png" alt="How to run CLI app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If everything was done right, you would get "Hello, World!" printed in the terminal - nothing much for now, but the first step towards our goal!&lt;/p&gt;

&lt;h2&gt;
  
  
  Building CLI File Explorer
&lt;/h2&gt;

&lt;p&gt;To build File Explorer we would need to do a few things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Show the current Path&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get the list of folders/files in the current directory&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Store them&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Render the list&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Navigate the list Up and Down&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go In and Out of directories using Enter and Delete keys (Backspace for Windows)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the changes to the UI to display the current path, selection, and current folders/files in a new directory&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sounds complicated, but bear with me, it will be easier than you think 😉&lt;/p&gt;

&lt;p&gt;Let's start with the simplest - show the current path and get a list of folders/files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Current Path and List of Folders/Files
&lt;/h3&gt;

&lt;p&gt;To simplify the process of running the commands, I will use &lt;a href="https://www.npmjs.com/package/execa" rel="noopener noreferrer"&gt;execa&lt;/a&gt; - abstraction library on top of Node.js &lt;code&gt;child_process&lt;/code&gt; methods.&lt;/p&gt;

&lt;p&gt;Install it:&lt;/p&gt;

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

npm i execa


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

&lt;/div&gt;

&lt;p&gt;execa will help us to run commands like &lt;code&gt;ls&lt;/code&gt; and &lt;code&gt;pwd&lt;/code&gt; inside the CLI application.&lt;/p&gt;

&lt;p&gt;First, let's create variables to store our path and folders/files. But...how should we do it? &lt;code&gt;let&lt;/code&gt;? &lt;code&gt;var&lt;/code&gt;? Nope 😌&lt;/p&gt;

&lt;p&gt;Remember, Ink is built on top of React, which means - we can use React hooks! Inside your &lt;code&gt;App&lt;/code&gt; component, add two variables using React's &lt;code&gt;useState&lt;/code&gt; hook:&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPath&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFiles&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&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;//if you don't use TypeScript, you can ommit &amp;lt;string[]&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Now, as in traditional React applications, whenever the &lt;code&gt;set*&lt;/code&gt; function is called and the value of &lt;code&gt;path&lt;/code&gt;/&lt;code&gt;files&lt;/code&gt; are changed, React will re-render respective components.&lt;/p&gt;

&lt;p&gt;Right now these values are empty, so, let's use another famous hook to populate them on &lt;code&gt;App&lt;/code&gt; component mount.&lt;/p&gt;

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

&lt;span class="nf"&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="nf"&gt;execa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ls&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-p&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setFiles&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&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="nf"&gt;execa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pwd&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&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;So, what's going on here?&lt;/p&gt;

&lt;p&gt;When &lt;code&gt;useEffect&lt;/code&gt; hook is called with an &lt;strong&gt;empty&lt;/strong&gt; dependencies array, which means it will run only once on component mount. When this happens, two things are executed:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;execa&lt;/code&gt; runs &lt;code&gt;ls&lt;/code&gt; command to list all folders/files in the current directory and &lt;code&gt;-p&lt;/code&gt; flag means that &lt;code&gt;ls&lt;/code&gt; command will append &lt;code&gt;/&lt;/code&gt; slash to the end of the folder names, which will help us later on to differentiate between folders and files&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* Once `execa` completes the command, we get access to `result` object. Since the resulted `stdout` is a text with every new folder/file representing a new line, we need to split them by `/n` and then we assign the resulting array to `files` variable.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;execa&lt;/code&gt; runs &lt;code&gt;pwd&lt;/code&gt; command to get the current path&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* Once `execa` completes the command, we get access to `result` object and set our `path` variable to `result.stdout` using `setPath` function.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, this is how our &lt;code&gt;app.tsx&lt;/code&gt; file looks:&lt;/p&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="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="s1"&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;Text&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ink&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;execa&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;execa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&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;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPath&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFiles&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;

    &lt;span class="nf"&gt;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="nf"&gt;execa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ls&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-p&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;setFiles&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&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="nf"&gt;execa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pwd&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;setPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&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="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;World&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&lt;/span&gt;&lt;span class="err"&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;We have all the data we need for now: current path and list of folders/files. Next, let's build a UI!&lt;/p&gt;

&lt;h3&gt;
  
  
  Path and Files UI
&lt;/h3&gt;

&lt;p&gt;Since this is just a guide, we will not go over our heads to create something stunning, but we will cover the main features of Ink.&lt;/p&gt;

&lt;p&gt;Let's start by creating a div...I mean, &lt;code&gt;Box&lt;/code&gt; and display the data that we've got:&lt;/p&gt;

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

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;yellow&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cyan&lt;/span&gt;&lt;span class="dl"&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;path&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Box&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;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&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;file&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Box&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Box&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;

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

&lt;/div&gt;

&lt;p&gt;As you can see, we used &lt;code&gt;Box&lt;/code&gt; and &lt;code&gt;Text&lt;/code&gt; component, that represents components similar to &lt;code&gt;div&lt;/code&gt; and &lt;code&gt;span&lt;/code&gt; respectively. We have used &lt;code&gt;color&lt;/code&gt; prop, to give them distinctive colors.&lt;/p&gt;

&lt;p&gt;Inside the top &lt;code&gt;Text&lt;/code&gt; component we display &lt;code&gt;path&lt;/code&gt; value and inside the &lt;code&gt;Box&lt;/code&gt; we iterate over &lt;code&gt;files&lt;/code&gt; array and render &lt;code&gt;Text&lt;/code&gt; component with it's contents.&lt;/p&gt;

&lt;p&gt;Let's run the application and see the result (don't forget to build it 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmz90ztq5vivytyyc9wmy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmz90ztq5vivytyyc9wmy.png" alt="First run"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you didn't get any errors during the build, you will see something similar.&lt;/p&gt;

&lt;p&gt;LOOKS UGLY!&lt;/p&gt;

&lt;p&gt;But, it does what we wanted - congrats! Now, let's yassify it 💅&lt;/p&gt;

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

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Box&lt;/span&gt; &lt;span class="nx"&gt;flexDirection&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;column&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;yellow&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cyan&lt;/span&gt;&lt;span class="dl"&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;path&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Box&lt;/span&gt; &lt;span class="nx"&gt;flexDirection&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;column&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;flexWrap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wrap&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;8&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;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="nx"&gt;paddingLeft&lt;/span&gt;&lt;span class="o"&gt;=&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="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;grey&lt;/span&gt;&lt;span class="dl"&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;file&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;))}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Box&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Box&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;

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

&lt;/div&gt;

&lt;p&gt;Build the CLI application again and run it:&lt;/p&gt;

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

&lt;p&gt;"Feel the difference 💅"&lt;/p&gt;

&lt;p&gt;The output looks way-way better! In the code above we have used CSS props that might have reminded you about inline CSS in JS. This is great, since if you know them, you will be super comfortable working with Ink!&lt;/p&gt;

&lt;p&gt;We have "fetched" and rendered the current path and folders/files - next, we need to add some interactivity and reactivity to our CLI.&lt;/p&gt;

&lt;h3&gt;
  
  
  User Input Handling
&lt;/h3&gt;

&lt;p&gt;Ink provides us with a lot of tools to build incredible and interactive CLIs. One of these is &lt;code&gt;useInput&lt;/code&gt; hook. &lt;code&gt;useInput&lt;/code&gt; hook allows us to watch for user input and based on the key they pressed react in any way we want.&lt;/p&gt;

&lt;p&gt;So, if you remember, one of the goals of our File Explorer application is to be able to navigate the files and go Up and Down the folders. Let's do just that.&lt;/p&gt;

&lt;h4&gt;
  
  
  Navigating files in the current directory
&lt;/h4&gt;

&lt;p&gt;Let's think about how we can allow users to navigate between the files. Since &lt;code&gt;files&lt;/code&gt; variable is an array, which means that we can navigate this array left and right if only we know the index, or better say - pointer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwknfmfeyre21zyuupy3j.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwknfmfeyre21zyuupy3j.gif" alt="pointer GIF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The animation above describes perfectly the approach we need to follow. We will create a variable &lt;code&gt;pointer&lt;/code&gt; that will be responsible for what the user is currently looking in the array. When the user hits &lt;code&gt;down&lt;/code&gt; key, we will increment the &lt;code&gt;pointer&lt;/code&gt; by 1 - meaning, the user now looks at &lt;code&gt;files[1]&lt;/code&gt; file. And if the user hits &lt;code&gt;up&lt;/code&gt; key, we will decrement the pointer by 1 - meaning, the user now looks at &lt;code&gt;files[0]&lt;/code&gt; file. Sounds like a plan 😌&lt;/p&gt;

&lt;p&gt;Let's implement it in the code using &lt;a href="https://github.com/vadimdemedes/ink#useinputinputhandler-options" rel="noopener noreferrer"&gt;&lt;code&gt;useInput&lt;/code&gt; hook&lt;/a&gt; from the Ink library.&lt;/p&gt;

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

&lt;span class="c1"&gt;//app.tsx&lt;/span&gt;
&lt;span class="c1"&gt;//...&lt;/span&gt;

&lt;span class="nf"&gt;useInput&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;upArrow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setPointer&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;prev&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;prev&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="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;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;downArrow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setPointer&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;prev&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;prev&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;//...&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;In the code above, we are using built-in &lt;code&gt;useInput&lt;/code&gt; hook that gives us access to &lt;code&gt;key&lt;/code&gt; argument that represents the key user clicked. I added some edge case handling, so that the &lt;code&gt;pointer&lt;/code&gt; can't become less than 0 and more than the last index in the &lt;code&gt;files&lt;/code&gt; array.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I could tell you to run the app and try it out, but you won't see anything.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's handle one last thing. We need to reflect the user's selection in the UI, otherwise &lt;code&gt;pointer&lt;/code&gt; will do the work, but the user won't be aware of what file they are looking at.&lt;/p&gt;

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

&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;pointer&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Box&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;flexDirection&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;row&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;paddingLeft&lt;/span&gt;&lt;span class="o"&gt;=&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="nx"&gt;justifyContent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;flex-start&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;greenBright&lt;/span&gt;&lt;span class="dl"&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;selected&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;  &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;selected&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;greenBright&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;grey&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Box&lt;/span&gt;&lt;span class="err"&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;In the code above we modified the rendering of &lt;code&gt;files&lt;/code&gt; array and added a few things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;selected&lt;/code&gt; - if &lt;code&gt;pointer&lt;/code&gt; is equal to &lt;code&gt;index&lt;/code&gt; of the current &lt;code&gt;file&lt;/code&gt; return true&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;top &lt;code&gt;Text&lt;/code&gt; component - responsible for showing &lt;code&gt;&amp;gt;&lt;/code&gt; sign pointing at folder/file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;bottom &lt;code&gt;Text&lt;/code&gt; component - modified to get color &lt;code&gt;greenBright&lt;/code&gt; if &lt;code&gt;selected&lt;/code&gt; true&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, we are ready! Let's build and test the application:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4bm8io7gjsdtp9f8ably.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4bm8io7gjsdtp9f8ably.gif" alt="Testing application with selection and navigation GIF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To stop the CLI application, when the terminal is in focus hit Ctrl+C&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This. Looks. GREAT!&lt;/p&gt;

&lt;p&gt;We've done an amazing job! Let's do one last thing and we are good.&lt;/p&gt;

&lt;h3&gt;
  
  
  In/Out Folders Handling
&lt;/h3&gt;

&lt;p&gt;We have handled most of the use cases for this application, except for one - how to navigate in and out of the folders. Let's not waste much time on it, since it includes all the things we have already covered above.&lt;/p&gt;

&lt;p&gt;Inside your &lt;code&gt;useInput&lt;/code&gt; hook add the following below &lt;code&gt;up&lt;/code&gt;/&lt;code&gt;down&lt;/code&gt; keys handling:&lt;/p&gt;

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

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&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;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]?.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;newPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;execa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ls&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-p&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newPath&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setFiles&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&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="nf"&gt;setPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newPath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;setPointer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backspace&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;newPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&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;newPath&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;newPath&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&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;newPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newPath&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;execa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ls&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-p&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newPath&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setFiles&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&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="nf"&gt;setPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newPath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;setPointer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Let's break the code above into steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;If &lt;code&gt;key&lt;/code&gt; === &lt;code&gt;return&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if the user tries to enter inside "non-directory"(file) - return&lt;/li&gt;
&lt;li&gt;create a new path string using the current &lt;code&gt;files[pointer]&lt;/code&gt; folder name and remove &lt;code&gt;/&lt;/code&gt; from the end of the string&lt;/li&gt;
&lt;li&gt;use &lt;code&gt;execa&lt;/code&gt; to run &lt;code&gt;ls&lt;/code&gt; command inside &lt;code&gt;newPath&lt;/code&gt; directory&lt;/li&gt;
&lt;li&gt;when &lt;code&gt;execa&lt;/code&gt; is done, set new files to the resulting &lt;code&gt;stdout&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;set a new path using &lt;code&gt;setPath&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;set &lt;code&gt;pointer&lt;/code&gt; to 0&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;if &lt;code&gt;key&lt;/code&gt; === &lt;code&gt;delete&lt;/code&gt; or &lt;code&gt;backspace&lt;/code&gt; (to support Windows)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create a new path by removing the last part of the &lt;code&gt;path&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;if the new path ends with &lt;code&gt;/&lt;/code&gt; - remove it&lt;/li&gt;
&lt;li&gt;use &lt;code&gt;execa&lt;/code&gt; to run &lt;code&gt;ls&lt;/code&gt; command inside &lt;code&gt;newPath&lt;/code&gt; directory&lt;/li&gt;
&lt;li&gt;when &lt;code&gt;execa&lt;/code&gt; is done, set new files to the resulting &lt;code&gt;stdout&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;set a new path using &lt;code&gt;setPath&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;set &lt;code&gt;pointer&lt;/code&gt; to 0&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Time to try it out!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxn7vknro6345kv7iaaj8.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxn7vknro6345kv7iaaj8.gif" alt="navigate in and out folders"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Awesome! Works well and looks great!&lt;/p&gt;

&lt;h4&gt;
  
  
  Bonus: User Hints
&lt;/h4&gt;

&lt;p&gt;Last, but not least, let's add some user hints, so they know how to use this application. Add the code below after the &lt;code&gt;Box&lt;/code&gt; rendering &lt;code&gt;files&lt;/code&gt; array:&lt;/p&gt;

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

&lt;span class="c1"&gt;//app.tsx&lt;/span&gt;
&lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Box&lt;/span&gt; &lt;span class="nx"&gt;flexDirection&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;column&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;grey&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;Press&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;greenBright&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Enter&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&amp;gt; to enter a directory, &amp;lt;Text color='greenBright'&amp;gt;Delete&amp;lt;/&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;go&lt;/span&gt; &lt;span class="nx"&gt;up&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;directory&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;grey&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;Use&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yellow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Up&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&amp;gt; and &amp;lt;Text color='yellow'&amp;gt;Down&amp;lt;/&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;navigate&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Box&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="c1"&gt;//...&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;For the last time today - build and run the app!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjlv26cmbf2lncpc2wxlh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjlv26cmbf2lncpc2wxlh.png" alt="Final CLI application with hints"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusions
&lt;/h3&gt;

&lt;p&gt;In this article, we used Ink - React-based library for building reactive and interactive UI CLI applications, to build our own CLI File Explorer app!&lt;/p&gt;

&lt;p&gt;Ink is one of the greatest examples of how powerful React is, even outside of the Web. React ideology and built-in hooks and APIs are powerful enough even for CLIs and way more than that.&lt;/p&gt;

&lt;p&gt;Our application is not complete though. The user wants not only to explore the folders and files but also &lt;code&gt;cd&lt;/code&gt; into folders and quit the CLI app without doing it themselves, but, I will leave it for you 😏 Let me know in the comments if you were able to finish it!&lt;/p&gt;

&lt;p&gt;Thanks for reading and I hope you enjoyed it! Hit me up on &lt;a href="https://twitter.com/SergiiKirianov" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; if you have any questions and give a star to &lt;a href="https://github.com/vadimdemedes/ink" rel="noopener noreferrer"&gt;Ink&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Learn Next.js Server Side Rendering by building your own implementation</title>
      <dc:creator>Sergii Kirianov</dc:creator>
      <pubDate>Wed, 11 Oct 2023 19:10:09 +0000</pubDate>
      <link>https://forem.com/skirianov/learn-nextjs-server-side-rendering-by-building-your-own-implementation-41m8</link>
      <guid>https://forem.com/skirianov/learn-nextjs-server-side-rendering-by-building-your-own-implementation-41m8</guid>
      <description>&lt;p&gt;If you're here, most probably you have issues understanding how &lt;em&gt;Server Side Rendering&lt;/em&gt; (SSR) works in meta frameworks like Next.js. I had them too and this is why I decided that I want to learn how they work under the hood and the best thing to do it - build it yourself.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Of course you could also read Next.js source code, but it's really hard to understand it if you never had experience with projects so big and complex.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, where are we at?&lt;/p&gt;

&lt;h2&gt;
  
  
  Understand Server Side Rendering
&lt;/h2&gt;

&lt;p&gt;First, to get a good understanding of what we are about to do, let's talk about what &lt;em&gt;Server Side Rendering&lt;/em&gt; is.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3iy0xh8ct7jpe4zlnng4.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3iy0xh8ct7jpe4zlnng4.gif" alt="Jack Black opens up a book GIF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Server Side Rendering&lt;/strong&gt; is a process where a web server generates an HTML page on the server itself, rather than letting JavaScript handle that on the client (browser).&lt;/p&gt;

&lt;p&gt;When a user visits a web page, the server will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Get the data from the database if required&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inject this data into the HTML template&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Respond with the resulting HTML back to the client&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the end, the browser would receive a generated HTML page and then request all the necessary static assets like CSS, JavaScript, etc.&lt;/p&gt;

&lt;p&gt;This is a very well-known process that was around for ages, but not in the React world. Next.js (along with other meta-frameworks) has popularised a new approach, where you basically write the same React as usual with a few new ways of fetching data and underlying technology will take care of rendering React on the server and delivering a complete HTML page to the client, instead of originally bare minimum HTML and a lot of JavaScript.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Next.js does way more than just that, but we only care about SSR here 😌&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Those who are new in the Next.js world may wonder, how the heck React - a frontend JavaScript framework can be rendered on the server but still has all the features like &lt;code&gt;useState&lt;/code&gt;, &lt;code&gt;useEffect&lt;/code&gt;, etc on the client?&lt;/p&gt;

&lt;p&gt;So, let's recreate Next.js &lt;em&gt;Server Side Rendering&lt;/em&gt; functionality from scratch and go step by step to understand "what the heck is going on" and "how the heck &lt;code&gt;getServerSideProps&lt;/code&gt; function is even called"?&lt;/p&gt;

&lt;p&gt;Welcome to &lt;strong&gt;"Learn Next.js Server Side Rendering by building your own" 😁&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Setup
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkf296fb18cehpl44tip3.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkf296fb18cehpl44tip3.gif" alt="Girl building with hammer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to create SSR functionality, first we need to create that very first &lt;strong&gt;'S'&lt;/strong&gt; - server. Since I don't know anything else than JavaScript (TypeScript doesn't count, okay?) and also Next.js uses Node.js under the hood, &lt;strong&gt;AND ALSO&lt;/strong&gt; we still need to work with React since it uses JavaScript - let's start with that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating Node.js Server
&lt;/h3&gt;

&lt;p&gt;For this tutorial, I want to create a bare-bone Node.js application and start building it along with you, so we don't miss anything 😁&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ready?&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Start New Project
&lt;/h4&gt;

&lt;p&gt;Create a new folder &lt;code&gt;react-ssr&lt;/code&gt;, &lt;strong&gt;cd&lt;/strong&gt; into it and generate a new npm project by running:&lt;/p&gt;

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

npm init


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

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F28ygg7kjwsq9ejov4ots.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F28ygg7kjwsq9ejov4ots.gif" alt="GIF showing the creation of react-ssr folder and npm init command"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Good news - this part is done 🤣&lt;/p&gt;

&lt;h4&gt;
  
  
  Create a Basic Express.js Application
&lt;/h4&gt;

&lt;p&gt;Since we are not replicating the Next.js server, but doing a simplified version of it, I will use the Express.js library to create the server and handle requests.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I will use yarn package manager, but you're free to use anything you prefer&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Install &lt;code&gt;express&lt;/code&gt; and create a basic Express.js application&lt;/p&gt;

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

yarn add express


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

&lt;/div&gt;

&lt;p&gt;In the root of your project create a new file &lt;code&gt;server.js&lt;/code&gt; and paste the following code:&lt;/p&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&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;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&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;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello World!&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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&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="s2"&gt;`Server is listening on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Let's test it out. Start the server from the terminal &lt;code&gt;node server.js&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fliqjalohp326axxshkv2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fliqjalohp326axxshkv2.png" alt="Cannot use import outside of the modeule"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! Our first error 😁&lt;/p&gt;

&lt;p&gt;Node.js cannot use &lt;code&gt;import&lt;/code&gt; by default, so in order to fix that, we will need to add a transpile step in our workflow.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Trust me, this will help us in the future, so bear with me even if right now it looks like unnecessary comlpexity&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To transpile our code, we will use &lt;a href="https://babeljs.io/" rel="noopener noreferrer"&gt;Babel&lt;/a&gt; - a JavaScript compiler, that will generate files Node.js is happy with, and &lt;a href="https://webpack.js.org/" rel="noopener noreferrer"&gt;Webpack&lt;/a&gt; - a JavaScript bundler, that will bundle our code and automate the compilation step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configure Babel&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, install all the necessary dependencies by running the following code:&lt;/p&gt;

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

yarn add &lt;span class="nt"&gt;-D&lt;/span&gt; @babel/core @babel/cli @babel/preset-env


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

&lt;/div&gt;

&lt;p&gt;This will add packages as &lt;code&gt;devDependencies&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, at the root of your project create &lt;code&gt;.babelrc&lt;/code&gt; file and paste the following configuration inside:&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="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;presets"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;@babel/preset-env"&lt;/span&gt;
  &lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="pi"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Let's test it! Run the following command inside your project:&lt;/p&gt;

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

npx babel server.js &lt;span class="nt"&gt;--out-file&lt;/span&gt; test-server.js


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

&lt;/div&gt;

&lt;p&gt;Babel will transpile our &lt;code&gt;server.js&lt;/code&gt; file and create a new &lt;code&gt;test-server.js&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Start the project&lt;/p&gt;

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

node test-server.js


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

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm06shbtchj6rgx2qah5i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm06shbtchj6rgx2qah5i.png" alt="Screenshot of successfully running Express app on port 3000"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If everything went well, congrats your server is started ✨&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configure Webpack&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Okay, okay, this all may be a bit hard, but this is the last configuration step, I promise!&lt;/p&gt;

&lt;p&gt;Install Webpack dependencies and &lt;code&gt;babel-loader&lt;/code&gt; package&lt;/p&gt;

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

yarn add &lt;span class="nt"&gt;-D&lt;/span&gt; webpack webpack-cli webpack-node-externals babel-loader


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

&lt;/div&gt;

&lt;p&gt;Again, adding packages to your &lt;code&gt;devDependencies&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the root of your project create a new file &lt;code&gt;webpack.config.js&lt;/code&gt; and paste the following code inside:&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;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path&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;nodeExternals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;webpack-node-externals&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="c1"&gt;// Server-side configuration&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./server.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Compiles for node.js environment&lt;/span&gt;
    &lt;span class="na"&gt;externals&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;nodeExternals&lt;/span&gt;&lt;span class="p"&gt;()],&lt;/span&gt; &lt;span class="c1"&gt;// Excludes node_modules from the server bundle&lt;/span&gt;
    &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;server.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dist&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;publicPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/static/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;module&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;rules&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="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.(&lt;/span&gt;&lt;span class="sr"&gt;js|jsx&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;exclude&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/node_modules/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;babel-loader&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="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.jsx&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;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;development&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Here we are simply telling Webpack to get entry file for server from the root folder and after everything is bundled store the final file inside dist folder.&lt;/p&gt;

&lt;p&gt;Just try to read it top to bottom line by line and you'll see it 😉&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And let's create a new script inside &lt;code&gt;package.json&lt;/code&gt; file to run our app from a single command. Replace &lt;code&gt;"scripts"&lt;/code&gt; object with the following code.&lt;/p&gt;

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

&lt;span class="c1"&gt;// you can remove "test" script from the file&lt;/span&gt;

&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scripts&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;webpack --watch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nodemon dist/server.js&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;What does it do?&lt;/p&gt;

&lt;p&gt;"build" - telling Webpack to bundle the code as per config and watch if entry files change, if yes - rebuild&lt;/p&gt;

&lt;p&gt;"start" - nodemon watches server.js file inside dist folder and if it changes, restarts the server&lt;/p&gt;

&lt;p&gt;P.S. if you don't have nodemon installed globally, add it as a dependency to the project - yarn add -D nodemon&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, shall we?&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;yarn build&lt;/code&gt; (or &lt;code&gt;npm run build&lt;/code&gt; if you chose npm) - Webpack will generate the final bundled files.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;yarn start&lt;/code&gt; - your server should be up and running!&lt;/p&gt;

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

&lt;p&gt;Phew! That was a bit intense, but trust me, we would end up doing it anyway once we get to the React part.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BACK TO THE FUN PART&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadpq9y7zfhfdkbazxevj.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadpq9y7zfhfdkbazxevj.gif" alt="Kid dancing fun"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  First React Component
&lt;/h2&gt;

&lt;p&gt;If you still remember what we are here for - good job. If not, I will remind you. We want to render React page on the server and for that, guess what, we need React component! Let's start with something very simple.&lt;/p&gt;

&lt;p&gt;Inside the root of your project create a new folder &lt;code&gt;app&lt;/code&gt; and subfolder &lt;code&gt;pages&lt;/code&gt; - this is where we will keep our React page (we are mimicking Next.js after all)&lt;/p&gt;

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

&lt;p&gt;Let's install React and React-DOM&lt;/p&gt;

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

yarn add react react-dom


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

&lt;/div&gt;

&lt;p&gt;And also Babel React preset as &lt;code&gt;devDependency&lt;/code&gt;&lt;/p&gt;

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

yarn add &lt;span class="nt"&gt;-D&lt;/span&gt; @babel/preset-react


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

&lt;/div&gt;

&lt;p&gt;Now our project is ready to use React. Inside &lt;code&gt;app/pages/index.jsx&lt;/code&gt; create a very basic React component:&lt;/p&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="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="s1"&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HomePage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Home&lt;/span&gt; &lt;span class="nx"&gt;Page&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="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;Good, but, how do we render it? 🤔&lt;/p&gt;

&lt;h3&gt;
  
  
  Rendering React Component on The Server
&lt;/h3&gt;

&lt;p&gt;Luckily there's already a function for us available from the &lt;code&gt;react-dom&lt;/code&gt; package - &lt;strong&gt;renderToString&lt;/strong&gt; - you can read more about it here &lt;a href="https://react.dev/reference/react-dom/server/renderToString" rel="noopener noreferrer"&gt;&lt;strong&gt;Server React DOM APIs&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As per React docs &lt;code&gt;renderToString&lt;/code&gt; renders a React tree to an HTML string - exactly what we need in order to get HTML out of React component!&lt;/p&gt;

&lt;p&gt;Let's change our Express app to use the function in order to render &lt;code&gt;HomePage&lt;/code&gt; to string that we later can pass inside the HTML page.&lt;/p&gt;

&lt;h4&gt;
  
  
  Modifying Express App
&lt;/h4&gt;

&lt;p&gt;My idea is that when a user visits the &lt;code&gt;/&lt;/code&gt; route, &lt;code&gt;HomePage&lt;/code&gt; the component will be rendered. For that, let's change the &lt;code&gt;/&lt;/code&gt; route handler.&lt;/p&gt;

&lt;p&gt;Inside the &lt;code&gt;server.js&lt;/code&gt; file:&lt;/p&gt;

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

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&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;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;htmlContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;renderToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HomePage&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`
    &amp;lt;!DOCTYPE html &amp;gt;
    &amp;lt;html lang="en"&amp;gt;
      &amp;lt;head&amp;gt;
        &amp;lt;meta charset="UTF-8"&amp;gt;
        &amp;lt;title&amp;gt;React SSR&amp;lt;/title&amp;gt;
      &amp;lt;/head&amp;gt;
      &amp;lt;body&amp;gt;
        &amp;lt;div id="root"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;htmlContent&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/div&amp;gt;
      &amp;lt;/body&amp;gt;
    &amp;lt;/html&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;Don't forget to import &lt;code&gt;renderToString&lt;/code&gt; function and &lt;code&gt;HomePage&lt;/code&gt; component.&lt;/p&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;renderToString&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-dom/server&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;HomePage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app/pages&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;So, let's see what it does step by step:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;app.get('/', () =&amp;gt; {})&lt;/code&gt; - listens to index route (&lt;code&gt;/&lt;/code&gt;) and calls the function when a GET request is received.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;const htmlContent = renderToString(&amp;lt;HomePage /&amp;gt;);&lt;/code&gt; - using the &lt;code&gt;react-dom/server&lt;/code&gt; function takes React component as an argument and renders it to an HTML string.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;res.send(`...`);&lt;/code&gt; - injects &lt;code&gt;htmlContent&lt;/code&gt; inside template HTML string and sends as a response to the client&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check the diagram below to see the overview of this process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbtt1fg90xak0gijwlaqe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbtt1fg90xak0gijwlaqe.png" alt="Overview of Client - Server communication"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I bet you are eager to try it out!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Well, let's try it 😉&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fznp5xk8qko8qc4kq488j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fznp5xk8qko8qc4kq488j.png" alt="Homepage error"&gt;&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq9coio88x5ea28e6w3ci.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq9coio88x5ea28e6w3ci.gif" alt="crying man"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Right...Webpack doesn't know about React. Let's fix it 🙌&lt;/p&gt;

&lt;p&gt;Add the following to your &lt;code&gt;.babelrc&lt;/code&gt; file:&lt;/p&gt;

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

&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;presets&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@babel/preset-env&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@babel/preset-react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;---- ADD 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;&lt;strong&gt;TRY AGAIN!&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fudjrqmad2mg9y29i5jx9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fudjrqmad2mg9y29i5jx9.png" alt="Successful build"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alright, the build is successful! Now, let's start it and visit &lt;code&gt;localhost&lt;/code&gt;!&lt;/p&gt;

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

&lt;span class="nx"&gt;yarn&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Open your browser and navigate to &lt;code&gt;http://localhost:3000&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjygj0k4opzb28yi7fbbh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjygj0k4opzb28yi7fbbh.png" alt="Another error - React is not defined"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Okay, okay, I won't torture you anymore. Basically, what is happening is that our &lt;code&gt;server.js&lt;/code&gt; file cannot use React unless we import it and rename the file to &lt;code&gt;.jsx&lt;/code&gt; too, so we can use JSX inside of it.&lt;/p&gt;

&lt;p&gt;Let's fix that!&lt;/p&gt;

&lt;h4&gt;
  
  
  Fixing Express / React incompatibility
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;First, import React to your &lt;code&gt;server.js&lt;/code&gt; file&lt;/li&gt;
&lt;/ol&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&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;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- ADD THIS&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;renderToString&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-dom/server&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;HomePage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app/pages&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;ol&gt;
&lt;li&gt;&lt;p&gt;Next, rename &lt;code&gt;server.js&lt;/code&gt; to &lt;code&gt;server.jsx&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And modify the Webpack config&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

    &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./server.jsx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;--- CHANGE .js to .jsx&lt;/span&gt;
    &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="nx"&gt;externals&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;nodeExternals&lt;/span&gt;&lt;span class="p"&gt;()],&lt;/span&gt;
    &lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;server.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dist&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nx"&gt;publicPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/static/&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;Good, let's try it again.&lt;/p&gt;

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

&lt;span class="nx"&gt;yarn&lt;/span&gt; &lt;span class="nx"&gt;build&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;yarn&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Go to &lt;code&gt;localhost:3000&lt;/code&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;YASSSSSS!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Awesome! Now, we have legit &lt;em&gt;Server Side Rendered&lt;/em&gt; React code! Congratulations!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3qssk0xxzof3ep1p53e5.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3qssk0xxzof3ep1p53e5.gif" alt="man dancing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Make It Real React
&lt;/h2&gt;

&lt;p&gt;We have managed to render React on the server side and ship it to the client. But...is it even React? 🥲&lt;/p&gt;

&lt;p&gt;Since we are on our way to mimicking Next.js, let's mimic more of it! Something like &lt;code&gt;getServerSideProps&lt;/code&gt; maybe? 👀&lt;/p&gt;

&lt;h3&gt;
  
  
  notNextServerSideProps
&lt;/h3&gt;

&lt;p&gt;Let's create a function that will be exported from our page and used to fetch data on &lt;em&gt;Server Side&lt;/em&gt; too. Go to &lt;code&gt;app/pages/index.jsx&lt;/code&gt; and add the following code outside of the &lt;code&gt;HomePage&lt;/code&gt; component:&lt;/p&gt;

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

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;notNextServerSideProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://fakestoreapi.com/products&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&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="s1"&gt;All Products&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;products&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkf1t3bak04yhkww8slkz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkf1t3bak04yhkww8slkz.png" alt="X (ex Twitter) What is happening screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Inside the &lt;code&gt;notNextServerSideProps&lt;/code&gt; function we are making a call to &lt;a href="https://fakestoreapi.com/" rel="noopener noreferrer"&gt;Fake Store API&lt;/a&gt; - an open and free e-commerce store API. Here, we are simply getting a list of products.&lt;/p&gt;

&lt;p&gt;Once we get the data, we return it as &lt;code&gt;props&lt;/code&gt; object, adding custom &lt;code&gt;title&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In order to be able to use fetch in Node.js application, we will install node-fetch package ("node-fetch": "^2.6.7") and pass it as an argument.&lt;/p&gt;

&lt;p&gt;This is a workaround(!), but for a simple prototype will do.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Calling notNextServerSideProps on The Server
&lt;/h4&gt;

&lt;p&gt;First, install &lt;code&gt;node-fetch&lt;/code&gt; the package. We will go with the version &lt;code&gt;2.6.7&lt;/code&gt; since it is &lt;strong&gt;commonjs&lt;/strong&gt; package and it will save us some time.&lt;/p&gt;

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

&lt;span class="nx"&gt;yarn&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;D&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;6.7&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Let's modify the &lt;code&gt;/&lt;/code&gt; route handler and call &lt;code&gt;notNextServerSideProps&lt;/code&gt; in order to fetch the data on the server.&lt;/p&gt;

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

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;notNextServerSideProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fetch&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;htmlContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;renderToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HomePage&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;initialData&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="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`
    &amp;lt;!DOCTYPE html &amp;gt;
    &amp;lt;html lang="en"&amp;gt;
      &amp;lt;head&amp;gt;
        &amp;lt;meta charset="UTF-8"&amp;gt;
        &amp;lt;title&amp;gt;React SSR&amp;lt;/title&amp;gt;
      &amp;lt;/head&amp;gt;
      &amp;lt;body&amp;gt;
        &amp;lt;div id="root"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;htmlContent&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/div&amp;gt;
      &amp;lt;/body&amp;gt;
    &amp;lt;/html&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;ul&gt;
&lt;li&gt;&lt;p&gt;First, we made &lt;code&gt;app.get&lt;/code&gt; callback an async function, so we can await a response from the Fake Store API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;initialData&lt;/code&gt; - data returned from &lt;code&gt;notNextServerSideProps&lt;/code&gt; function&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;&amp;lt;HomePage {...initialData.props} /&amp;gt;&lt;/code&gt; - pass the &lt;code&gt;initialData.props&lt;/code&gt; as props to &lt;code&gt;HomePage&lt;/code&gt; component.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don't forget to update your imports! (&lt;em&gt;I forgot while writing this article)&lt;/em&gt;&lt;/p&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HomePage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;notNextServerSideProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app/pages&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;--&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node-fetch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//&amp;lt;-- using node-fetch library&lt;/span&gt;


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

&lt;/div&gt;
&lt;h4&gt;
  
  
  Rendering React Component with Props
&lt;/h4&gt;

&lt;p&gt;Now, we will need to change the &lt;code&gt;HomePage&lt;/code&gt; component, so it can actually receive and use props inside.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HomePage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;title&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&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;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="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;For now, we will keep it simple and render &lt;code&gt;title&lt;/code&gt; only. Save files, build (&lt;code&gt;yarn build&lt;/code&gt;) project and start it again, then visit &lt;code&gt;localhost:3000&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;Good! The &lt;code&gt;notNextServerSideProps&lt;/code&gt; function is running and passing props down to the React component, which then renders with the dynamic data.&lt;/p&gt;

&lt;p&gt;Let's utilize the data we receive from Fake Store API then!&lt;/p&gt;

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

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HomePage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;products&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&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;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;
          &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
            &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;flexDirection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;column&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;200px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1px solid black&lt;/span&gt;&lt;span class="dl"&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&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;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;))}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Here, we destructure &lt;code&gt;products&lt;/code&gt; from &lt;code&gt;props&lt;/code&gt; and map over them in order to display product data. We also add some inline style just to help us visualize it better (&lt;em&gt;it will be ugly - bear with me&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Once again, build -&amp;gt; start -&amp;gt; &lt;code&gt;localhost:3000&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgsdpmcjyznjvoi9mzn6h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgsdpmcjyznjvoi9mzn6h.png" alt="Server Side Rendered data fetched on server rendered on client"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GOOOOOOOOOOOOOOD!&lt;/p&gt;

&lt;p&gt;We have implemented a very hacky and very simplified version of Next.js &lt;strong&gt;getServerSideProps&lt;/strong&gt; ourselves! How cool is that, huh?!&lt;/p&gt;

&lt;h2&gt;
  
  
  I Said Real React
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fygxy6kgzyqnabbxze381.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fygxy6kgzyqnabbxze381.gif" alt="X-men Magneto meme"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;React is not only about mapping over an array of data and rendering it. React is all about &lt;em&gt;'reactivity'&lt;/em&gt; (pun intended). And this is what our app is lacking at the moment.&lt;/p&gt;

&lt;p&gt;But, how can we add reactivity to the page if we don't have any JavaScript inside the HTML page and especially nothing close to React itself - this is where Hydration comes into play.&lt;/p&gt;

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

&lt;p&gt;As per ChatGPT&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Hydration&lt;/strong&gt;: To make this static content interactive, React needs to attach event listeners and establish its internal representation of the page. This process is called "hydration." During hydration, React will preserve the server-rendered markup and attach event handlers to it, effectively turning the static content into a dynamic React application.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What it means is that React will take over the rendering inside the browser, use the HTML and data provided by the server and make things clickable, interactive, and &lt;em&gt;reactive&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Luckily for us (&lt;strong&gt;again&lt;/strong&gt;) React team has another function for us called &lt;code&gt;hydrateRoot&lt;/code&gt;. You can read more about it here - &lt;a href="https://react.dev/reference/react-dom/client/hydrateRoot" rel="noopener noreferrer"&gt;React Client APIs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It's very easy to use this function. We need to create an entry point into our Client application, get the &lt;code&gt;root&lt;/code&gt; element of our app and using &lt;code&gt;hydrateRoot&lt;/code&gt; - hydrate components into the &lt;code&gt;root&lt;/code&gt; element (sorry for the tautology).&lt;/p&gt;

&lt;h4&gt;
  
  
  Create Client Application
&lt;/h4&gt;

&lt;p&gt;To create an entry point to our application, inside &lt;code&gt;app&lt;/code&gt; folder, let's create &lt;code&gt;app.jsx&lt;/code&gt; file and write some code inside:&lt;/p&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="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="s1"&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;hydrateRoot&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-dom/client&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;HomePage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./pages&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;domNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&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;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;hydrateRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;domNode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HomePage&lt;/span&gt; &lt;span class="o"&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;As we learned before, we get &lt;code&gt;root&lt;/code&gt; element from the DOM and hydrate component inside it using &lt;code&gt;hydrateRoot&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;But this will lead to an error, many errors to be honest, but let's start one by one.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It's extremely important that SSR React output (HTML) and CSR React output (HTML) are matching, otherwise React will not be able to render and attach event listeners properly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In order to make sure that the data available to &lt;code&gt;HomePage&lt;/code&gt; the component is exactly the same, Next.js injects this data as a global variable inside &lt;code&gt;window&lt;/code&gt; the object as part of the HTML it returns to the client.&lt;/p&gt;

&lt;p&gt;Let's do it together but before that!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extract HTML Template in The Separate Function&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So far we were injecting &lt;code&gt;htmlContent&lt;/code&gt; directly in the string inside the &lt;code&gt;/&lt;/code&gt; route handler. This is of course not optimal, since the more routes we get, the more HTML templates we will have hardcoded in our project.&lt;/p&gt;

&lt;p&gt;To avoid that and make the template more versatile, let's create &lt;code&gt;document.js&lt;/code&gt; file and &lt;code&gt;document&lt;/code&gt; function inside it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;By the way, this will be simplified version of Next.js _document.js file&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Create &lt;code&gt;utils/document.js&lt;/code&gt; file in the root of your project and paste the following code:&lt;/p&gt;

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

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;htmlContent&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="s2"&gt;`
    &amp;lt;!DOCTYPE html &amp;gt;
    &amp;lt;html lang="en"&amp;gt;
      &amp;lt;head&amp;gt;
        &amp;lt;meta charset="UTF-8"&amp;gt;
        &amp;lt;title&amp;gt;React SSR&amp;lt;/title&amp;gt;
      &amp;lt;/head&amp;gt;
      &amp;lt;body&amp;gt;
        &amp;lt;div id="root"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;htmlContent&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/div&amp;gt;
      &amp;lt;/body&amp;gt;
    &amp;lt;/html&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;Now, go back to &lt;code&gt;server.jsx&lt;/code&gt; and change the route handler:&lt;/p&gt;

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

&lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./utils/document&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;//...&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;notNextServerSideProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fetch&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;htmlContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;renderToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HomePage&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;initialData&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="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;document&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;htmlContent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;html&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;We can reuse this function for future pages!&lt;/p&gt;

&lt;h4&gt;
  
  
  Pass Initial Data to HTML
&lt;/h4&gt;

&lt;p&gt;Let's add &lt;code&gt;initialData&lt;/code&gt; that we receive from the &lt;code&gt;notNextServerSideProps&lt;/code&gt; function and inject it into HTML. For this, we need to pass it on to the &lt;code&gt;document&lt;/code&gt; function and then add it as a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag inside HTML template.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;document.js&lt;/code&gt; file and replace the existing code with the new one:&lt;/p&gt;

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

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;htmlContent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initialData&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="s2"&gt;`
    &amp;lt;!DOCTYPE html &amp;gt;
    &amp;lt;html lang="en"&amp;gt;
      &amp;lt;head&amp;gt;
        &amp;lt;meta charset="UTF-8"&amp;gt;
        &amp;lt;title&amp;gt;React SSR&amp;lt;/title&amp;gt;
      &amp;lt;/head&amp;gt;
      &amp;lt;body&amp;gt;
        &amp;lt;div id="root"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;htmlContent&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/div&amp;gt;
        &amp;lt;script&amp;gt;window.__SSR_DATA__ = &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialData&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/script&amp;gt;
      &amp;lt;/body&amp;gt;
    &amp;lt;/html&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;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;initialData&lt;/code&gt; - added &lt;code&gt;initialData&lt;/code&gt; as an argument to the function&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; - inside this script tag, we set a new property to &lt;code&gt;window&lt;/code&gt; object - &lt;code&gt;__SSR_DATA__&lt;/code&gt; that will be available globally inside the app. &lt;code&gt;initialData&lt;/code&gt; has to be stringified in order to be transferred across the network.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, when the Client Application is loaded in the &lt;code&gt;root&lt;/code&gt; of our HTML, it can access the &lt;code&gt;initialData&lt;/code&gt; and use it in order to hydrate the component!&lt;/p&gt;

&lt;p&gt;And add &lt;code&gt;initialData.props&lt;/code&gt; to the &lt;code&gt;document&lt;/code&gt; function inside route handler:&lt;/p&gt;

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

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;notNextServerSideProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fetch&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;htmlContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;renderToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HomePage&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;initialData&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="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;document&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;htmlContent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initialData&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;html&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;h4&gt;
  
  
  Adding &lt;code&gt;initialData&lt;/code&gt; to HomePage Component
&lt;/h4&gt;

&lt;p&gt;Since the data is available in the &lt;code&gt;window&lt;/code&gt; object, we can easily access it from the Client Application.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;app.jsx&lt;/code&gt; and add the following:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="cm"&gt;/* imports */&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__SSR_DATA__&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;domNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&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;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;hydrateRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;domNode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HomePage&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;initialProps&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;

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

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;getting &lt;code&gt;initialProps&lt;/code&gt; from the &lt;code&gt;window&lt;/code&gt; object&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;passing &lt;code&gt;initialProps&lt;/code&gt; as &lt;code&gt;HomePage&lt;/code&gt; props&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, when React will hydrate the component on the Client Side, it will have access to the same exact data as the Server and the contents will match.&lt;/p&gt;

&lt;h3&gt;
  
  
  Running Client Application
&lt;/h3&gt;

&lt;p&gt;Our latest challenge is to run a Client Application because so far, we are only rendering HTML on the server and sending it to the browser, but we don't really run React app in the browser.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Remember I said "no more Webpack"? I LIED.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First of all, we need to transpile our React code into browser-readable code using Babel and Webpack, so all imports are bundled together.&lt;/p&gt;

&lt;p&gt;Inside your &lt;code&gt;webpack.config.js&lt;/code&gt; paste the following before or after the server-side config:&lt;/p&gt;

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

&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app/app.jsx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Entry point for your client-side code&lt;/span&gt;
    &lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dist&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nx"&gt;publicPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/static/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// Important for dynamic imports to know where to fetch bundles&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;rules&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="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.(&lt;/span&gt;&lt;span class="sr"&gt;js|jsx&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;exclude&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/node_modules/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;babel-loader&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="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.jsx&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;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;development&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;Again, no magic here, just simple "where grab the file" and "where to put this file".&lt;/p&gt;

&lt;p&gt;Once this is done, Webpack will transpile and bundle &lt;code&gt;app.jsx&lt;/code&gt; to &lt;code&gt;app.js&lt;/code&gt; and keep it in the &lt;code&gt;dist&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;Now, we need to actually make our HTML request for the Client Application aka &lt;code&gt;app.js&lt;/code&gt;. Express.js provides us with a simple middleware to set up a static folder, from where HTML can request files. Let's do that.&lt;/p&gt;

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

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/static&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;static&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;span class="c1"&gt;// THIS CODE SHOULD BE BEFORE app.get&lt;/span&gt;

&lt;span class="c1"&gt;// app.get('/', async (req, res) =&amp;gt; {&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Since the output file (after transpile and bundling) will be located inside &lt;code&gt;dist&lt;/code&gt; folder (&lt;code&gt;dist/server.js&lt;/code&gt;), we set &lt;code&gt;static&lt;/code&gt; middleware to point to the same directory.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;don't forget to import path 😉 (yes I forgot again)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, when HTML requests for static content (JS, CSS, images) it will be able to call &lt;code&gt;/static&lt;/code&gt; route and get what it needs.&lt;/p&gt;

&lt;p&gt;The very last step is to add &lt;code&gt;app.js&lt;/code&gt; to the HTML. Open your &lt;code&gt;document.js&lt;/code&gt; and add the following after the &lt;code&gt;initialData&lt;/code&gt; script tag.&lt;/p&gt;

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

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/static/app.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;

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

&lt;/div&gt;

&lt;p&gt;Everything is ready! Let's try it out!&lt;/p&gt;

&lt;p&gt;build -&amp;gt; start -&amp;gt; &lt;code&gt;localhost:3000&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhaoj1jafrd9udn7rx74t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhaoj1jafrd9udn7rx74t.png" alt="Product list page with React hydration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everything looks the same as before...But, there are no errors and it means that everything worked! Test time!&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing SSR React Application
&lt;/h2&gt;

&lt;p&gt;Let's make a simple test!&lt;/p&gt;

&lt;p&gt;We will create a counter on top of the page and for every product card add a button that &lt;code&gt;onClick&lt;/code&gt; will console log product name.&lt;/p&gt;

&lt;p&gt;Go back to &lt;code&gt;app/pages/index.jsx&lt;/code&gt; and replace &lt;code&gt;HomePage&lt;/code&gt; component:&lt;/p&gt;

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

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HomePage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;products&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;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&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;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&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="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Increment&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;8px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;flexWrap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wrap&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;
            &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
              &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;flexDirection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;column&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;200px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1px solid black&lt;/span&gt;&lt;span class="dl"&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&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;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&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;console&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="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&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;Console&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;))}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&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;Don't forget to import &lt;code&gt;useState&lt;/code&gt; 😅&lt;/p&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="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="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&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;Okay! Fingers crossed!&lt;/p&gt;

&lt;p&gt;build -&amp;gt; start -&amp;gt; &lt;code&gt;localhost:3000&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjr4cskcfyqd0x8pyt9x4.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjr4cskcfyqd0x8pyt9x4.gif" alt="Gif showing the completed application"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;BOOM! 💥&lt;/p&gt;

&lt;p&gt;We have created a very simple, but working React Application with &lt;em&gt;Server Side Rendering&lt;/em&gt;!&lt;/p&gt;

&lt;p&gt;Almost as good as Next.js itself 😁 Gret job!&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;No conclusions 😁&lt;/p&gt;

&lt;p&gt;You've done a great job coming so far! Round of applause for you!&lt;/p&gt;

&lt;p&gt;We dug a bit deeper into the hows of Next.js and next time, we will go deeper or broader. How about we dive deep into how App Router works under the hood? 👀&lt;/p&gt;

&lt;p&gt;Ask your questions below if you have any and please share this article with those who have doubts on Next.js SSR.&lt;/p&gt;

&lt;p&gt;Find me on X 👋&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1693037630890406064-339" src="https://platform.twitter.com/embed/Tweet.html?id=1693037630890406064"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1693037630890406064-339');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1693037630890406064&amp;amp;theme=dark"
  }



&lt;/p&gt;

</description>
    </item>
    <item>
      <title>A Step-by-Step Guide to Deploying Vue Storefront Application on the DigitalOcean App Platform</title>
      <dc:creator>Sergii Kirianov</dc:creator>
      <pubDate>Fri, 24 Feb 2023 10:57:34 +0000</pubDate>
      <link>https://forem.com/skirianov/a-step-by-step-guide-to-deploying-vue-storefront-application-on-the-digitalocean-app-platform-3ol4</link>
      <guid>https://forem.com/skirianov/a-step-by-step-guide-to-deploying-vue-storefront-application-on-the-digitalocean-app-platform-3ol4</guid>
      <description>&lt;p&gt;Building an application is a complex process, however, this is only half of the work that has to be done. Once the application is built, it must be deployed, so that the world can visit your new online shop. This is a critical step and, in this article, we will focus on the technical aspects of deploying Vue Storefront on DigitalOcean.&lt;/p&gt;

&lt;p&gt;This guide is intended for developers who are familiar with both Vue Storefront and DigitalOcean and are looking for a step-by-step guide to setting up the eCommerce application on the cloud-based hosting service. By the end of this article, you will have a fully functioning Vue Storefront instance hosted on DigitalOcean.&lt;/p&gt;

&lt;p&gt;So, if you're ready to dive into the world of cloud deployment, grab your favorite text editor and let's get started!&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;For this article, we assume that you already have hosted a Magento 2 instance and your Vue Storefront application is fully connected to the Magento 2 platform.&lt;/p&gt;

&lt;p&gt;You’ll need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Account with &lt;a href="https://www.digitalocean.com/"&gt;DigitalOcean&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GitHub repository with Vue Storefront application source code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Environment variables for the Vue Storefront application&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A bit of patience 🙂&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you have all of the above, let’s start with creating a DigitalOcean application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating DigitalOcean application
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 1: Create a DigitalOcean App&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To create a DigitalOcean app, go to the sidebar and click "&lt;strong&gt;Apps&lt;/strong&gt;". DigitalOcean's application platform allows you to set up a CI/CD from your source code and redeploy it on every new commit to the branch of your choice. In this article, we will be using GitHub to store our Vue Storefront application.&lt;/p&gt;

&lt;p&gt;Click on the "&lt;strong&gt;Create App&lt;/strong&gt;" button and let's configure our repository. You will be prompted to choose the service provider, repository, branch, source directory, and “&lt;strong&gt;Autodeploy”&lt;/strong&gt; if needed. We have opted for auto-deploy so that every time our branch updates, it will trigger a redeploy. Click "&lt;strong&gt;Next&lt;/strong&gt;" to continue with the setup.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4Tgrxtpw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.contentstack.io/v3/assets/blt189c1df68c6b48d7/blt3c3936419dabd8b7/63ece3eaebf0774eed52ddc6/creating-digitalocean-application.png%3Fwidth%3D768%26auto%3Dwebp%26format%3Dpjpg%26disable%3Dupscale%26quality%3D100%26dpr%3D2%2520align%3D%2522left%2522" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4Tgrxtpw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.contentstack.io/v3/assets/blt189c1df68c6b48d7/blt3c3936419dabd8b7/63ece3eaebf0774eed52ddc6/creating-digitalocean-application.png%3Fwidth%3D768%26auto%3Dwebp%26format%3Dpjpg%26disable%3Dupscale%26quality%3D100%26dpr%3D2%2520align%3D%2522left%2522" alt="creating-digitalocean-application.png" width="768" height="708"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 2: Allocate Resources&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;On the &lt;strong&gt;Resources&lt;/strong&gt; page make sure you check the &lt;strong&gt;Edit Plan&lt;/strong&gt; button, you may be charged additionally in case DigitalOcean decided to spin up multiple containers. Set the containers to &lt;strong&gt;1&lt;/strong&gt; or anything that is suitable to your needs. Click “&lt;strong&gt;Next”&lt;/strong&gt; to continue.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NOkLZgma--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.contentstack.io/v3/assets/blt189c1df68c6b48d7/bltf24dbee8157c0938/63ece3ea723591743bc4d85c/allocating-resources-digitalocean.png%3Fwidth%3D768%26auto%3Dwebp%26format%3Dpjpg%26disable%3Dupscale%26quality%3D100%26dpr%3D2%2520align%3D%2522left%2522" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NOkLZgma--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.contentstack.io/v3/assets/blt189c1df68c6b48d7/bltf24dbee8157c0938/63ece3ea723591743bc4d85c/allocating-resources-digitalocean.png%3Fwidth%3D768%26auto%3Dwebp%26format%3Dpjpg%26disable%3Dupscale%26quality%3D100%26dpr%3D2%2520align%3D%2522left%2522" alt="allocating-resources-digitalocean.png" width="768" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3. Setup Environment Variables
&lt;/h3&gt;

&lt;p&gt;In this step, you can provide the &lt;strong&gt;Environment Variables&lt;/strong&gt; - open the &lt;code&gt;.env&lt;/code&gt; file you are using for your locally running application and paste it here - don’t worry, we will be able to change it later on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IMPORTANT:&lt;/strong&gt; To deploy successfully on the DigitalOcean App Platform you have to change the values of your environmental variables. Please follow the guide below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;VSF_NUXT_APP_ENV=production&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VSF_NUXT_APP_PORT=8080&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VSF_NUXT_APP_HOST=0.0.0.0&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VSF_STORE_URL=&lt;a href="https://0.0.0.0:8080"&gt;https://0.0.0.0:8080&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--V_Uo-aE9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.contentstack.io/v3/assets/blt189c1df68c6b48d7/blt363591c5220eea7a/63ece3ebc7306d1b0f973251/setup-environment-variables-digitalocean.png%3Fwidth%3D768%26auto%3Dwebp%26format%3Dpjpg%26disable%3Dupscale%26quality%3D100%26dpr%3D2%2520align%3D%2522left%2522" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V_Uo-aE9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.contentstack.io/v3/assets/blt189c1df68c6b48d7/blt363591c5220eea7a/63ece3ebc7306d1b0f973251/setup-environment-variables-digitalocean.png%3Fwidth%3D768%26auto%3Dwebp%26format%3Dpjpg%26disable%3Dupscale%26quality%3D100%26dpr%3D2%2520align%3D%2522left%2522" alt="setup-environment-variables-digitalocean.png" width="768" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4. Review the configuration information
&lt;/h3&gt;

&lt;p&gt;Click through the next steps and review all the information you have provided, when done, click “&lt;strong&gt;Create Resources”&lt;/strong&gt; - you will be redirected to the application dashboard. Let’s wait while our application is building.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8ZXM87_q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.contentstack.io/v3/assets/blt189c1df68c6b48d7/bltbcc9ba8f8abd5f46/63ece3eaec2e7d124d31c347/reviewing-configuration-information-digitalocean.png%3Fwidth%3D768%26auto%3Dwebp%26format%3Dpjpg%26disable%3Dupscale%26quality%3D100%26dpr%3D2%2520align%3D%2522left%2522" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8ZXM87_q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.contentstack.io/v3/assets/blt189c1df68c6b48d7/bltbcc9ba8f8abd5f46/63ece3eaec2e7d124d31c347/reviewing-configuration-information-digitalocean.png%3Fwidth%3D768%26auto%3Dwebp%26format%3Dpjpg%26disable%3Dupscale%26quality%3D100%26dpr%3D2%2520align%3D%2522left%2522" alt="reviewing-configuration-information-digitalocean.png" width="768" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you first build your application, you will get your &lt;strong&gt;Live&lt;/strong&gt; URL, if you visit it you will see an error in your console and network tab, this is because DigitalOcean will try to run API middleware on an &lt;strong&gt;HTTP&lt;/strong&gt; host we can’t access due to the &lt;strong&gt;Mixed Content&lt;/strong&gt; policy. To fix that, we will need to make another adjustment to our &lt;strong&gt;Environment Variables&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure Environment Variables
&lt;/h2&gt;

&lt;p&gt;In your &lt;strong&gt;App Dashboard&lt;/strong&gt; go to the &lt;strong&gt;Setting&lt;/strong&gt; and click on &lt;strong&gt;Components:&lt;/strong&gt; &lt;code&gt;&amp;lt;&amp;lt;PROJECT_NAME&amp;gt;&amp;gt;&lt;/code&gt; - in our case it’s &lt;code&gt;vsf-deploy-article&lt;/code&gt;. Find the &lt;strong&gt;Environment Variables&lt;/strong&gt; menu and click &lt;strong&gt;Edit&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--42AC5AZS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.contentstack.io/v3/assets/blt189c1df68c6b48d7/bltbc6b4b53ed1c4a2c/63ece3ea2b5f1f5b059f126c/configure-environment-variables-digitalocean.png%3Fwidth%3D768%26auto%3Dwebp%26format%3Dpjpg%26disable%3Dupscale%26quality%3D100%26dpr%3D2%2520align%3D%2522left%2522" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--42AC5AZS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.contentstack.io/v3/assets/blt189c1df68c6b48d7/bltbc6b4b53ed1c4a2c/63ece3ea2b5f1f5b059f126c/configure-environment-variables-digitalocean.png%3Fwidth%3D768%26auto%3Dwebp%26format%3Dpjpg%26disable%3Dupscale%26quality%3D100%26dpr%3D2%2520align%3D%2522left%2522" alt="configure-environment-variables-digitalocean.png" width="768" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Change the following variables with the URL of your &lt;strong&gt;Live&lt;/strong&gt; website with the &lt;strong&gt;API&lt;/strong&gt; route.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;API_BASE_URL - &lt;code&gt;&amp;lt;&amp;lt;YOUR_APP_LIVE_URL&amp;gt;&amp;gt;/api&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API_SSR_BASE_URL - &lt;code&gt;&amp;lt;&amp;lt;YOUR_APP_LIVE_URL&amp;gt;&amp;gt;/api&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Save your changes. This will trigger redeployment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--c7lY6ABe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.contentstack.io/v3/assets/blt189c1df68c6b48d7/blt9965c47475637d0c/63ece3eb8144df106174ba6c/digitalocean-deployment-status.png%3Fwidth%3D768%26auto%3Dwebp%26format%3Dpjpg%26disable%3Dupscale%26quality%3D100%26dpr%3D2%2520align%3D%2522left%2522" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--c7lY6ABe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.contentstack.io/v3/assets/blt189c1df68c6b48d7/blt9965c47475637d0c/63ece3eb8144df106174ba6c/digitalocean-deployment-status.png%3Fwidth%3D768%26auto%3Dwebp%26format%3Dpjpg%26disable%3Dupscale%26quality%3D100%26dpr%3D2%2520align%3D%2522left%2522" alt="digitalocean-deployment-status.png" width="768" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the build and deploy step is completed, you will get a notification that everything is OK and healthy. Now you can visit your &lt;strong&gt;Live&lt;/strong&gt; URL. Let’s do that.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--h7tLGgZL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.contentstack.io/v3/assets/blt189c1df68c6b48d7/bltd6cb10ee13c6d3bf/63ece3eb0773755832f89e79/digitalocean-live-url-review.png%3Fwidth%3D768%26auto%3Dwebp%26format%3Dpjpg%26disable%3Dupscale%26quality%3D100%26dpr%3D2%2520align%3D%2522left%2522" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h7tLGgZL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.contentstack.io/v3/assets/blt189c1df68c6b48d7/bltd6cb10ee13c6d3bf/63ece3eb0773755832f89e79/digitalocean-live-url-review.png%3Fwidth%3D768%26auto%3Dwebp%26format%3Dpjpg%26disable%3Dupscale%26quality%3D100%26dpr%3D2%2520align%3D%2522left%2522" alt="digitalocean-live-url-review.png" width="768" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Our Vue Storefront application is up and running! Congratulations! 🥳&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;It was pretty easy! We have deployed our Vue Storefront application fast and effortlessly thanks to the capabilities of the DigitalOcean App Platform. Now your store is available for everyone in the world! Of course, this is not the end of the journey and you will need to set up a proper domain name too, but this is pretty and you can check it in the DigitalOcean documentation - &lt;a href="https://docs.digitalocean.com/products/app-platform/how-to/manage-domains/"&gt;How to Manage Domains in App Platform&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Even though this method is very simple and straightforward it is not the best solution for a large enterprise application- but, luckily, Vue Storefront has got you covered! &lt;a href="https://vuestorefront.io/cloud"&gt;Vue Storefront Cloud&lt;/a&gt; provides the solution for Enterprise clients to cover all your hosting needs (also reach out to me if you’d like an introduction to the right person to guide you with that).&lt;/p&gt;

&lt;p&gt;Feel free to contact us on our &lt;a href="https://discord.com/invite/vuestorefront"&gt;Discord server&lt;/a&gt; for any matter if you have questions about manual deployment with Ubuntu droplet or other Vue Storefront-related questions.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Find your first job as Junior Developer</title>
      <dc:creator>Sergii Kirianov</dc:creator>
      <pubDate>Mon, 20 Jun 2022 22:43:35 +0000</pubDate>
      <link>https://forem.com/skirianov/find-your-first-job-as-junior-developer-38kb</link>
      <guid>https://forem.com/skirianov/find-your-first-job-as-junior-developer-38kb</guid>
      <description>&lt;p&gt;&lt;strong&gt;You were working hard, congratulations!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You've studied long hours, fight scary bugs and weird terminology, and built some cool and not-so-cool projects. &lt;strong&gt;You are here.&lt;/strong&gt; You are ready to start searching for a job, aren't you? &lt;/p&gt;

&lt;p&gt;Well, most probably the ones, who are about to search for their very first job, are never ready enough for it. Feels like diving from a high platform in a swimming pool. You are hesitant and think you are not prepared enough or not good enough. You can climb down of course, but at my University swimming pool, the platform stairs were so bad, that it was actually even scarier to climb down. For many, it may resemble a fear of dropping everything they've gone through to learn to code. It's fear of being a failure. Though, I don't think you are a failure even if you have decided to drop it.** You're definitely not a failure! **&lt;/p&gt;

&lt;p&gt;So, what to do now? You are afraid to jump and you don't want to drop all you have succeeded till now. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Jump.&lt;/strong&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The fun fact is, the chances that it will be way easier next time are &lt;strong&gt;very&lt;/strong&gt; high. But, normally people don't just go to the highest platform and jump immediately, right? First, they prepare for it by jumping from the smallest platform, then - a bit higher, higher, and finally, they are ready for the last one. &lt;/p&gt;

&lt;p&gt;Below, we will go through different techniques that will help you to nail the job search and finally get a job. Let's go from the very first and the lowest platform and slowly reach the highest in order to finally conquer it.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.5 m platform - Get your papers ready
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;In its 2018 Eye-Tracking Study, Ladders Inc. revealed that the time recruiters spend on the initial screen of a resume is up from an average of only six seconds in 2012, but only by about a second. Today’s recruiters skim resumes for an average of 7.4 seconds.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's assume that you already have a decent portfolio of projects that you can showcase to the companies to prove your skills. There are myriads of articles on what projects are good for the first try, but in case you want me to give you a list of cool projects to build for your portfolio, please leave a comment below 😉&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1534252903585792004-508" src="https://platform.twitter.com/embed/Tweet.html?id=1534252903585792004"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1534252903585792004-508');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1534252903585792004&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;When I say portfolio, I don't say that you &lt;strong&gt;must&lt;/strong&gt; have a portfolio &lt;strong&gt;website&lt;/strong&gt;. It may be useful, though it can be harmful too. It depends a lot on your specialization and skills. I would recommend you read this article that might help you to decide - &lt;a href="https://dev.to/jkettmann/don-t-waste-your-time-on-a-portfolio-website-314b"&gt;Don't waste your time on a portfolio website&lt;/a&gt;. Or, you can also check the replies in the tweet above, there are some great advice and opinions. &lt;/p&gt;

&lt;p&gt;By portfolio, I mean anything that can prove your work, whether these are live websites, GitHub repositories, or even blog posts. Anything that can show your skills, knowledge, and passion.&lt;/p&gt;

&lt;p&gt;What we will focus on, this time, is &lt;strong&gt;resume&lt;/strong&gt; and &lt;strong&gt;cover letters&lt;/strong&gt;. Yes, not every single company requires you to have a cover letter, but having one will definitely help, once you will get to an application spree. &lt;/p&gt;

&lt;p&gt;My favorite "go-to" cheatsheet for both of them is &lt;a href="https://ocs.fas.harvard.edu/files/ocs/files/undergrad_resumes_and_cover_letters.pdf?m=1598037165"&gt;Harvard - OCS RESUMES &amp;amp; COVER LETTERS&lt;/a&gt;. It has an amazing list of keywords that will make your resume professional. Examples of resumes and cover letters. Just trust me, it's only 10 pages, give it a read and most probably it will deserve a space on your hard drive (or SSD if you're rich 😏).&lt;/p&gt;

&lt;h3&gt;
  
  
  My personal recommendations about your resume:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Keep it short - one-page resumes are best. If you can structure information in an accessible and readable way for quick glance check - great!&lt;/li&gt;
&lt;li&gt;Make recruiter life easier - do not list all technologies you have ever touched. Highlight technologies that are applicable to a current job you're applying to and keep others aside / remove them.&lt;/li&gt;
&lt;li&gt;Keep it formal - yes, we live in a modern unicorn world full of colors and free template resume designs. Trust me, however deep you'll search for a resume template, the chances that somebody has used it already are extremely high. And just somebody but many somebodies. Make a clear black-on-white resume. &lt;/li&gt;
&lt;li&gt;Once again, structure information - if your resume is in English (most probably it is) - the person who will review your resume will for sure review it from top to bottom left to right.&lt;/li&gt;
&lt;li&gt;Make it flexible - you've heard about targeted marketing, right? It's a good idea to align your resume for a position you're applying for. Especially, in case you're well versed in different programming languages.&lt;/li&gt;
&lt;li&gt;This is a &lt;strong&gt;LIVE&lt;/strong&gt; document - don't forget to update your resume even if you found a job already. Add as many points as you can while you're learning or getting experience, it will help you to find the most important topics later on.&lt;/li&gt;
&lt;li&gt;Evaluate yourself - either it's a community review, or you want to run your resume through an ATS scanner. Do it. You'll learn a lot about how good your resume is. There are multiple ways to do it: ask people on Twitter (as I did, see thread below), ask Redditors in subreddit like &lt;a href="https://www.reddit.com/r/learnjavascript/"&gt;r/learnjavascript&lt;/a&gt;, &lt;a href="https://www.reddit.com/r/learnpython/"&gt;r/learnpython&lt;/a&gt; and many others, or find an ATS service that provides you &lt;strong&gt;FREE&lt;/strong&gt; trial to check your resume.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the other options can use services that will create a professional resume for you and they charge from 20-40$. As for me, this is the last resort, but we are all differently tailored, so it may be best for you.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1454562595701202956-121" src="https://platform.twitter.com/embed/Tweet.html?id=1454562595701202956"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1454562595701202956-121');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1454562595701202956&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;My resume review request is on Twitter. Check the comments, there is some really good advice.&lt;/p&gt;

&lt;p&gt;Resources to consider: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.freecodecamp.org/news/how-to-write-a-great-resume-for-software-engineers-75d514dd8322/"&gt;How to write a great resume for software engineers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.freecodecamp.org/news/writing-a-killer-software-engineering-resume-b11c91ef699d/"&gt;How to write a killer Software Engineering résumé&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cover Letters
&lt;/h3&gt;

&lt;p&gt;Cover letters - I really hate them. While I can easily write an article for 2+ thousand words, I barely can write a great Cover Letter. Luckily, there are people like @&lt;a href="https://dev.to@jrdev_"&gt;Ali&lt;/a&gt; and their articles that will help you to get better at Cover Letters than me - &lt;a href="https://jrdev.hashnode.dev/how-to-write-a-cover-letter-to-land-your-first-dev-job-ckdcwqr6p048g66s1cylp0950"&gt;How to Write a Cover Letter to Land Your First Dev Job&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To add a few points from me, please make sure that your Cover Letter is aligned for nearly every job if they have different requirements. Be aware, that some job postings include hidden "keywords" that you must include in your CV, otherwise it won't pass the screening by AI.  Don't forget, this all is a game and you need to play by the rules and be good at it, especially for your very first role.&lt;/p&gt;

&lt;p&gt;Quite a short part, ha? 😬&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jump&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your first platform is behind you, you submerged into the water in a matter of a fraction of a second, but the emotions were great! You want more, now you want a higher platform!&lt;/p&gt;

&lt;h2&gt;
  
  
  3.0 m - Polishing your projects
&lt;/h2&gt;

&lt;p&gt;Imagine you are about to climb on the next platform, but after the previous collision with water, your swimsuit is torn. Most probably you don't want to get to the highest platform to jump with your ass shown to everyone around, right? Well, maybe you want, but I believe not. So, make sure your swimsuit is intact before going anywhere up.&lt;/p&gt;

&lt;p&gt;It's quite often while building projects solo, we may overlook something here and there. It's quite often too, that some jobs require you to know let's say testing, but you have never done it. You don't want to be an appropriate candidate for this job just because of something simple like tests. Go to one of your latest projects and cover at least some part of it with tests, this will increase your chances to get a job drastically! By the way, if you're a web dev and have never tried testing, here's my latest article on the intro to Jest, have a look - &lt;a href="https://codecryrepeat.hashnode.dev/beginners-guide-your-first-test"&gt;Beginner's guide: Your first test&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You need to make sure that your projects are shining. Well, none of the projects in the world are actually shining, but at least you need to clean up the mess you've made. Top things I've noticed while reviewing some of the beginner's projects: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub repository README.md file is not updated - make sure you remove default generated README files and add some documentation to your project. This includes: how to run the project, if the project is deployed - add the link to live view, list technologies used in the project, describe the purpose of the project and what is it doing, list the hardest part of the project, list what issues you had during development and how did you solve them (don't just say "I Googled them").&lt;/li&gt;
&lt;li&gt;Clean up any unnecessary system outputs - remove not required "console.logs", "prints", "system.out.printlns" and so on. Your project must be production-ready &lt;strong&gt;OR&lt;/strong&gt; at least mention in the repo that work is in progress.&lt;/li&gt;
&lt;li&gt;If you are Frontend developer - &lt;strong&gt;PLEASE&lt;/strong&gt; make sure your website is responsive enough. Ask your friends to run it, ask the community to run it and give feedback, do the lighthouse reports and check that your accessibility is good enough.&lt;/li&gt;
&lt;li&gt;Write tests - see two paragraphs above.&lt;/li&gt;
&lt;li&gt;Write comments - yes we know you've made this project and you know every single line. Oh, I mean you knew it two days back. Write comments saying why this function is here, not what this function does.&lt;/li&gt;
&lt;li&gt;Check your variables - make sure your variables have good and self-explanatory names.&lt;/li&gt;
&lt;li&gt;Split up your code - one single file of thousands of lines of code is not what people would expect to see unless this is on purpose. Extract your helper functions. Keep code clean. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  6.0 m - Visibility does not hurt
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;The easiest way to get noticed is to be visible&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I started writing a blog a few months before I even planned to start looking for a job. Currently, employers are becoming more and more demanding on what kind of developers they want to hire. You need to stand out from the crowd or at least be visible in it. Your writing is not only to get likes and comments, followers and haters. Your writing shows your potential employer that you are passionate about what you are doing. It shows that you've spent time outside of your coding life to share your knowledge and experience with others. Don't know what to write? Do you think you're too inexperienced to write technical posts? Well, we all were there. Write about your project. Create a dev journal and write how are you approaching and solving the problem of your project. What issues did you meet and how did you resolve them. Doing so you'll see, that more and more people are getting around. People with less and more experience. People who would like to help you or give you advice on how to avoid such problems in the future.&lt;/p&gt;

&lt;p&gt;And by saying writing, I don't necessarily mean "writing", any content creation would be great. Whether it's writing, video blogging, streaming, podcasts, etc. &lt;/p&gt;

&lt;p&gt;Another great option - engage with the community. There are many stereotypes about developers and techies in general, but you can forget about them. I have met many people online and in-person and they are awesome. Ask the community for help, it's not bad to ask. Ask some more experienced dev to take a look at your project, get their feedback, and apply changes (just don't lose personality in your projects). Make a group of people who are searching for jobs too and help each other on the way. Try to make a mock interview and ask each other the most popular interview questions.&lt;/p&gt;

&lt;p&gt;LinkedIn - this is a whole game, there are tons of resources about it, and even the ones from LinkedIn itself are great. Read them and make your profile shiny.&lt;/p&gt;

&lt;p&gt;I must admit though, that this is not everyone's path. Some people are more open and social, and they actually want to share this, some are not. This whole 6m platform is already high enough to be skipped and go for the highest one.&lt;/p&gt;

&lt;h2&gt;
  
  
  10 m - Highest One - Job search
&lt;/h2&gt;

&lt;p&gt;You set your foot on the last step, you're trembling and still hesitant. You are ready, but no one is ready till they jump. You have passed all the platforms below and you know what to expect. So now, only the last step ahead is remaining. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jump&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You have everything ready. If you can afford it, your job search should become your full-time job, if you're time-constrained, at least try to dedicate a few hours a day. Even one hour a day would be good, to be honest. &lt;/p&gt;

&lt;p&gt;There are tons of resources to prepare for the interviews and we are not going to cover them here. Those are made by professionals and I am not in a position to tell you something better. Just Google for those resources 😉&lt;/p&gt;

&lt;p&gt;But what I can say - &lt;strong&gt;let's get to the grind&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I am completely self-taught, spent 0 dollars to learn, and got a job after two weeks since I started my search. At least I can share with you what I've done.&lt;/p&gt;

&lt;p&gt;I won't share the websites I was looking for a job at. Why? Because it's pointless. Day after day, after day I was searching Google, Yahoo, DuckDuckGo, and Bing even for keywords: "junior developer", "junior web developer", "junior web remote", and "junior remote software", "junior frontend", etc. Every day, from 8 AM to 6 PM. I went even on 4th !!!! page of Google search results. &lt;/p&gt;

&lt;p&gt;Yeah, I was playing a game on hardcore, trying to find my very first programming job remotely. But I did it, so can you!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You are ready for it and you can apply to jobs that have a degree as requirement. You are ready and you can apply to jobs that even have 3+ years of experience as a requirement. And yes, you can apply to jobs if you're not fully matching the requirements.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Try any job board available where you see even part of the stack you work on. Honestly, I was not applying for a job with the stack I have no idea about at all, but I've heard that for someone that worked out 🤷🏼‍♂️&lt;/p&gt;

&lt;p&gt;What I'm saying is - &lt;strong&gt;jump&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  rejections
&lt;/h3&gt;

&lt;p&gt;Don't get too disappointed to get rejections. We all are getting them. Even people with 10 years of experience are getting rejections at times. The reasons for that are nearly infinite, so don't even bother to worry. BUT. Make sure that after a certain amount of rejections you re-evaluate your resume and CV, because it may be the problem. &lt;/p&gt;

&lt;h2&gt;
  
  
  In the water
&lt;/h2&gt;

&lt;p&gt;After all the tension you finally fly down into the water. Submerged. Excited. The fear is still present, but it's somewhere down in the emotions call stack. Right now you've made that step and from now on every next step will be easier. Looking for jobs won't be as scary as before. It will just become, well, a necessity or desire to get to a better place. Most importantly you've done it and you are searching for a job. Congratulations! &lt;/p&gt;

&lt;p&gt;If you liked this article, please share it with your friends it will be a pleasure for me if this article will help anyone, even a single person. Also, if you want to have a chat or maybe set up a mock interview, you can find me on Twitter &lt;a href="https://twitter.com/SergiiKirianov"&gt;@SergiiKirianov&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Thanks a lot for reading and see you soon☺️&lt;/p&gt;

</description>
      <category>career</category>
      <category>beginners</category>
      <category>resume</category>
      <category>programming</category>
    </item>
    <item>
      <title>Beginner's guide: Your first test</title>
      <dc:creator>Sergii Kirianov</dc:creator>
      <pubDate>Sun, 05 Jun 2022 15:50:51 +0000</pubDate>
      <link>https://forem.com/skirianov/beginners-guide-your-first-test-2pda</link>
      <guid>https://forem.com/skirianov/beginners-guide-your-first-test-2pda</guid>
      <description>&lt;h2&gt;
  
  
  We always hear a lot about testing
&lt;/h2&gt;

&lt;p&gt;We always hear a lot about testing. It's literally everywhere and many of us have no idea how to start, what tests to write, and what's the point of tests? &lt;/p&gt;

&lt;p&gt;I'll try to give you a very basic introduction that will be easy to understand. We will use JavaScript and Jest Testing Framework. But first, let's start with very very basic stuff.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do we need tests?
&lt;/h2&gt;

&lt;p&gt;Because.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--77TVYF-Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://c.tenor.com/ei8s117ZieIAAAAC/ugh-rolling-eyes.gif%2520align%3D%2522center%2522" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--77TVYF-Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://c.tenor.com/ei8s117ZieIAAAAC/ugh-rolling-eyes.gif%2520align%3D%2522center%2522" alt="rolling eyes gif" width="498" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But if we talk seriously there are a lot of reasons for that, let's take a look at some:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You ensure your code is doing what it is supposed to do&lt;/li&gt;
&lt;li&gt;You ensure that the app behaves as expected&lt;/li&gt;
&lt;li&gt;You ensure people don't hate you&lt;/li&gt;
&lt;li&gt;You prevent bugs creeping in&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So that's fine, we all more or less understand that. Testing is something being done in any industry and this is in fact the standard. You can't neglect testing after a repair, manufacturing, or anything that may endanger somebody or destroy the user experience. Though it's heavily neglected with the beginners.&lt;/p&gt;

&lt;p&gt;You may wonder - "I'm a beginner, why should I learn testing?". The answer is simple, many companies that are about to hire you, want you to understand the testing and at least have some minimal experience with it. If you cover your portfolio project with &lt;strong&gt;some&lt;/strong&gt; unit testing - you're 100 steps away from your competitors. &lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hdWbynK9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://c.tenor.com/FPa-y4oDJGcAAAAC/i-dont-understand-this-terminology-i-dont-understand-these-words.gif%2520align%3D%2522center%2522" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hdWbynK9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://c.tenor.com/FPa-y4oDJGcAAAAC/i-dont-understand-this-terminology-i-dont-understand-these-words.gif%2520align%3D%2522center%2522" alt="I don't understand these words" width="498" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I'll make sure you understand.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before we start, let's understand a few terms, nothing ultra-serious, but this will help you to understand a bit what are we even talking about.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Unit testing - "is a software development process in which the smallest testable parts of an application, called units, are individually and independently scrutinized for proper operation." - in simple words, we are testing functions. We must test that function &lt;strong&gt;ALWAYS&lt;/strong&gt; returns what we are expecting it to return.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Integration testing - "is a type of testing where software modules are integrated logically and tested as a group" - here you are testing different group components of the app to see that they work well together. Think of "if this is sent to the backend, this is what has to be received and displayed".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;End-to-end testing - "is a methodology used in the software development lifecycle (SDLC) to test the functionality and performance of an application under product-like circumstances and data to replicate live settings. The goal is to simulate what a real user scenario looks like from start to finish". Quite self-descriptive, but to say it in human language - we are simulating user behavior. User visits this page - clicks this button - this modal opens - enters this data - submits - receives the result from BE. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  I told you, simple tests first - Unit testing
&lt;/h2&gt;

&lt;p&gt;Hope you're ready because this is going to be hard! &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OHg_C_zd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://c.tenor.com/wJ5ySDJdyEAAAAAd/ag-ag-hardcore.gif%2520align%3D%2522center%2522" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OHg_C_zd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://c.tenor.com/wJ5ySDJdyEAAAAAd/ag-ag-hardcore.gif%2520align%3D%2522center%2522" alt="hardcore gif" width="640" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nah, it won't. &lt;/p&gt;

&lt;p&gt;The good practice writing tests is following the TDD - Test Driven Development approach, but not in our case. Let's first understand how to write them, before going into complex details of the TDD approach.&lt;/p&gt;

&lt;p&gt;Okay, let's write our first function. This is the approach I use when I have to write a function, so follow along.&lt;/p&gt;

&lt;p&gt;**Task: **Write a function that takes a string of any size and creates an abbreviation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Input:&lt;/strong&gt; a string of any size&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Desired output:&lt;/strong&gt; an abbreviation consisting of concatenated capitalized first letters of each word in a string&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Input: "Advanced Business Application Programming" Output: "ABAP"&lt;/li&gt;
&lt;li&gt;Input: "Object Oriented Programming" Output: "OOP"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Knowing this information we can split the task into small and easy-to-understand pieces.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// input: string = "Object oriented programming"

const createAbbreviation = (string) =&amp;gt; {
  const arrayOfWords = string.split(' '); // ["Object", "oriented", "programming"]
  const arrayOfFirstLetters = arrayOfWords.map(word =&amp;gt; word[0]); // ["O", "o", "p"]
  const stringOfFirstLetts = arrayOfFirstLetters.join(''); // "Oop"
  const upperCasedAbbreviation = stringOfFirstLetts.toUpperCase(); // "OOP"

  return upperCasedAbbreviation;
}

// output: "OOP"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I think this function is simple enough, but if you want to be a bit "special", the following function is exactly the same.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const createAbbreviation = (string) =&amp;gt;
  string
    .split(' ')
    .map((word) =&amp;gt; word[0])
    .join('')
    .toUpperCase();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay, we have our function, we know what is it doing, so now we can think of a way to test it. &lt;br&gt;
Let's initiate a project and install Jest.&lt;/p&gt;

&lt;p&gt;Create a new folder and run &lt;code&gt;npm init&lt;/code&gt;, just span &lt;code&gt;Enter&lt;/code&gt;, we don't really care about our settings right now.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BXycdp8l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rsv6fn1ohjdlt41bkzn1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BXycdp8l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rsv6fn1ohjdlt41bkzn1.gif" alt="npm init terminal output" width="600" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's add Jest as a dev dependency. Open your VSCode and open the terminal. Once that is done, let's do the magic. Copy-paste this in your terminal and hit Enter: &lt;code&gt;yarn add --dev jest&lt;/code&gt;. Congratulations, Jest is installed. In case you have an issue, please consult the &lt;a href="https://jestjs.io/docs/getting-started"&gt;docs&lt;/a&gt;. Few changes have to be made in your &lt;code&gt;package.json&lt;/code&gt;, please go there and change the default test script command to this &lt;code&gt;"test": "jest"&lt;/code&gt;. Okay, you're all set, let's write that first test.&lt;/p&gt;

&lt;p&gt;Create a new file named &lt;code&gt;index.test.js&lt;/code&gt; - this is one of the default ways Jest can find test files. Usually, you don't write your functions inside test files, but we do it this way for the sake of simple configuration. Normally, you would have a dedicated file with functions and a separate file with tests. &lt;br&gt;
And let's get to the interesting part. &lt;/p&gt;

&lt;p&gt;Because of the way we thought of our function in the first place, we know what should be the input and what kind of output we should get. So let's do the same thing, but with JavaScript. Jest has its own syntax, so if you want to learn more - read &lt;a href="https://jestjs.io/docs/getting-started"&gt;docs&lt;/a&gt;. For now, we will use the most common syntax.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const createAbbreviation = (string) =&amp;gt; {
  const arrayOfWords = string.split(' ');
  const arrayOfFirstLetters = arrayOfWords.map(word =&amp;gt; word[0]);
  const stringOfFirstLetts = arrayOfFirstLetters.join('');
  const upperCasedAbbreviation = stringOfFirstLetts.toUpperCase();

  return upperCasedAbbreviation;
}

describe('Test createAbbreviation function', () =&amp;gt; {
  it('creates abbreviation', () =&amp;gt; {
    expect(createAbbreviation('European Union')).toEqual('EU');
    expect(createAbbreviation('Public Announcement')).toEqual('PA');
    expect(createAbbreviation('Very long name with more than five words')).toEqual('VLNWMTFW');
    expect(createAbbreviation('single')).toEqual('S');
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's go line by line and see what this code is doing 👇&lt;/p&gt;

&lt;p&gt;First, we create a test suite that defines the name of all tests inside it. A good practice is to have one single &lt;code&gt;describe&lt;/code&gt; in the test file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;describe('name of the test suite', tests_functions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then inside test suites, we are finally writing the actual tests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;it('name of the single test', single_test_function);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, remember what we were talking about previously, we need to make sure that every time the input we give to a function always returns the exact same result. So, we are &lt;strong&gt;expecting&lt;/strong&gt; the result of the function with example &lt;strong&gt;string&lt;/strong&gt; to &lt;strong&gt;be equal&lt;/strong&gt; to that &lt;strong&gt;output&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;expect(createAbbreviation('European Union)).toEqual('EU');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hooray! Our first test is done! Now, let's run it! Go back to your VSCode terminal and type &lt;code&gt;yarn jest&lt;/code&gt; to run the testing script and you should get something similar ❤️‍🔥&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fGLbInYr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6hrlspuf1oowqcek1ilh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fGLbInYr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6hrlspuf1oowqcek1ilh.png" alt="jest passed tests results" width="760" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  You're the boss
&lt;/h2&gt;

&lt;p&gt;As you see, testing is not that hard and it's pretty easy to start with. If you approach a function/task in a proper way understanding what should be the output, you already know how to write the test. Of course, our function is very primitive and it does not include many edge cases, but for the sake of understanding, it's good enough. &lt;/p&gt;

&lt;p&gt;If you're interested in E2E testing with Cypress you can check out my introduction article &lt;a href="https://codecryrepeat.hashnode.dev/end-to-end-testing-with-cypress"&gt;End-to-End testing with Cypress&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Thanks for your time and I hope this article opened up a door to the testing world for you. Even if just a bit ☺️&lt;/p&gt;

&lt;p&gt;You can contact me on Twitter &lt;a href="https://twitter.com/SergiiKirianov"&gt;@SergiiKirianov&lt;/a&gt; if you have some questions, or leave them below in the comment section &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>testing</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Tech Community is blind</title>
      <dc:creator>Sergii Kirianov</dc:creator>
      <pubDate>Sat, 28 May 2022 23:10:59 +0000</pubDate>
      <link>https://forem.com/skirianov/tech-community-is-blind-266n</link>
      <guid>https://forem.com/skirianov/tech-community-is-blind-266n</guid>
      <description>&lt;h2&gt;
  
  
  The Numbers
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Disclaimer: numbers are taken all over the world in general and some are from the US, UK, and EU since the data is mostly available for those regions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As per WHO there are more than 1 billion people in the world with visual impairment, more than 1 billion people with some form of disabilities, and between 110 to 190 million people aged 15 and older with significant difficulties in functioning. Those people are struggling in day-to-day life, because the environment we live in, though on the way to make life easier for them and more accessible, is still not ready. Bureau of Labor Statistics (US) has reported in 2021 that out of all people with disabilities only &lt;strong&gt;19.1 %&lt;/strong&gt; are employed.&lt;/p&gt;

&lt;p&gt;The numbers are bad, though not surprising at all. The daily commute to work is hard, availability and accessibility of public transportation need a lot of work to be done. So what would be the best solution for them? Well, I would say working remotely would be great, also becoming a developer would be really great! What can be done to attract more people with disabilities to the Tech industry? What can be done to make their developer experience seamless and accessible? What can be done to make Tech more Diverse and Inclusive? Let's find out what has been done so far and what has to be done still.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Spoiler: not much has been done and a LOT has to be done.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Accessibility
&lt;/h2&gt;

&lt;p&gt;Most of us are familiar with this topic, some are even evangelists and professionals advocating for accessibility. But have you ever thought of accessibility for developers? How can we call ourselves Diverse and Inclusive if we can't even help people to enter the same field we work in? Most talks about accessibility are aimed at user experience to cover more and more user groups and create an accessible environment for potential customers.&lt;/p&gt;

&lt;p&gt;The user-centric design and workflow are great, we do attract more users, more money, and more innovation. But we are being selfish. We don't think about our own potential colleagues. What hypocrisy, right?&lt;/p&gt;

&lt;p&gt;During one of the conferences in Brussels, I asked the speaker who had a talk about user accessibility what he thinks about accessibility for developers. Well, nobody could answer the question. I've seen the eyes of all people who looked at me when I asked the question and I saw no answer in them. I realized, looks like most developers never asked themselves this before...Sad.&lt;/p&gt;

&lt;p&gt;The biggest issue is that basically, it's extremely hard to find &lt;strong&gt;any&lt;/strong&gt; information on tools for developers with disabilities. The moment you Google anything, most of the results are tools to help you create accessible apps, but not accessibility tools for developers. &lt;/p&gt;

&lt;p&gt;Think about it. Even the learning content is so spoiled. Yes, there are lots of courses and guides on how to start, how to learn language X in Y time, and how to set up the project. There are a lot of text guides, but also there are guides that are videos...with code snippets that they show you on the screen...in the video.&lt;/p&gt;

&lt;p&gt;So is there anything?&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools and why they fail
&lt;/h2&gt;

&lt;p&gt;The most common tools for accessibility on an OS level: are a screen keyboard, voice-to-text, voice control, and a screenreader. &lt;/p&gt;

&lt;p&gt;I think it's quite obvious even without me explaining it, why those tools are basically useless for people with disabilities who want to start programming. But let me give you a few examples so you can feel all the pain.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Screen keyboard&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Needless to say that speed of development using the mouse as a single input would be terrible, especially how verbose the code can be and how much stuff we actually type, we barely think of it in terms of characters. After a short research, I have found out that an average programmer makes at least 10-15k keystrokes during a normal working day. This tool is basically one of the "soft" tools that can be used. It basically requires you to have &lt;strong&gt;at least&lt;/strong&gt; hand and the ability to see, which is not always the case.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Voice-to-text&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We all are in different conditions and for people who have limbs, it's extremely hard to imagine how to type / work / do your chores without hands. And now imagine that you have to write any function bigger than 10 lines of code by your voice, jump from line to line, manipulate cursor position, navigate between tabs/windows/ etc. Well, I doubt you can. It's extremely hard, I've tried, and trust me I couldn't do any of what I do during my normal daily workflow. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Voice control&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Should I tell you that if your English is not "clear" enough or if you don't speak in a particular way - no control for you...My English is pretty okayish, but hell no this thing will ever understand me. For more insights on voice control day-to-day life of a developer, you can check this article &lt;a href="https://betterprogramming.pub/what-software-development-looks-like-when-you-have-a-partial-disability-f94d791e4102"&gt;What Software Development Looks Like When You Have a Partial Disability&lt;/a&gt;. Keep in mind, &lt;strong&gt;this&lt;/strong&gt; is a partial disability, just a hand. &lt;/p&gt;

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

&lt;p&gt;I'll give you the quickest example to understand how bad things are. You're a blind developer and Webpack bundling error generates 100+ lines of errors because of a typo in a component...&lt;/p&gt;

&lt;p&gt;I have &lt;strong&gt;really&lt;/strong&gt; just touched the tip of the iceberg, there are way more issues. Issues we don't think about on a daily basis, things we don't pay attention to, things we don't care about. We - developers, we the ones who try to make the world a better place, or at least we say so, we fail to see how bad the whole ecosystem is for people with disabilities. We are gatekeepers for so many people. We have done minimum to open doors for those people who really need it, for those for whom this job could be a gamechanger, a golden ticket to the world. &lt;/p&gt;

&lt;p&gt;As I said, we have done the minimum, it's progress, but we are so &lt;strong&gt;far&lt;/strong&gt; from at least OKAY.&lt;/p&gt;

&lt;h2&gt;
  
  
  What has been done?
&lt;/h2&gt;

&lt;p&gt;There are quite a few initiatives to try and open the gate. I would like to "shout out" them and tell you about them. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://serenade.ai"&gt;Serenade&lt;/a&gt; - a project created to involve more voice control for development. Voice-to-code tool specializing in writing code by voice uses a code snippets approach and is quite easy to use. But. It's still primarily targeting the developers who have no issues such as disabilities. They don't target people with disabilities specifically and so - paywall...&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Microsoft AI's research on the tools for people with disabilities - is quite a new initiative by Microsoft, still in the working stage, but already has done some real impact and serves as a pathway for those who want to contribute.  You can read more about it here &lt;a href="https://www.bcu.ac.uk/computing/research/digital-media-technology/research-projects/coding-for-disabled-developers"&gt;Inclusive Coding for Disabled Developers&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The list is....short. Really, it's damn hard to find anything. Leave the tools you've heard/know/use in the comments. I would love to test them.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ask yourself a question
&lt;/h2&gt;

&lt;p&gt;Life is unpredictable. Think about it. Right now you're healthy, this is a gift you have and at most do not realize. You have a job, you love being a programmer, at least I hope you do.&lt;/p&gt;

&lt;p&gt;Ask yourself a question "Am I secure at this job?". What would happen to me, my career, and my skills if due to a force major something happened to you and you've got a disability. You lost your arms/sight. Are you able to continue your job? Do you still feel secure? Well, personally, I would think that this is the end of my career. Though I still have the skills, and knowledge to do it. I still can work remotely as I am doing it now. I still can use a computer and sit in front of it for hours. I still can, but unfortunately, I can not work. Isn't it weird? &lt;/p&gt;

&lt;h2&gt;
  
  
  What needs to be done?
&lt;/h2&gt;

&lt;p&gt;Around 64% of people with disabilities are internet users (&lt;a href="https://www.researchgate.net/publication/262642900_An_analysis_of_the_digital_literacy_of_people_with_disabilities_in_Korea_Verification_of_a_moderating_effect_of_gender_education_and_age"&gt;An analysis of the digital literacy of people with disabilities in Korea: Verification of a moderating effect of gender, education and age&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;For now the most important is &lt;strong&gt;awareness&lt;/strong&gt;! We need to put more people into a state of awareness, educate people on the matter, and start building, innovating, and delivering. We all have got the benefits of working remotely, now it's time to let people who actually &lt;strong&gt;have to&lt;/strong&gt; work remotely join us. Brilliant, smart, innovative people who could be a great asset to the industry. People who will build and contribute to accessibility as no one else would. People who would care.&lt;/p&gt;

&lt;p&gt;We need to get the attention of big corporations and influencers to speak out loud about these issues. We &lt;strong&gt;must&lt;/strong&gt; create a friendly community of allies, who would provide assistance to onboard people with disabilities. We &lt;strong&gt;must&lt;/strong&gt; make sure that products and resources are free for those people. We &lt;strong&gt;must&lt;/strong&gt; create a smooth and fast track for them. We &lt;strong&gt;must&lt;/strong&gt; create specialized software for them.&lt;/p&gt;

&lt;p&gt;Do you know why there are no tools? Because people with disabilities treat being a programmer as inaccessible to them. This job is a "no go" for them. And this is why we must make sure that &lt;strong&gt;our&lt;/strong&gt; field is as accessible as possible.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Teaching, Creating, Delivering&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What's the plan?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;You can easily break a stick, but you can't break sticks in a bundle&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I would like to gather more people, more creative people, and more empathic people who would be willing to contribute and spread the awareness. If you're one of them, please reach out to me on Twitter - &lt;a href="https://twitter.com/SergiiKirianov"&gt;@SergiiKirianov&lt;/a&gt;, I would like to grow this community and start creating meaningful products, guidelines, and learning resources. Spread the word. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I believe that this is possible!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>a11y</category>
      <category>inclusion</category>
    </item>
    <item>
      <title>Imagine Scope</title>
      <dc:creator>Sergii Kirianov</dc:creator>
      <pubDate>Mon, 27 Sep 2021 01:53:55 +0000</pubDate>
      <link>https://forem.com/skirianov/imagine-scope-nde</link>
      <guid>https://forem.com/skirianov/imagine-scope-nde</guid>
      <description>&lt;p&gt;Step by step we are on the way to understand JavaScript Engine better. We have seen how JavaScript creates, executes and navigates through the world of script. We were exercising our imagination last two posts. This time we need to try harder 💪&lt;/p&gt;

&lt;p&gt;If you need refresher on Execution Context and Call Stack consider reading last two posts 😉&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.skirianov.com/imagine-execution-context-and-hoisting"&gt;Imagine Execution Context and Hoisting&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.skirianov.com/imagine-call-stack"&gt;Imagine Call Stack&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;We already know that JavaScript &lt;strong&gt;function&lt;/strong&gt; is a world. The tiny world inside big Global world. Today, we are going to create the first city. The "Function City".&lt;/p&gt;

&lt;h2&gt;
  
  
  Welcome to Function City! 🌃
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--b1OsloAG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1631931164482/GIHjvL61T.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--b1OsloAG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1631931164482/GIHjvL61T.jpeg" alt="5BFE8A32-5652-4E75-A6FC-9E9FE24B22A7.jpeg" width="800" height="652"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Imagination ON&lt;/em&gt;&lt;/strong&gt; 🌈 &lt;/p&gt;

&lt;p&gt;Each city need to have &lt;strong&gt;buildings&lt;/strong&gt; and &lt;strong&gt;houses&lt;/strong&gt; (it's same thing, aha). Every city has items and goods for citizens too, so that they can &lt;strong&gt;use&lt;/strong&gt; it - buy, sell, cook, wear, etc. Buildings can be goods too, like a private property. Citizens &lt;strong&gt;use&lt;/strong&gt; buildings too.&lt;/p&gt;

&lt;p&gt;City needs a Mayor. And Mayor of Function City is beloved by all! She is a very kind and generous person. City has it's own assets and goods. These goods are public and free for everyone. Every &lt;strong&gt;house&lt;/strong&gt;hold have &lt;em&gt;access&lt;/em&gt; to them.&lt;/p&gt;

&lt;p&gt;As in any modern society everyone has their private goods, which citizens keep inside their &lt;strong&gt;houses&lt;/strong&gt;. Some, on the other hand, have some priviliges and can change the goods available for citizens.&lt;/p&gt;

&lt;p&gt;Of course, city is not complete without &lt;em&gt;helper&lt;/em&gt; &lt;strong&gt;buildings&lt;/strong&gt;, so that citizens can interact with them. Restaurants, Cinemas, Shops, etc. All this &lt;strong&gt;buildings&lt;/strong&gt; offer you their services and are &lt;strong&gt;function&lt;/strong&gt;ing in the city.&lt;/p&gt;

&lt;p&gt;By the way, your sister Julia works in one of those. She works at Translation Services Agency. How this agency works you wonder? So you &lt;em&gt;pass&lt;/em&gt; them your documents (goods), they process it and &lt;strong&gt;return&lt;/strong&gt; result back to you. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VRQwHN6X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1631931296319/FfCzRrXWj.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VRQwHN6X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1631931296319/FfCzRrXWj.jpeg" alt="translating agency at work processing passed document" width="800" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are so many goods in the city which are public and Agency has &lt;em&gt;access&lt;/em&gt; to them. The Agency can actually change and process this documents if needed.&lt;/p&gt;

&lt;p&gt;So, looks like a nice city right? It is. But a little weird too. Mayor can change the meaning of the goods. What? What does it mean? Let's say, today you had a car, then Mayor has &lt;em&gt;reassigned&lt;/em&gt; another item to your car and poof....now you have a carrot. &lt;/p&gt;

&lt;p&gt;There are set of words, which were given by the creator of this whole world. Those words can't be changed. No one can &lt;em&gt;reassign&lt;/em&gt; them. Also, citizens do have some common sense. When they were building the city, they made a list of &lt;strong&gt;constant&lt;/strong&gt; words which cannot be reassigned too. Whole city depends on these words.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Imagination OFF&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Phew...this one was a hard abstraction to make up. I've tried to make it simple, yet meaningful. &lt;/p&gt;

&lt;p&gt;Any constructions like &lt;strong&gt;building&lt;/strong&gt; are representing functions. Do you remember the small world in the big one thing? Just like your own house is a small world in the big world. The &lt;strong&gt;goods&lt;/strong&gt; are values. Names are variable names. Any item can be reassigned to any name, except for those rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scope
&lt;/h2&gt;

&lt;p&gt;Before EcmaSript 2015 (ES6) only &lt;code&gt;var&lt;/code&gt; was available and scopes were a real issue. Variable declared with &lt;code&gt;var&lt;/code&gt; would be accessible everywhere within the script and could be redeclared. ES6 introduced &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt; variable declarations. They have block (local) scope and &lt;code&gt;var&lt;/code&gt; was almost completely replaced.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So what is Scope? 🤔&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Our scripts are full of functions. Functions as we know can take arguments, they have their own local Execution Context, they can have own local variables. This - is Scope. The Scope of the function. It is like indoors of the buildings that we have imagined. Private. Secure. You can interact with outer world from inside. But outer world cannot interact with you. &lt;/p&gt;

&lt;p&gt;Functions can have functions inside and those will follow the same rules. Let's look at example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function example (a, b) {
  console.log(a);
  function inside () {
    let c = 'Hello';
    console.log(c + ' world!');
    console.log(b);
  }
  inside();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks confusing right? Try to remember all that we have learned so far. What will happen first? Global Execution Context. At Creation Phase all the code will be read by JavaScript Engine and stored into memory. &lt;code&gt;function example()&lt;/code&gt; is completely stored into memory and ready to be invoked. Creation Phase is over at this point. Execution Phase starts. Execution Phase will go through the code and once it reached &lt;code&gt;example()&lt;/code&gt; it will invoke it. What's next? &lt;/p&gt;

&lt;p&gt;Once &lt;code&gt;function example()&lt;/code&gt; is invoked the Function Execution Context will start. If you remember, it's almost same as Global. The arguments object will be created and store our &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; arguments. &lt;code&gt;console.log(a)&lt;/code&gt; is also a function and will be stored into memory. &lt;code&gt;function inside()&lt;/code&gt; will be stored too. Then it's time for Execution Phase again. &lt;code&gt;console.log(a)&lt;/code&gt; will be invoked and print statement in console. Then once it will reach &lt;code&gt;inside()&lt;/code&gt; again the same thing is going to happen. Function Execution Context will start.&lt;/p&gt;

&lt;p&gt;Hope when you look at this step by step it became much easier to understand. Every Execution Context can have access to the parent Execution Context variables. But parent doesn't have access to it's child ones. Parent Execution Context can only pass data as arguments. &lt;/p&gt;

&lt;p&gt;Example output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  example('Yo!', 'You are the best =)');

  &amp;gt; 'Yo!'
  &amp;gt; 'Hello world!'
  &amp;gt; 'You are the best =)'

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

&lt;/div&gt;



&lt;p&gt;Can you trace what happen? What will happen in this case then?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function example (a, b) {
  console.log(a);
  b = 'See you around =)';
  console.log(c);
  function inside () {
    let c = 'Hello';
    console.log(c + ' world!');
    console.log(b);
  }
  inside();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try to use your imagination. Try to imagine those scopes, those locked houses with private data. Can somebody access your goods inside your house? &lt;/p&gt;

&lt;p&gt;I think you have managed it. But what if we declare &lt;code&gt;c&lt;/code&gt; before and then try to declare it again with &lt;code&gt;var&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;function example (a, b) {
  console.log(a);
  var c = 'Hehehe I am nasty var';
  b = 'See you around =)';
  function inside () {
    var c = 'Hello';
    console.log(c + ' world!');
    console.log(b);
  }
  console.log(c);
  inside();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Are we those privileged citizens who can change &lt;code&gt;c&lt;/code&gt; on their will? Yes we are. &lt;code&gt;var&lt;/code&gt; declaration is happening in Global Scope (available everywhere in the program) or in the Function Scope (available only inside the function and other inner functions). &lt;code&gt;var&lt;/code&gt; can be reassigned and even redeclared.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let a = 'hey I am an a!';
let a = 'now I am z!';

  &amp;gt; Uncaught SyntaxError: Identifier 'a' has already been declared

var b = 'hey I am b!';
var b = 'now I am z!';
console.log(b);

  &amp;gt; 'now I am z!'

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

&lt;/div&gt;



&lt;p&gt;Now after this code snippet, if you could not manage the previous one, have a look again. &lt;/p&gt;

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

&lt;p&gt;JavaScript scopes may be confusing. It may be daunting and hard. But hey, we all have passed through this. Try to practice with scopes. Play with variables in different parts of your script and functions. Try to nest 10 functions and before you run it, put everything on paper. How are you expecting &lt;code&gt;console.log&lt;/code&gt; statements print out. What will be the order? Make it harder. Add &lt;code&gt;let&lt;/code&gt;, &lt;code&gt;const&lt;/code&gt; and &lt;code&gt;var&lt;/code&gt; inside your functions and try to reassign and redeclare variables. Put on paper. Can you still trace them? &lt;/p&gt;

&lt;p&gt;I bet once you do this exercises few times, you will see the picture. You will be able to folow the data flow from the arguments passed to the first function and down to the most inner function. Imagination is what I want you to engage. &lt;/p&gt;

&lt;p&gt;Hope it was not confusing and helped you. Even a little. It was a great help to me too. Writing this post was hard and imaginary world is not perfect. &lt;/p&gt;

&lt;p&gt;See you around!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Imagine Call Stack</title>
      <dc:creator>Sergii Kirianov</dc:creator>
      <pubDate>Mon, 20 Sep 2021 01:56:37 +0000</pubDate>
      <link>https://forem.com/skirianov/imagine-call-stack-3pjb</link>
      <guid>https://forem.com/skirianov/imagine-call-stack-3pjb</guid>
      <description>&lt;p&gt;In last article we have discussed how the JavaScript Engine reads through our code and executes it. A lot of guides and courses treat this information as an advanced topic and jumps straight into coding. If I had the knowledge of this processes when I started it would be so much easier for me to understand why things happen as they happen. We went through the very fundamental process in JavaScript Engine runtime, now let's have a closer look how Engine runs your code. &lt;/p&gt;

&lt;p&gt;Today we will learn something about Call Stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  Call Stack
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Call Stack&lt;/strong&gt; is a mechanism, which allows JavaScript Engine to keep track of it's location inside a script. It is a data structure. Array of some kind. Array where things are getting pushed into it and popped out. &lt;br&gt;
As mentioned in the last article, after everything is set up, the Execution Phase starts. Using &lt;strong&gt;Hoisting&lt;/strong&gt; it can access any function within your code. So if you have nested function inside other function, and that function has many more of them inside, how will JavaScript understand what is it location now within your code?. This is where &lt;strong&gt;Call Stack&lt;/strong&gt; kicks in. &lt;/p&gt;

&lt;p&gt;Let's stack those calls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Imagination ON&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You are function. Let's say, your name is Tom. You need to go to the mall, but you can't find the keys from his car. You searched all the house upside down but failed to spot them. Maybe your sister Amy took them or brother Ryan? Let's find out. You pick up the phone and &lt;strong&gt;call&lt;/strong&gt; your sister function Amy.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hey Amy, have you seen my keys?&lt;/li&gt;
&lt;li&gt;Let me have a look. No, I can't find them either. Hold the line, I'll call Ryan.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You are waiting for Amy to complete the execution of a task she has. Your family has strict rules, you cannot just proceed to anything else, until Amy &lt;em&gt;returns&lt;/em&gt; to you with the answer.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hey Ryan, it's Amy. By any chance, have you seen Tom's keys?&lt;/li&gt;
&lt;li&gt;Hello Amy. Just give me a moment, I'll have a look. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, Amy waits for Ryan to complete his task and &lt;strong&gt;return&lt;/strong&gt; to her. You are still waiting for both of them, you know the rules. You see, the calls are in the stack.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Yeah I found them Amy. I'll &lt;strong&gt;return&lt;/strong&gt; them to you, just pass it back to To, okay?&lt;/li&gt;
&lt;li&gt;Thanks! Sure, I'll do.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, the execution of Ryan's task is completed and he is out of the stack.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hey Tom, we found the keys, I'll return them to you now. Thanks for waiting!&lt;/li&gt;
&lt;li&gt;Oh, that's sweet, thanks Amy!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The execution of the Amy's task is also over. She hangs the phone and out of the stack now. Last thing is for Tom to &lt;strong&gt;return&lt;/strong&gt; to his task,  to go to mall and complete it.&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%2Fs9.gifyu.com%2Fimages%2FCE616726-6C0F-4996-98CA-8A277BD63580.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%2Fs9.gifyu.com%2Fimages%2FCE616726-6C0F-4996-98CA-8A277BD63580.gif" alt="stack of calls"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Imagination OFF&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Back to JavaScript. &lt;/p&gt;

&lt;p&gt;When first function is invoked it is pushed to &lt;strong&gt;Call Stack&lt;/strong&gt; as a foundation. If there are no nested functions inside the first one, once it is completed it is removed from the stack. Function are pushed and popped off the stack in the &lt;strong&gt;&lt;em&gt;Last In First Out&lt;/em&gt;&lt;/strong&gt; way. Imagine a stack of dirty plates at the sink. Last plate put on top will be the first plate to get washed.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;JavaScript Engine is a single threaded and it's synchronous nature means that is can do only one thing at a time. Until that task is over, the Engine can not proceed with next one.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's take a simple nested function as an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  function main() {
    one();  //can we call function one() before it's declaration? 
    console.log('Message from main function');
  }

  function two() {
    three();
    console.log('Message from function two');
  }

  function three() {
    console.log('Message from function three');
  }

  function one() {  //yes we can. this is what hoisting is. if you are not sure why, check the last article
    two();
    console.log('Message from function one');
  }


main()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we are JavaScript Engine and we are going to build the stack. First function to add to our stack will be function &lt;code&gt;main&lt;/code&gt;. &lt;code&gt;main&lt;/code&gt; calls function &lt;code&gt;one&lt;/code&gt;, it is added to the stack and function &lt;code&gt;main&lt;/code&gt; waits for it to finish. &lt;code&gt;one&lt;/code&gt; calls &lt;code&gt;two&lt;/code&gt; and then &lt;code&gt;two&lt;/code&gt; calls &lt;code&gt;three&lt;/code&gt;. What will be the last function added to the stack? &lt;br&gt;
If you say &lt;code&gt;three&lt;/code&gt; you are almost there. Actually, when function &lt;code&gt;three&lt;/code&gt; is added to the stack it also calls function &lt;code&gt;console.log&lt;/code&gt; (we will not go deep to the implementation of console.log to simplify) and this &lt;code&gt;console.log&lt;/code&gt; is the last function we add to the stack. Let's have a look at our stack, before we start popping things off it.&lt;/p&gt;

&lt;p&gt;You can see, that other &lt;code&gt;console.log&lt;/code&gt; were not added to the Call Stack just yet. As mentioned earlier, JavaScript Engine will not proceed with the next task, until first one is completed.&lt;/p&gt;

&lt;p&gt;Okay, now we start popping things off the stack. Is it only popping things off or we will push something more into the stack?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;console.log&lt;/code&gt; on top of the stack has printed in the console and was popped off the stack. Function &lt;code&gt;three&lt;/code&gt; has no more tasks and also popped off the stack. Next, function &lt;code&gt;two&lt;/code&gt; still has another function inside - the &lt;code&gt;console.log&lt;/code&gt;. Now, this &lt;code&gt;console.log&lt;/code&gt; will be pushed into the stack on top and all other functions will wait for it to complete. Things are going to be popped off and pushed into, until the reach the last &lt;code&gt;main&lt;/code&gt; function, after it's execution, the stack will be empty and JavaScript will proceed to execute next portion of your code.&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%2Fs9.gifyu.com%2Fimages%2F57D52389-509D-4DE7-9349-326B36BD09BB.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%2Fs9.gifyu.com%2Fimages%2F57D52389-509D-4DE7-9349-326B36BD09BB.gif" alt="stack"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Call Stack&lt;/strong&gt; can get very complicated and it may become very hard to track things. The more functions are nested inside other functions the harder it gets. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Thing to note. All this process is lightning fast unless heavy computation is involved&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Stack Overflow
&lt;/h2&gt;

&lt;p&gt;Except for being a developers Mecca, stack overflow is the process when your function calls itself and does not have any exit point. I called it process, but it is actually a tool which spots this infinite recursion and prevents your computer to blow up :D The &lt;strong&gt;Call Stack&lt;/strong&gt; will grow and grow, until it reached the limit of the memory and cannot grow anymore. This is where you will get stack overflow error.&lt;/p&gt;

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

&lt;p&gt;Is it better now? I hope it is. &lt;strong&gt;Call Stack&lt;/strong&gt; is only one of many things happening under the hood when you run your code, but it is extremely important to understand in which order your functions run and how JavaScript Engine treats them.&lt;br&gt;
The implementation in the imaginary world and example is the synchronous. JavaScript has evolved a lot and asynchronous approach is the new gold standard. We will get to that point in future articles, but understanding of synchronous way is a must. I want to make sure that we will have everything necessary to proceed with more advanced topics.&lt;/p&gt;

&lt;h2&gt;
  
  
  A few words on recursion
&lt;/h2&gt;

&lt;p&gt;I have mentioned recursion at the stack overflow section and even we are now ready to get familiar with this concept, I would suggest to keep it for later. Recursion is just a tool and it is not required right now for understanding of the basics.&lt;/p&gt;

&lt;p&gt;Please, imagine what you are reading. Even though the pictures are provided, try to use your imagination. Create this blocks in your head and go through the example, stack them on top of each other and pop them off when they are done.&lt;/p&gt;

&lt;p&gt;As usual, comment if something is wrong, contact me if you need clarification, suggest if you want!&lt;/p&gt;

&lt;p&gt;See you around.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>v8</category>
      <category>node</category>
    </item>
    <item>
      <title>Imagine Execution Context and Hoisting</title>
      <dc:creator>Sergii Kirianov</dc:creator>
      <pubDate>Sat, 18 Sep 2021 22:52:30 +0000</pubDate>
      <link>https://forem.com/skirianov/imagine-execution-context-and-hoisting-3fa1</link>
      <guid>https://forem.com/skirianov/imagine-execution-context-and-hoisting-3fa1</guid>
      <description>&lt;p&gt;JavaScript fundamentals may be overwhelming and difficult to understand. This blog posts are reflection of my understanding of concepts and aimed to help others, who may struggle to grasp them.&lt;/p&gt;

&lt;p&gt;Today we will look at the fundamentals of how JavaScript running behind the scenes. Today we will be JavaScript ourselves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Execution Context
&lt;/h2&gt;

&lt;p&gt;What is this? &lt;strong&gt;Execution Context&lt;/strong&gt; is the process JavaScript Engine is using to interpret your code. It is simply a splitting of one big and complicated task into small easy steps. Understanding of this topic is &lt;em&gt;essential&lt;/em&gt; to see the big picture. Other advanced topics will get much clearer once you get it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Global Execution Context
&lt;/h2&gt;

&lt;p&gt;JavaScript "reads" your code from top to bottom. Line by line, like you read this post. The first thing happens when you run your &lt;strong&gt;&lt;em&gt;.js&lt;/em&gt;&lt;/strong&gt; file is the creation of Global Execution Context. This process consists of two phases: &lt;strong&gt;Creation&lt;/strong&gt; and &lt;strong&gt;Execution&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creation Phase&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Imagination ON&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You are the writer. You want to write a new book. What will you do first? Right, create the world. You will &lt;em&gt;create&lt;/em&gt; a foundation of the story - the world, where your &lt;em&gt;characters&lt;/em&gt; will exist and live. Like a global object everyone refers to. &lt;em&gt;this&lt;/em&gt; world.&lt;/p&gt;

&lt;p&gt;Once the world is created, you want to add some &lt;em&gt;characters&lt;/em&gt;, right? Empty world is no fun, you know. Somebody who will &lt;em&gt;interact&lt;/em&gt; with each other and the world. Let's do it. Let's declare their existance and function. &lt;/p&gt;

&lt;p&gt;A while after, the story is completed. The book has become a new bestseller. Hollywood wants to film it now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Imagination OFF&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When JavaScript Engine parses your code it &lt;em&gt;creates&lt;/em&gt; a global object &lt;code&gt;window&lt;/code&gt; and variable &lt;code&gt;this&lt;/code&gt; which refers to that object. Memory is allocated for variables. Their names stored and assigned a value of 'undefined'.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  var foo = 'bar';
  var person = 'John Doe';

  function sayHi() {
    console.log('Hello world!')
  }

  sayHi();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1631321006726%2F04Uyb6u84.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1631321006726%2F04Uyb6u84.png" alt="16F3C4F6-FC39-4BD1-AE0B-92AF70612213.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;JavaScript running in the browser will create &lt;code&gt;window&lt;/code&gt; object and running in Nodejs will create &lt;code&gt;global&lt;/code&gt; object.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Execution Phase&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Imagination ON&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Now, you are a famous Holywood Director, you've got the script for that new book everyone is talking about and big bosses wants it to be filmed. The world has been created for you already, it just needs to be brought to life. You have noticed, that script is not written very well and sometimes new characters appear in the middle of the chapter. But you are a visioner, you are well known for following the scripts like a machine, no one can say that book was better.&lt;/p&gt;

&lt;p&gt;You start hiring actors and &lt;em&gt;assigning&lt;/em&gt; them to the characters. Then. Camera! Motor! Action! You are filming them acting, &lt;em&gt;functioning&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;And that's it. Movie is ready. Oscar is your, no doubt.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Imagination OFF&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At the Execution Phase the JavaScript Engine is assigning values to the variables stored in memory and ininitializing functions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1631321039676%2FPEmqyBeJr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1631321039676%2FPEmqyBeJr.png" alt="24337E4B-8AEE-4FBF-B8CB-1477316BBC9B.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creation and Execution Phase&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Execution Phase starts when Creation Phase is over. If you look closely, you will spot that because all the variables have been stored with value of 'undefined' during Creation Phase, you can actually call them before they were assigned a value. This leads us to the next concept - Hoisting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Function Execution Context
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1631321062611%2FiqzlZnAgh.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1631321062611%2FiqzlZnAgh.jpeg" alt="D92A2F40-5C03-40BA-AF70-7D6EB19FF008.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, almost.&lt;/p&gt;

&lt;p&gt;Function Execution Context follows almost identically same principles as Global Execution Context. Only difference is, that Function Execution Context is not creating another &lt;code&gt;window&lt;/code&gt; object, as it can be created only once, but instead it creates an &lt;code&gt;arguments&lt;/code&gt; object. This "arguments" object is local and accessible only within the context of that function.&lt;/p&gt;

&lt;p&gt;It is like the &lt;em&gt;world&lt;/em&gt; created inside the global &lt;em&gt;wowld&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hoisting
&lt;/h2&gt;

&lt;p&gt;During the Execution Phase variables declared with &lt;code&gt;var&lt;/code&gt; will be accessible, even before values were assigned to them, because they already store 'undefined' and it will not cause a Reference error. Variables declared with &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt; will be only initialized during Execution Phase and values assigned at that moment, hence trying to access this variables before will lead to Refence error. &lt;/p&gt;

&lt;p&gt;On the other hand, Functions have been fully stored in memory during Creation Phase, which allows us to invoke them even before they have been initialized at the Execution Phase. &lt;/p&gt;

&lt;p&gt;Ability to invoke functions before initializing is called &lt;strong&gt;Hoisting&lt;/strong&gt;. &lt;/p&gt;

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

&lt;p&gt;I hope this was helpfull and made things clear. This is very fundamental topic, which I recently was not aware of and most of beginner guides are missing this. Even while I was writing draft of this post, I have got better understanding how recursion works. Please feel free to contact me if you find something wrong or if there anything you would like to add. &lt;/p&gt;

&lt;p&gt;See you around!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>webdev</category>
      <category>computerscience</category>
    </item>
  </channel>
</rss>
