<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Akash Joshi - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Akash Joshi - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 19 May 2026 20:24:25 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/thewritingdev/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ What's New in React 18 Alpha? Concurrency, Batching, the Transition API and More ]]>
                </title>
                <description>
                    <![CDATA[ Hey everyone! In this article, I'm going to show you what's new in the latest of version of React – React 18 alpha – in under 8 minutes. First, you might be wondering whether the latest set of changes will break anything with your current setup, or w... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/whats-new-in-react-18/</link>
                <guid isPermaLink="false">66d45d6051f567b42d9f841b</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Akash Joshi ]]>
                </dc:creator>
                <pubDate>Fri, 09 Jul 2021 18:42:26 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/07/SUSPENSE-BATCHING-TRANSITION.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Hey everyone! In this article, I'm going to show you what's new in the latest of version of React – React 18 alpha – in under 8 minutes.</p>
<p>First, you might be wondering whether the latest set of changes will break anything with your current setup, or whether you will have to learn new completely unrelated concepts.</p>
<p>Well, don't worry – you can continue with your present work or continue learning your current React course as it is, as React 18 doesn't break anything.</p>
<p>If you want to watch a video to supplement your reading, check it out here:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/IOeqma3YcGs" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>For those of you who really want to learn what's happening, here's the breakdown.</p>
<p>Just a quick note: React 18 is still in alpha and isn't out yet. So this is what you can expect when it's released.</p>
<h2 id="heading-what-is-concurrency-in-react">What is Concurrency in React?</h2>
<p>The major theme for this release is <strong>concurrency</strong>. To start with, let's look at what concurrency is.</p>
<p>Concurrency is the ability to execute multiple tasks simultaneously. Taking the example of a standard React app, let's consider that an animation is playing in a component, and at the same time a user is able to click or type in other React components.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/firefox_juLm49pOIQ.png" alt="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/f5a65bda-b76b-466f-abe3-3d8fbb232655/firefox_PJSGkv5qWX.png" width="600" height="400" loading="lazy"></p>
<p>Here, while the user is typing and clicking on buttons, an animation is also rendering there within the context of React.</p>
<p>React has to manage all the function calls, hook calls, and event callbacks, several of which can even occur at the same time. If React spends all its time rendering animation frames, the user will feel like the app is "stuck", since it won't react to their inputs.</p>
<p>Now React, running on a single threaded process, has to combine, reorder and prioritize these events and functions so that it can give users an optimum and performant experience.</p>
<p>To do this, React uses a "dispatcher" internally which is responsible for prioritizing and invoking these callbacks.</p>
<p>Before React 18, the user had no way to control the invocation order of these functions. But now, React is giving some control of this event loop to the user via the Transition API.</p>
<p>You can read more about this in this article by Dan Abramov: <a target="_blank" href="https://github.com/reactwg/react-18/discussions/46#discussioncomment-846786">An ELI5 of concurrency</a>.</p>
<h2 id="heading-the-transition-api">The Transition API</h2>
<p>The developers of React have exposed a few APIs which allow React users to have some control over concurrency.</p>
<p>One of these APIs is <code>startTransition</code>, which allows developers to indicate to React which actions may block the thread and cause lag on screen.</p>
<p>Typically, these actions are the ones you might have previously used debounce for, like network calls via a search API, or render-heavy processes like searching through an array of 1000 strings.</p>
<p>Updates wrapped in <code>startTransition</code> are marked as non-urgent and are interrupted if more urgent updates like clicks or key presses come in.</p>
<p>If a transition gets interrupted by the user (for example, by typing multiple letters into a search field), React will throw out the stale rendering work that wasn’t finished and render only the latest update.</p>
<h3 id="heading-transition-api-example">Transition API example</h3>
<p>To understand this in more detail, let's consider a component with a search field. Let's say it has 2 functions to control the state:</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// Update input value</span>
setInputValue(input)

<span class="hljs-comment">// Update the searched value and search results</span>
setSearchQuery(input);
</code></pre>
<p><code>setInputValue</code> is responsible for updating the input field, while <code>setSearchQuery</code> is responsible for performing search based on the present input value. Now, if these function calls happened synchronously every time the user started typing, either of 2 things would happen:</p>
<ol>
<li><p>Several search calls would be made, which would delay or slow down other network calls.</p>
</li>
<li><p>Or, more likely, the search operation would turn out to be very heavy and would lock up the screen on each keystroke.</p>
</li>
</ol>
<p>One way to solve this problem would've been using debounce, which would space out the network calls or search operations. But, the problem with debounce is that we have to play with and optimize the debounce timer quite frequently.</p>
<p>So in this case, we can wrap setSearchQuery in <code>startTransition</code>, allowing it to handle it as non-urgent and to be delayed as long as the user is typing.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { startTransition } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-comment">// Urgent: Show what was typed</span>
setInputValue(input);

<span class="hljs-comment">// Mark any state updates inside as transitions</span>
startTransition(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-comment">// Transition: Show the results</span>
  setSearchQuery(input);
});
</code></pre>
<p>Transitions let you keep most interactions snappy even if they lead to significant UI changes. They also let you avoid wasting time rendering content that's no longer relevant.</p>
<p>React also provides a new hook called <code>useTransition</code> , so you can show a loader while the transition is pending. This helps in indicating to the user that the app is processing their input and will display the results shortly.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useTransition } <span class="hljs-keyword">from</span><span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> [isPending, startTransition] = useTransition();

<span class="hljs-keyword">const</span> callback = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-comment">// Urgent: Show what was typed</span>
  setInputValue(input);

  <span class="hljs-comment">// Mark any state updates inside as transitions</span>
  startTransition(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// Transition: Show the results</span>
    setSearchQuery(input);
  });
}

{isPending &amp;&amp; <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Spinner</span> /&gt;</span></span>}
</code></pre>
<p>As a rule of thumb, you can use the transition API wherever network calls or render-blocking processes are present.</p>
<p>You can read more about the API in this article, <a target="_blank" href="https://github.com/reactwg/react-18/discussions/41">An explanation of startTransition</a> by Ricky from the Core React team.</p>
<h3 id="heading-demos-of-the-transition-api">Demos of the Transition API</h3>
<p>Use <code>useTransition</code> and Suspense in an app: <a target="_blank" href="https://codesandbox.io/s/sad-banach-tcnim?file=/src/App.js:664-676">https://codesandbox.io/s/sad-banach-tcnim?file=/src/App.js:664-676</a></p>
<p>Demo of <code>startTransition</code> with a complex rendering algorithm: <a target="_blank" href="https://react-fractals-git-react-18-swizec.vercel.app/">https://react-fractals-git-react-18-swizec.vercel.app/</a></p>
<h2 id="heading-batching-in-react">Batching in React</h2>
<p>Next up is batching. Batching is something that the developer generally doesn't have to care about, but it's good to know what's happening behind the scenes.</p>
<p>Whenever you are using setState to change a variable inside any function, instead of making a render at each setState, React instead collects all setStates and then executes them together. This is known as batching.</p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);
  <span class="hljs-keyword">const</span> [flag, setFlag] = useState(<span class="hljs-literal">false</span>);

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClick</span>(<span class="hljs-params"></span>) </span>{
    setCount(<span class="hljs-function"><span class="hljs-params">c</span> =&gt;</span> c + <span class="hljs-number">1</span>); <span class="hljs-comment">// Does not re-render yet</span>
    setFlag(<span class="hljs-function"><span class="hljs-params">f</span> =&gt;</span> !f); <span class="hljs-comment">// Does not re-render yet</span>
    <span class="hljs-comment">// React will only re-render once at the end (that's batching!)</span>
  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleClick}</span>&gt;</span>Next<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">color:</span> <span class="hljs-attr">flag</span> ? "<span class="hljs-attr">blue</span>" <span class="hljs-attr">:</span> "<span class="hljs-attr">black</span>" }}&gt;</span>{count}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>This is great for performance because it avoids unnecessary re-renders. It also prevents your component from rendering “half-finished” states where only one state variable was updated, which may cause UI glitches and bugs within your code.</p>
<p>However, React didn't used to be consistent about when it performed batching. This was because React used to only batch updates <em>during</em> browser events (like a click), but here we’re updating the state <em>after</em> the event has already been handled (in a fetch callback):</p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);
  <span class="hljs-keyword">const</span> [flag, setFlag] = useState(<span class="hljs-literal">false</span>);

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClick</span>(<span class="hljs-params"></span>) </span>{
    fetchSomething().then(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-comment">// React 17 and earlier does NOT batch these because</span>
      <span class="hljs-comment">// they run *after* the event in a callback, not *during* it</span>
      setCount(<span class="hljs-function"><span class="hljs-params">c</span> =&gt;</span> c + <span class="hljs-number">1</span>); <span class="hljs-comment">// Causes a re-render</span>
      setFlag(<span class="hljs-function"><span class="hljs-params">f</span> =&gt;</span> !f); <span class="hljs-comment">// Causes a re-render</span>
    });
  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleClick}</span>&gt;</span>Next<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">color:</span> <span class="hljs-attr">flag</span> ? "<span class="hljs-attr">blue</span>" <span class="hljs-attr">:</span> "<span class="hljs-attr">black</span>" }}&gt;</span>{count}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>Starting in React 18 with <code>[createRoot](&lt;https://github.com/reactwg/react-18/discussions/5&gt;)</code>, all state updates will be automatically batched, no matter where they originate from.</p>
<p>This means that updates inside of timeouts, promises, native event handlers or any other event will batch the same way as updates inside of React events. This will result in less rendering work by React, and therefore better performance in applications.</p>
<p>You can read more about batching here in <a target="_blank" href="https://github.com/reactwg/react-18/discussions/21">An explanation of Batching</a> by Dan Abramov.</p>
<h3 id="heading-demos-of-batching">Demos of batching</h3>
<p>Before React 18: <a target="_blank" href="https://codesandbox.io/s/hopeful-fire-ge4t2?file=/src/App.tsx">https://codesandbox.io/s/hopeful-fire-ge4t2?file=/src/App.tsx</a></p>
<p>After React 18: <a target="_blank" href="https://codesandbox.io/s/morning-sun-lgz88?file=/src/index.js">https://codesandbox.io/s/morning-sun-lgz88?file=/src/index.js</a></p>
<h2 id="heading-the-suspense-api">The Suspense API</h2>
<p>React 18 includes a lot of changes to improve React performance in a <a target="_blank" href="https://www.freecodecamp.org/news/server-side-rendering-your-react-app-in-three-simple-steps-7a82b95db82e/">Server-Side Rendered</a> context. Server-side rendering is a way of rendering the JS data to HTML on the server to save computation on the frontend. This results in a faster initial page load in most cases.</p>
<p>React performs Server Side Rendering in 4 sequential steps:</p>
<ul>
<li><p>On the server, data is fetched for each component.</p>
</li>
<li><p>On the server, the entire app is rendered to HTML and sent to the client.</p>
</li>
<li><p>On the client, the JavaScript code for the entire app is fetched.</p>
</li>
<li><p>On the client, the JavaScript connects React to the server-generated HTML, which is known as Hydration.</p>
</li>
</ul>
<p>React 18 introduces the <code>Suspense</code> API, which allows you to break down your app into <strong>smaller independent units</strong>, which will go through these steps independently and won’t block the rest of the app. As a result, your app’s users will see the content sooner and be able to start interacting with it much faster.</p>
<h3 id="heading-how-does-the-suspense-api-work">How does the Suspense API work?</h3>
<h4 id="heading-streaming-html">Streaming HTML</h4>
<p>With today’s SSR, rendering HTML and hydration are “all or nothing”. The client has to fetch and hydrate all of the app at once.</p>
<p>But React 18 gives you a new possibility. You can wrap a part of the page with <code>&lt;Suspense&gt;</code>.</p>
<pre><code class="lang-jsx">&lt;Suspense fallback={<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Spinner</span> /&gt;</span></span>}&gt;
  {children}
&lt;/Suspense&gt;
</code></pre>
<p>By wrapping the component in <code>&lt;Suspense&gt;</code>, we tell React that it doesn’t need to wait for comments to start streaming the HTML for the rest of the page. Instead, React will send the placeholder (a spinner) instead.</p>
<p>When the data for the comments is ready on the server, React will send additional HTML into the same stream, as well as a minimal inline <code>&lt;script&gt;</code> tag to put that HTML in the “right place”.</p>
<h4 id="heading-selective-hydration">Selective Hydration</h4>
<p>Before React 18, hydration couldn't start if the complete JavaScript code for the app hadn't loaded in. For larger apps, this process can take a while.</p>
<p>But in React 18, <code>&lt;Suspense&gt;</code> lets you hydrate the app before the child components have loaded in.</p>
<p>By wrapping components in <code>&lt;Suspense&gt;</code>, you can tell React that they shouldn’t block the rest of the page from streaming—and even hydration. This means that you no longer have to wait for all the code to load in order to start hydrating. React can hydrate parts as they’re being loaded.</p>
<p>These 2 features of <code>Suspense</code> and several other changes introduced in React 18 speed up initial page loads tremendously.</p>
<p>You can read more in this article <a target="_blank" href="https://github.com/reactwg/react-18/discussions/37">An explanation of Suspense SSR</a> and related changes by Dan Abramov</p>
<h3 id="heading-demo-of-suspense">Demo of Suspense</h3>
<p><a target="_blank" href="https://codesandbox.io/s/recursing-mclaren-1ireo?file=/src/index.js:458-466">https://codesandbox.io/s/recursing-mclaren-1ireo?file=/src/index.js:458-466</a></p>
<h2 id="heading-summary">Summary</h2>
<p>So to summarize, the features that React 18 brings are:</p>
<ul>
<li><p>Concurrency control with the Transition API,</p>
</li>
<li><p>Automatic Batching of function calls and events to improve in-app performance, and</p>
</li>
<li><p>Much faster page loads for SSR with Suspense.</p>
</li>
</ul>
<p>Although not a very large departure from the previous version of React, all of these changes are making React a trend-setter for all the frameworks out there.</p>
<p>Thanks for reading this! You can check out my previous posts and tutorials on React here on freeCodeCamp. You can also follow me on Twitter <a target="_blank" href="https://twitter.com/thewritingdev">@thewritingdev</a>, where I post daily content on React and web development.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build React Applications with Deno Using the AlephJS Library ]]>
                </title>
                <description>
                    <![CDATA[ If you're a front end developer who's just getting started with Deno, you might be wondering – can you build something as complex as a NextJS or create-react-app (CRA) application using Deno? I was recently thinking the same thing. I wanted to try De... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-react-app-using-deno-and-alephjs/</link>
                <guid isPermaLink="false">66d45d5d55db48792eed3f05</guid>
                
                    <category>
                        <![CDATA[ Deno ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Akash Joshi ]]>
                </dc:creator>
                <pubDate>Fri, 12 Mar 2021 18:08:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/03/Kapture-2021-03-11-at-11.33.15-4.gif" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you're a front end developer who's just getting started with Deno, you might be wondering – can you build something as complex as a NextJS or create-react-app (CRA) application using Deno?</p>
<p>I was recently thinking the same thing. I wanted to try Deno because of its shareability that results from being able to run an application directly from a URL. The Deno compiler supports running JavaScript and TypeScript files from a URL and it also supports imports from a URL, resulting in extreme portability.</p>
<p>I looked to see if there were any existing solutions online, but I only found <a target="_blank" href="https://dev.to/adriantwarog/react-deno-server-side-rendering-with-deno-ssr-4438">this article</a>, which built an SSR'd React application using some complex techniques. It wasn't simple, like getting started with NextJS or CRA.</p>
<p>So, through my searches online, I ended up at <a target="_blank" href="https://alephjs.org/">AlephJS</a>, which has one of the coolest landing page animations ever.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Kapture-2021-03-11-at-11.33.15-3.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Aleph is a Zero-Config, Typescript-driven React framework, just like NextJS. The only drawback is that that Aleph is still very much in alpha.</p>
<p>So to get a true Next-like React experience inside Deno, let's get started with AlephJS. It has many of the same conventions as Next, such as:</p>
<ul>
<li><p>A <code>/pages</code> directory for creating URL routes</p>
</li>
<li><p>Direct <code>.js, .jsx, .ts, .tsx</code> support in pages</p>
</li>
<li><p>A <code>/public</code> directory for serving static assets like video, audio, or image files</p>
</li>
<li><p>A <code>/pages/api</code> folder for serving JavaScript or TypeScript files as serverless APIs.</p>
</li>
</ul>
<p>If you want to watch a video about how to do this to supplement your reading, check it out here:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/SDTedmFhnQc" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<h2 id="heading-how-to-get-started-with-alephjs">How to Get Started with AlephJS</h2>
<p>To be able to use AlephJS, you need Deno installed on your machine. You can see how to install and get started with Deno in my <a target="_blank" href="https://www.freecodecamp.org/news/build-a-url-shortener-in-deno/">previous article here</a>.</p>
<p>To get started with Aleph, you need to first install the Aleph CLI by running this command:</p>
<pre><code class="lang-bash">deno install -A -f -n aleph https://deno.land/x/aleph@v0.3.0-alpha.1/cli.ts
</code></pre>
<p>After installation, you can run <code>aleph -h</code> to check whether it got installed correctly.</p>
<p>Because of the portability of Deno, you can replace <code>aleph</code> with <code>deno run -A https://deno.land/x/aleph@v0.3.0-alpha.1/cli.ts start $app_URI</code> for any command and it will be able to run the Aleph program without having the CLI locally installed.</p>
<p>To create a starter app, run:</p>
<pre><code class="lang-bash">aleph init hello
<span class="hljs-built_in">cd</span> hello
</code></pre>
<p>And start the app in development mode using <code>aleph dev</code> to start a server at port <code>8080</code>.</p>
<p>To start the app in production mode, you have to first <code>build</code> the app and then run the built app. You can do this through these commands:</p>
<pre><code class="lang-bash">aleph build <span class="hljs-comment"># build your app</span>
aleph start <span class="hljs-comment"># runs built app</span>
</code></pre>
<p>After you initialise your Aleph app, you will find that the root component is defined at <code>pages/index.tsx</code>. It's a normal React component. You can experiment with it to see how Aleph works.</p>
<p>You can add more routes to your application by creating more <code>.jsx</code> or <code>.tsx</code> files inside the <code>pages</code> folder. You can read more on routing in Aleph <a target="_blank" href="https://alephjs.org/docs/basic-features/routing">here</a>.</p>
<h2 id="heading-how-to-import-libraries-in-deno">How to Import Libraries in Deno</h2>
<p>I've written about Deno previously on <a target="_blank" href="https://www.freecodecamp.org/news/build-a-url-shortener-in-deno/">freeCodeCamp</a> where I demoed some Deno basics, including URL imports. Since Aleph is a Deno framework, all imports happen in the "Deno way".</p>
<p>There are two kinds of libraries which you can import in a Deno application.</p>
<ol>
<li><p>Importing Deno-Native Libraries: These libraries were either built for Deno, or ported over from npm to support Deno usage.</p>
</li>
<li><p>Importing from NPM: if you've worked with JS recently you probably know about npm. If you don't, npm (the company behind node package manager) is the standard repository for all JavaScript libraries. Luckily, Deno has limited support for npm libraries. Using tools like <a target="_blank" href="http://esm.sh">esm.sh</a> or skypack.dev, users can import npm libraries into Deno.</p>
</li>
</ol>
<h3 id="heading-1-how-to-import-deno-native-libraries">1. How to Import Deno-Native Libraries</h3>
<p>You can import Deno-Native libraries in your application by importing their URLs directly. You can find a list of Deno libraries here: <a target="_blank" href="http://deno.land/x">deno.land/x</a></p>
<p>To test this out, let’s import this <a target="_blank" href="https://deno.land/std@0.88.0/datetime">standard Deno date formatting library</a>, and call a date format function in a React page. Create a file <code>date-import.tsx</code> in the <code>pages</code> folder of your app. Inside the file, write the following code:</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// react is a compulsoy import in Aleph</span>
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-comment">// import the format function from its URL</span>
<span class="hljs-keyword">import</span> { format } <span class="hljs-keyword">from</span> <span class="hljs-string">"https://deno.land/std@0.88.0/datetime/mod.ts"</span>;

<span class="hljs-comment">// capitalize the function name so it's recognized as a React component</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">DateImport</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// Here, directly calling the format function works as expected.</span>
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">section</span>&gt;</span>Hello all! Today is: {format(new Date(), "dd-MM-yyyy")}<span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span></span>;
}
</code></pre>
<p>To see the output of this file, go to <a target="_blank" href="http://localhost:8080/date-import">localhost:8080/date-import</a>, or its equivalent for your server. You should see the page displaying today's date.</p>
<h3 id="heading-2-how-to-import-libraries-from-npm">2. How to Import Libraries from NPM</h3>
<p>To import an npm library, you can also import directly from a URL – but in this case there's a slight change. Since we talked about <a target="_blank" href="http://esm.sh">esm.sh</a> and skypack.dev, let's try to use them in action. In this case, let's try to use the <a target="_blank" href="https://www.npmjs.com/package/dayjs">dayjs</a> library in our project.</p>
<blockquote>
<p>Note: Not all npm libraries work correctly in Deno because they may be relying on Node-specific functions.</p>
</blockquote>
<p>To import a library in <a target="_blank" href="http://esm.sh">esm.sh</a>, you post-pend the library's package name to the URL. In this case to import dayjs, we would be importing <a target="_blank" href="https://esm.sh/dayjs"><code>https://esm.sh/dayjs</code></a>. This also works for any CSS files you might want to import from a library.</p>
<p>Now, let's create a file in <code>pages</code> called <code>dayjs-import.tsx</code>. So, the code in our page will look like this:</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// react is a compulsoy import in Aleph</span>
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-comment">// import the dayjs npm library using esm.sh</span>
<span class="hljs-keyword">import</span> dayjs <span class="hljs-keyword">from</span> <span class="hljs-string">"https://esm.sh/dayjs"</span>;

<span class="hljs-comment">// capitalize the function name so it's recognized as a React component</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">DateImport</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// call the dayjs function directly to display today's date</span>
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">section</span>&gt;</span>Hello all! Today is: {dayjs().format("DD-MM-YYYY")}<span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span></span>;
}
</code></pre>
<p>To see the output of this file, go to <a target="_blank" href="http://localhost:8080/dayjs-import">localhost:8080/dayjs-import</a>, or its equivalent for your server. You should see the page displaying the day's date.</p>
<p>There's one important thing before we go ahead, though – how do you handle <strong>React imports</strong> like importing <code>useState</code>, <code>useEffect</code>, and so on? Luckily, the devs at Aleph have already written an example for us.</p>
<p>Go into <code>./lib/useCounter.ts</code> and you'll find the code for the custom hook that's used for the counter in the home page.</p>
<p>Since I want to focus on Aleph and React themselves in this article, to check out all the different ways you can import a CSS file in Aleph, visit <a target="_blank" href="https://alephjs.org/docs/basic-features/built-in-css-support">this page from the official documentation</a>.</p>
<h2 id="heading-how-to-build-a-sample-app-with-deno-and-alephjs">How to Build a Sample App with Deno and AlephJS</h2>
<p>Now, let's get into the nitty gritty and try to build a React app in Aleph ourselves. We're going to be building "Is It Down?", a sample app I had made using an existing website-checking API. This app will allow us to check whether a website is currently up or down.</p>
<p>Here's the CodeSandbox link: <a target="_blank" href="https://codesandbox.io/s/awesome-firefly-5dofg">https://codesandbox.io/s/awesome-firefly-5dofg</a></p>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codesandbox.io/embed/awesome-firefly-5dofg?fontsize=14&amp;hidenavigation=1&amp;theme=dark&amp;view=preview" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodeSandbox embed" allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin" loading="lazy"></iframe></div>
<p> </p>
<p>Building this application will show you how to use the State hook, the Effect hook, and how to make API calls in Aleph.</p>
<p>Create a new file called <code>web-checker.tsx</code> in your <code>pages</code> folder. Let's start by just adding the UI elements first. We'll display an <code>h1</code> element with the title, an <code>h2</code> element linking to the API, and a form element to take user input. This is a non-interactive page that just displays the elements.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">fontFamily:</span> "<span class="hljs-attr">sans-serif</span>", <span class="hljs-attr">textAlign:</span> "<span class="hljs-attr">center</span>" }}&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Is it Down?<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>
        Go{" "}
        <span class="hljs-tag">&lt;<span class="hljs-name">a</span>
          <span class="hljs-attr">href</span>=<span class="hljs-string">"https://rapidapi.com/jakash1997/api/website-data-gathering-and-update-tracking"</span>
          <span class="hljs-attr">target</span>=<span class="hljs-string">"_blank"</span>
        &gt;</span>
          here
        <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>{" "}
        to get an API key
      <span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">form</span>
        <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{(e)</span> =&gt;</span> {
          e.preventDefault();
        }}
      &gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
          <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
        /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>Next, to capture the state of the input field, and also to capture the response of the API call we will have to make, let's introduce state.</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// import useState from react</span>
<span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">// define both state variables</span>
  <span class="hljs-keyword">const</span> [siteURL, setUrl] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [response, setResponse] = useState(<span class="hljs-literal">undefined</span>);
...
</code></pre>
<p>Now, we'll use this state inside our input element so it can react to it.</p>
<pre><code class="lang-jsx">...
&lt;input
  value={siteURL}
  onChange={<span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> setUrl(e.target.value)}
  type=<span class="hljs-string">"text"</span>
/&gt;
...
</code></pre>
<p>We'll also add some code to display a response when it's returned from the API response:</p>
<pre><code class="lang-jsx">...
    &lt;/form&gt;

    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span></span>

    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">code</span>&gt;</span>{JSON.stringify(response, null, 2)}<span class="hljs-tag">&lt;/<span class="hljs-name">code</span>&gt;</span></span>
&lt;/div&gt;
...
</code></pre>
<p>Now, to get started with integrating the API, let's try to form the request correctly. In this case, the API is a simple <code>GET</code> call, so we only need to pass a param and an API key.</p>
<p>Firstly, go here, and generate an API key: <a target="_blank" href="https://rapidapi.com/jakash1997/api/website-data-gathering-and-update-tracking">https://rapidapi.com/jakash1997/api/website-data-gathering-and-update-tracking</a>. Find the API key like you see in the screenshot below, and keep it somewhere safe:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screenshot_2021-03-08_at_3.47.01_PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Next, let's create a separate function <code>submitData</code> which will generate the required request data. We will be using the <code>axios</code> library to make our <code>GET</code> call, so we will be forming its options object.</p>
<pre><code class="lang-jsx">...
const [response, setResponse] = useState(<span class="hljs-literal">undefined</span>);

<span class="hljs-keyword">const</span> submitData = <span class="hljs-function">(<span class="hljs-params">siteURL</span>) =&gt;</span> {
  setResponse(<span class="hljs-string">"Loading..."</span>);
  <span class="hljs-keyword">const</span> options = {
        <span class="hljs-comment">// passing siteURL here through object shorthand</span>
    <span class="hljs-attr">params</span>: { siteURL },

        <span class="hljs-comment">// passing the required headers here</span>
    <span class="hljs-attr">headers</span>: {
      <span class="hljs-string">"x-rapidapi-key"</span>: <span class="hljs-string">"YOUR_API_KEY"</span>,
      <span class="hljs-string">"x-rapidapi-host"</span>:
        <span class="hljs-string">"website-data-gathering-and-update-tracking.p.rapidapi.com"</span>,
    },
  };

    <span class="hljs-comment">// print options here</span>
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"options"</span>, options);
};

<span class="hljs-keyword">return</span> (
...
</code></pre>
<p>And we add this to the <code>onSubmit</code> function in our form.</p>
<pre><code class="lang-jsx">onSubmit={<span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
  e.preventDefault();
  submitData(siteURL);
}}
</code></pre>
<p>Now, whenever you press the Submit button, you will see the <code>options</code> we generated in the console. If you see the <code>options</code> object in the console, you're doing well so far!</p>
<p>Next we just have the simple step of importing the <code>axios</code> library using <a target="_blank" href="http://esm.sh"><code>http://esm.sh</code></a> and using it to make an API call.</p>
<p>Import <code>axios</code> after the <code>react</code> import like this:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"https://esm.sh/axios"</span>;

...
</code></pre>
<p>And use it in the <code>submitData</code> function as:</p>
<pre><code class="lang-jsx">...
    axios
    .get(
      <span class="hljs-string">"https://website-data-gathering-and-update-tracking.p.rapidapi.com/sitecheck"</span>,
      options
    )
    .then(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">response</span>) </span>{
      setResponse(response.data);
      <span class="hljs-built_in">console</span>.log(response.data);
    })
    .catch(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">error</span>) </span>{
      <span class="hljs-built_in">console</span>.error(error);
    });
};
...
</code></pre>
<p>And that's it! Try submitting the form again, and this time you'll see the result both on screen and in the console.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Now you know the basics of Aleph. It's a really interesting tool which allows you to mix your existing React knowledge with the forward-looking nature and security of <a target="_blank" href="http://deno.land">deno.land</a>.</p>
<p>If you liked this tutorial, you can follow me on Twitter <a target="_blank" href="http://twitter.com/thewritingdev">@thewritingdev</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ A Better Way to Structure React Projects ]]>
                </title>
                <description>
                    <![CDATA[ Hello, everyone! A lot of e-ink has already been spilt on the relatively easier pickings of “Doing X in React” or “Using React with technology X”. So instead, I want to talk about the experiences I've had building frontends from scratch at DelightCha... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/a-better-way-to-structure-react-projects/</link>
                <guid isPermaLink="false">66d45d59a3a4f04fb2dd2e2b</guid>
                
                    <category>
                        <![CDATA[ Code Quality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Akash Joshi ]]>
                </dc:creator>
                <pubDate>Tue, 02 Feb 2021 22:54:52 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/02/z02wxvp94dwg84c4ifhj.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Hello, everyone! A lot of e-ink has already been spilt on the relatively easier pickings of “Doing X in React” or “Using React with technology X”.</p>
<p>So instead, I want to talk about the experiences I've had building frontends from scratch at <a target="_blank" href="https://delightchat.io/">DelightChat</a> and at my previous companies.</p>
<p>These projects require a deeper understanding of React and extended usage in a production setting.</p>
<p>If you want to watch a video version of this tutorial to supplement your reading, <a target="_blank" href="https://www.youtube.com/watch?v=lViIdphWTwY">you can do so here</a>.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/lViIdphWTwY" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<h2 id="heading-introduction">Introduction</h2>
<p>In a nutshell, a complex React project should be structured like this. Although I use NextJS in production, this file structure should be quite useful in any React setting.</p>
<pre><code class="lang-javascript">src
|---adapters
|---contexts
|---components
|---styles
|---pages
</code></pre>
<p><em>Note: In the above file structure, the assets or static files should be placed in whatever the variant of</em> <code>public *</code> <em>folder for your framework is.</em></p>
<p>For each of the above folders, let’s discuss them in order of precedence.</p>
<h2 id="heading-1-adapters">1. Adapters</h2>
<p><code>Adapters</code> are the connectors of your application with the outside world. Any form of API call or websocket interaction which needs to happen, to share data with an external service or client, should happen within the adapter itself.</p>
<p>There are cases where some data is always shared between all the adapters – for example, sharing of cookies, base URL and headers across your AJAX (XHR) adapters. These can be initialized in the xhr folder, and then imported inside of your other adapters to be used further.</p>
<p>This structure will look like this:</p>
<pre><code class="lang-javascript">adapters
|---xhr
|---page1Adapter
|---page2Adapter
</code></pre>
<p>In the case of axios, you can use <code>axios.create</code> to create a base adapter, and either export this initialized instance, or create different functions for get, post, patch and delete to abstract it further. This would look like this:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// adapters/xhr/index.tsx</span>

<span class="hljs-keyword">import</span> Axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">returnAxiosInstance</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> Axios.create(initializers);
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">get</span>(<span class="hljs-params">url</span>)</span>{
  <span class="hljs-keyword">const</span> axios = returnAxiosInstance();
  <span class="hljs-keyword">return</span> axios.get(url);
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">post</span>(<span class="hljs-params">url, requestData</span>)</span>{
  <span class="hljs-keyword">const</span> axios = returnAxiosInstance();
  <span class="hljs-keyword">return</span> axios.post(url, requestData);
}

... and so on ...
</code></pre>
<p>After you have your base file (or files) ready, create a separate adapter file for each page, or each set of functionalities, depending on how complex your app is. A well-named function makes it very easy to understand what each API call does and what it should accomplish.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// adapters/page1Adapter/index.tsx</span>

<span class="hljs-keyword">import</span> { get, post } <span class="hljs-keyword">from</span> <span class="hljs-string">"adapters/xhr"</span>;
<span class="hljs-keyword">import</span> socket <span class="hljs-keyword">from</span> <span class="hljs-string">"socketio"</span>;

<span class="hljs-comment">// well-named functions</span>
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getData</span>(<span class="hljs-params"></span>)</span>{
  <span class="hljs-keyword">return</span> get(someUrl);
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setData</span>(<span class="hljs-params">requestData</span>)</span>{
  <span class="hljs-keyword">return</span> post(someUrl, requestData);
}

... and so on ...
</code></pre>
<p>But how will these adapters be of any use? Let’s find out in the next section.</p>
<h2 id="heading-2-components">2. Components</h2>
<p>Although in this section we should talk about contexts, I want to talk about components first. This is to understand why context is required (and needed) in complex applications.</p>
<p><code>Components</code> are the life-blood of your application. They will hold the UI for your application, and can sometimes hold the Business Logic and also any State which has to be maintained.</p>
<p>In case a component becomes too complex to express Business Logic with your UI, it is good to be able to split it into a separate bl.tsx file, with your root index.tsx importing all of the functions and handlers from it.</p>
<p>This structure would look like this:</p>
<pre><code class="lang-javascript">components
|---page1Components
        |--Component1
        |--Component2
|---page2Component
        |--Component1
               |---index.tsx
               |---bl.tsx
</code></pre>
<p>In this structure, each page gets its own folder inside of components, so that it’s easy to figure out which component affects what.</p>
<p>It’s also important to limit the scope of a component. Hence, a component should only use <code>adapters</code> for data-fetching, have a separate file for complex Business Logic, and only focus on the UI part.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// components/page1Components/Component1/index.tsx</span>

<span class="hljs-keyword">import</span> businessLogic <span class="hljs-keyword">from</span> <span class="hljs-string">"./bl.tsx"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Component2</span>(<span class="hljs-params"></span>) </span>{

  <span class="hljs-keyword">const</span> { state and functions } = businessLogic();

  <span class="hljs-keyword">return</span> {
    <span class="hljs-comment">// JSX</span>
  }
}
</code></pre>
<p>While the BL file only imports data and returns it:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// components/page1Components/Component1/bl.tsx</span>

<span class="hljs-keyword">import</span> React, {useState, useEffect} <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { adapters } <span class="hljs-keyword">from</span> <span class="hljs-string">"adapters/path_to_adapter"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Component1Bl</span>(<span class="hljs-params"></span>)</span>{
  <span class="hljs-keyword">const</span> [state, setState] = useState(initialState);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    fetchDataFromAdapter().then(updateState);
  }, [])
}
</code></pre>
<p>However, there’s a problem which is common across all complex apps. State Management, and how to share state across distant components. For example, consider the following file structure:</p>
<pre><code class="lang-javascript">components
|---page1Components
        |--Component1
               |---ComponentA
|---page2Component
        |--ComponentB
</code></pre>
<p>If some state has to be shared across ComponentA and B in the above example, it will have to be passed through all the intermediate components, and also to any other components who want to interact with the state.</p>
<p>To solve this, their are several solutions which can be used like Redux, Easy-Peasy, and React Context, each of them having their own pros and cons. Generally, React Context should be “good enough” to solve this problem. We store all of the files related to context in <code>contexts</code>.</p>
<h2 id="heading-3-contexts">3. Contexts</h2>
<p>The <code>contexts</code> folder is a bare minimum folder only containing the state which has to be shared across these components. Each page can have several nested contexts, with each context only passing the data forward in a downward direction. But to avoid complexity, it is best to only have a single context file. This structure will look like this:</p>
<pre><code class="lang-javascript">contexts
|---page1Context
        |---index.tsx (Exports consumers, providers, ...)
        |---Context1.tsx (Contains part <span class="hljs-keyword">of</span> the state)
        |---Context2.tsx (Contains part <span class="hljs-keyword">of</span> the state)
|---page2Context
        |---index.tsx (Simple enough to also have state)
</code></pre>
<p>In the above case, since <code>page1</code> may be a bit more complex, we allow some nested context by passing the child context as a child to the parent. However, generally a single <code>index.tsx</code> file containing state and exporting relevant files should be enough.</p>
<p>I won’t go into the implementation part of React state management libraries since each of them are their own beasts and have their own upsides and downsides. So, I recommend going through the tutorial of whatever you decide to use to learn their best practises.</p>
<p>The context is allowed to import from <code>adapters</code> to fetch and react to external effects. In case of React Context, the providers are imported inside pages to share state across all components, and something like <code>useContext</code> is used inside these <code>components</code> to be able to utilize this data.</p>
<p>Moving on to the final major puzzle-piece, <code>pages</code>.</p>
<h2 id="heading-4-pages">4. Pages</h2>
<p>I want to avoid being biased to a framework for this piece, but in general, having a specific folder for route-level components to be placed is a good practise.</p>
<p>Gatsby &amp; NextJS enforce having all routes in a folder named <code>pages</code>. This is quite a readable way of defining route-level components, and mimicking this in your CRA-generated application would also result in better code readability.</p>
<p>A centralized location for routes also helps you utilize the “Go To File” functionality of most IDEs by jumping to a file by using (Cmd or Ctrl) + Click on an import.</p>
<p>This helps you move through the code quickly and with clarity of what belongs where. It also sets a clear hierarchy of differentiation between <code>pages</code> and <code>components</code>, where a page can import a component to display it and do nothing else, not even Business Logic.</p>
<p>However, it’s possible to import Context Providers inside of your page so the child components can consume it. Or, in the case of NextJS, write some server-side code which can pass data to your components using getServerSideProps or getStaticProps.</p>
<h2 id="heading-5-styles">5. Styles</h2>
<p>Finally, we come to styles. Although my go-to way is to just embed styles inside of the UI by using a CSS-in-JS solution like Styled-Components, it’s sometimes helpful to have a global set of styles in a CSS file.</p>
<p>A plain old CSS file is more shareable across projects, and can also affect the CSS of components which styled-components can’t reach (for example, third-party components).</p>
<p>So, you can store all of these CSS files inside of the <code>styles</code> folder, and import or link to them freely from wherever you wish.</p>
<p>Those were my thoughts. Feel free to email me in case you want to discuss something or have any more inputs on how this can be improved!</p>
<p>For further updates or discussions, you can follow me on Twitter <a target="_blank" href="https://twitter.com/thewritingdev">here</a>.</p>
<p>My last article on freeCodeCamp was written on how you can get started with Deno by building a URL shortener, which <a target="_blank" href="https://www.freecodecamp.org/news/build-a-url-shortener-in-deno/">you can read here</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a URL Shortener in Deno ]]>
                </title>
                <description>
                    <![CDATA[ In this article, we’re going to learn the basics of Deno, like how to run a program and embrace security. Deno is the new JavaScript and TypeScript runtime written in Rust. It offers tight security, TypeScript support out-of-the-box, a single executa... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-url-shortener-in-deno/</link>
                <guid isPermaLink="false">66d45d5b246e57ac83a2c6f9</guid>
                
                    <category>
                        <![CDATA[ Deno ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ TypeScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Akash Joshi ]]>
                </dc:creator>
                <pubDate>Wed, 07 Oct 2020 15:40:28 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9848740569d1a4ca192c.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, we’re going to learn the basics of Deno, like how to run a program and embrace security.</p>
<p>Deno is the new JavaScript and TypeScript runtime written in Rust. It offers tight security, TypeScript support out-of-the-box, a single executable to run it, and a set of reviewed and audited standard modules.</p>
<p>Like <a target="_blank" href="https://npmjs.com">npm</a> in Node.js, packages in Deno are managed in a centralized package repository called <a target="_blank" href="https://deno.land/x/">X</a>. We'll be using one of these libraries, Oak, to build a REST API-based server in Deno.</p>
<p>After learning the basics by using the Express-like router package <a target="_blank" href="https://deno.land/x/oak@v6.3.0">Oak</a>, we will jump into the deep end of Deno and build a complete application.</p>
<p>Here's what we will set up in this application:</p>
<ol>
<li><p>Mapping URL shortcodes to endpoints using a JSON-based config file.</p>
</li>
<li><p>Have expiration dates attached to each URL so that these redirects are only valid for a limited period of time.</p>
</li>
</ol>
<h2 id="heading-0-prerequisites">0. Prerequisites</h2>
<ol>
<li><p>Install Deno from <a target="_blank" href="https://deno.land/#installation">this link</a>.</p>
</li>
<li><p>Make sure you know the basics of JavaScript.</p>
</li>
</ol>
<p>Although not really required to follow along with this article, you can check out the YouTube video below to get an intro to Deno in video-format.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/VQ8Jb7GLHgk" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>So, let’s get started. ?</p>
<h2 id="heading-1-how-to-build-the-router">1. How to Build the Router</h2>
<p>To write the server-side code for our application, we'll use the Oak module. It has an Express-like syntax for defining API routes.</p>
<p>If we look at its <a target="_blank" href="https://deno.land/x/oak">documentation here</a>, the "<a target="_blank" href="https://deno.land/x/oak#basic-usage">Basic Usage</a>" section pretty much covers all the use cases we will need in our router. So, we will expand on that code to build our application.</p>
<p>To test this code, you can create a file called <code>index.ts</code> in a folder, and copy the "Basic Usage" code into it.</p>
<p>To understand how to run TypeScript or JavaScript files in Deno, you first need to understand how Deno runs files.</p>
<p>You run a file by running the command <code>deno run file_name.ts</code> or <code>file_name.js</code>, followed by a set of flags providing certain system permissions to your application.</p>
<p>To test this, run the file we just created, containing the "Basic Usage" code, by using the command <code>deno run index.ts</code>.</p>
<p>You will see that Deno complains that you haven't given network access to your application. So, to do that, you add the <code>-allow-net</code> to the run command. The command will look like <code>deno run index.ts -allow-net</code>.</p>
<p>The router written down in the "Basic Usage” code looks like this:</p>
<pre><code class="lang-jsx">router
  .get(<span class="hljs-string">"/"</span>, <span class="hljs-function">(<span class="hljs-params">context</span>) =&gt;</span> {
    context.response.body = <span class="hljs-string">"Hello world!"</span>;
  })
  .get(<span class="hljs-string">"/book"</span>, <span class="hljs-function">(<span class="hljs-params">context</span>) =&gt;</span> {
    context.response.body = <span class="hljs-built_in">Array</span>.from(books.values());
  })
  .get(<span class="hljs-string">"/book/:id"</span>, <span class="hljs-function">(<span class="hljs-params">context</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (context.params &amp;&amp; context.params.id &amp;&amp; books.has(context.params.id)) {
      context.response.body = books.get(context.params.id);
    }
  });
</code></pre>
<p>To break down the above code, first a <code>router</code> object has been defined. Then the <code>get</code> function is called on the router, to define the various endpoints for our application. The respective logic is defined inside the callback functions.</p>
<p>For example, for the "/" endpoint, a callback function which returns "Hello World" in the response body has been defined. We can keep this endpoint unchanged to test whether our application server is running by receiving this response.</p>
<p>We don’t need the “/book” URL which has been defined, so its definition can be safely removed. At this point, your router should have the below structure:</p>
<pre><code class="lang-javascript">router
  .get(<span class="hljs-string">"/"</span>, <span class="hljs-function">(<span class="hljs-params">context</span>) =&gt;</span> {
    context.response.body = <span class="hljs-string">"Hello world!"</span>;
  })
  .get(<span class="hljs-string">"/book/:id"</span>, <span class="hljs-function">(<span class="hljs-params">context</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (context.params &amp;&amp; context.params.id &amp;&amp; books.has(context.params.id)) {
      context.response.body = books.get(context.params.id);
    }
  });
</code></pre>
<p>In the next section, we'll be focussing on starting to build the actual application.</p>
<h2 id="heading-2-how-to-build-the-url-shortener">2. How to Build the URL Shortener</h2>
<p>Now let's get started with building the actual URL shortener.</p>
<p>It should redirect to a destination (<code>dest</code>), based on a <code>shortcode</code>. The redirect should also only be valid up to an <code>expiryDate</code>, which can be provided in the Year-Month-Day format.</p>
<p>Based on these assumptions, let's create the config file, named <code>urls.json</code>. The format of the file will be:</p>
<pre><code class="lang-jsx">{
  <span class="hljs-string">"shortcode"</span>: {
    <span class="hljs-string">"dest"</span>: <span class="hljs-string">"destination_url_string"</span>,
    <span class="hljs-string">"expiryDate"</span>: <span class="hljs-string">"YYYY-MM-DD"</span>
  }
}
</code></pre>
<p>You can <a target="_blank" href="https://github.com/akash-joshi/deno-url-shortener/blob/master/urls.json">check out the JSON file here</a>.</p>
<p>To read this JSON file in your code, add the following to the top of your <code>index.ts</code>:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { Application, Router } <span class="hljs-keyword">from</span> <span class="hljs-string">"&lt;https://deno.land/x/oak/mod.ts&gt;"</span>;

<span class="hljs-keyword">const</span> urls = <span class="hljs-built_in">JSON</span>.parse(Deno.readTextFileSync(<span class="hljs-string">"./urls.json"</span>));

<span class="hljs-built_in">console</span>.log(urls);
</code></pre>
<p>Now, to run your <code>index.ts</code>, you will need another flag <code>—allow-read</code>, otherwise Deno will throw a "read permissions not provided" error. Your final command becomes <code>deno run —allow-net —allow-read index.ts</code>.</p>
<p>After running this command, you'll see the JSON file being printed in your terminal window. This means that your program is able to read the JSON file correctly.</p>
<p>If we go back to the "Basic Usage" example that we saw above, the route “/book/:id” is exactly what we need.</p>
<p>Instead of "/book/:id", we can use "/shrt/:urlid", where we will get the individual URLs based on the URL ID (<code>:urlid</code>).</p>
<p>Replace the existing code present inside the "/book/:id" route with this:</p>
<pre><code class="lang-jsx">.get(<span class="hljs-string">"/shrt/:urlid"</span>, <span class="hljs-function">(<span class="hljs-params">context</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (context.params &amp;&amp; context.params.urlid &amp;&amp; urls[context.params.urlid]) {
      context.response.redirect(urls[context.params.urlid].dest);
    } <span class="hljs-keyword">else</span> {
      context.response.body = <span class="hljs-string">"404"</span>;
    }
  });
</code></pre>
<p>The <code>if</code> condition in the route does the following:</p>
<ol>
<li><p>Checks if parameters are attached to the route</p>
</li>
<li><p>Checks if the parameter <code>urlid</code> is in the parameter list.</p>
</li>
<li><p>Checks whether the <code>urlid</code> matches with any URL in our JSON.</p>
</li>
</ol>
<p>If it matches with all these, the user is redirected to the correct URL. If it doesn't, a 404 response on the body is returned.</p>
<p>To test this, copy this route into <code>index.ts</code>. The router will now look like this:</p>
<pre><code class="lang-jsx">router
  .get(<span class="hljs-string">"/"</span>, <span class="hljs-function">(<span class="hljs-params">context</span>) =&gt;</span> {
    context.response.body = <span class="hljs-string">"Hello world!"</span>;
  })
    .get(<span class="hljs-string">"/shrt/:urlid"</span>, <span class="hljs-function">(<span class="hljs-params">context</span>) =&gt;</span> {
        <span class="hljs-keyword">if</span> (context.params &amp;&amp; context.params.urlid &amp;&amp; urls[context.params.urlid]) {
          context.response.redirect(urls[context.params.urlid].dest);
        } <span class="hljs-keyword">else</span> {
          context.response.body = <span class="hljs-string">"404"</span>;
        }
      });
</code></pre>
<p>And run the file using <code>deno run —allow-net —allow-read index.ts</code>.</p>
<p>If you copied the JSON file from the example, and if you go to <code>http://localhost:8000/shrt/g</code>, you'll be redirected to Google's homepage.</p>
<p>On the other hand, if you use a random shortcode that doesn't work in our URL's config, it brings you to the 404 page.</p>
<p>However, you'll see that our shortener doesn't react live to changes in the JSON file. To test this, try adding a new redirect to <code>urls.json</code> in the same format as:</p>
<pre><code class="lang-javascript"><span class="hljs-string">"shortcode"</span>: {
    <span class="hljs-string">"dest"</span>: <span class="hljs-string">"destination_url_string"</span>,
    <span class="hljs-string">"expiryDate"</span>: <span class="hljs-string">"YYYY-MM-DD"</span>
  }
</code></pre>
<p>The reason for this is that <code>urls.json</code> is only read once at that start. So, now we will add live-reloading to our server.</p>
<h2 id="heading-3-how-to-add-live-reloading">3. How to Add Live-Reloading</h2>
<p>To make the <code>urls</code> object react live to changes in the JSON file, we simply move the read statement inside our route. This should look like the following:</p>
<pre><code class="lang-jsx">.get(<span class="hljs-string">"/shrt/:urlid"</span>, <span class="hljs-function">(<span class="hljs-params">context</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> urls = <span class="hljs-built_in">JSON</span>.parse(Deno.readTextFileSync(<span class="hljs-string">"./urls.json"</span>));

  <span class="hljs-keyword">if</span> (context.params &amp;&amp; context.params.urlid &amp;&amp; urls[context.params.urlid]) {
    context.response.redirect(urls[context.params.urlid].dest);
  } <span class="hljs-keyword">else</span> {
    context.response.body = <span class="hljs-string">"404"</span>;
  }
});
</code></pre>
<p>Note how we have moved the URLs object inside our router. Now in this case, the config file is read every time that route is called, so it can react live to any changes made in the <code>urls.json</code> file. So even if we add or remove other redirects on the fly, our code reacts to it.</p>
<h2 id="heading-4-how-to-add-an-expiration-to-the-urls">4. How to Add an Expiration to the URLs</h2>
<p>To make our URLs expire at a certain date, we will be using the popular Moment.js library, which makes it easy to work with dates.</p>
<p>Luckily, it has also been <a target="_blank" href="https://deno.land/x/moment">ported for Deno</a>. To understand how it works, check out its documentation in the previous link.</p>
<p>To use it in our code, import it directly through its URL like this:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { Application, Router } <span class="hljs-keyword">from</span> <span class="hljs-string">"&lt;https://deno.land/x/oak/mod.ts&gt;"</span>;
<span class="hljs-keyword">import</span> { moment } <span class="hljs-keyword">from</span> <span class="hljs-string">"&lt;https://deno.land/x/moment/moment.ts&gt;"</span>;

<span class="hljs-keyword">const</span> router = <span class="hljs-keyword">new</span> Router();
</code></pre>
<p>To check the date for when the URL will expire, we check the <code>expiryDate</code> key on our <code>urls</code> object. This will make the code look like this:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">if</span> (context.params &amp;&amp; context.params.urlid &amp;&amp; urls[context.params.urlid]) {
  <span class="hljs-keyword">if</span> (
    urls[context.params.urlid].expiryDate &gt; moment().format(<span class="hljs-string">"YYYY-MM-DD"</span>)
  ) {
    context.response.redirect(urls[context.params.urlid].dest);
  } <span class="hljs-keyword">else</span> {
    context.response.body = <span class="hljs-string">"Link Expired"</span>;
  }
} <span class="hljs-keyword">else</span> {
  context.response.body = <span class="hljs-string">"404"</span>;
}
</code></pre>
<p>In <code>moment().format("YYYY-MM-DD")</code>, we get the current date and time using <code>moment()</code>. We can convert it to the "YYYY-MM-DD" (Year-Month-Date) format using the function <code>.format("YYYY-MM-DD")</code>.</p>
<p>By comparing it against our <code>expiryDate</code> key, we can check whether the URL has expired or not.</p>
<p>That's it! You have built a fully functional URL shortener in Deno. You can find the final code <a target="_blank" href="https://github.com/akash-joshi/deno-url-shortener">in the GitHub repo here</a>.</p>
<p>Test it out by setting <code>expiryDate</code> as the current date and by making other changes to <code>urls.json</code> and our code.</p>
<h3 id="heading-my-thoughts-on-deno">My Thoughts on Deno</h3>
<p>To wrap the article up, I'll put my forward final thoughts on deno.land.</p>
<p>While it's refreshing to see a server-side language which takes security into consideration and supports TypeScript out-of-the-box, Deno still has a long way to go before being ready for use in production systems.</p>
<p>For example, the TypeScript compilation is still very slow, with compilation times ~20 seconds, even for simple programs like the one we just developed.</p>
<p>On the error-reporting front, it still is pretty bad with describing the errors. For example, while embedding the code to read <code>urls.json</code> in the function itself, Deno isn't able to report that the <code>-allow-read</code> flag hasn't been set. Instead, it just throws an internal server error without a proper error printed on the terminal.</p>
<h3 id="heading-what-next">What Next?</h3>
<p>You can improve your Deno or Typescript skills by building more complex applications like a <a target="_blank" href="https://css-tricks.com/build-a-chat-app-using-react-hooks-in-100-lines-of-code/">Chatting Application</a> or a <a target="_blank" href="https://auth0.com/blog/building-a-wikipedia-app-using-react-hooks-and-auth0/">Wikipedia Clone</a>.</p>
<p>You can also go through the Deno documentation at <a target="_blank" href="http://deno.land/">deno.land</a> to get more familiar with the basics.</p>
<p>Thank you for reading this far and happy programming ? !!</p>
<h3 id="heading-important-links">Important Links</h3>
<p>Deno - https://deno.land<br>Deno X (package repository) - https://deno.land/x/<br>Oak (REST framework) - <a target="_blank" href="https://deno.land/x/oak">https://deno.land/x/oak</a><br>Oak Basic Usage - <a target="_blank" href="https://deno.land/x/oak@v6.3.1#basic-usage">https://deno.land/x/oak@v6.3.1#basic-usage</a><br>Final GitHub Repo - <a target="_blank" href="https://github.com/akash-joshi/deno-url-shortener">https://github.com/akash-joshi/deno-url-shortener</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Alexa and Google Home: How to Build your own Voice Apps and Deploy Them to Millions of Devices Around the World ]]>
                </title>
                <description>
                    <![CDATA[ Voice apps completely change the way we interact with the digital world. Voice adds another dimension to human-computer interaction that developers are only beginning to explore. In this article, I will show you how you can use your existing backend ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/creating-deploying-voice-apps-for-alexa-google/</link>
                <guid isPermaLink="false">66d45d5fc17d4b8ace5b9eb0</guid>
                
                    <category>
                        <![CDATA[ Alexa Skills ]]>
                    </category>
                
                    <category>
                        <![CDATA[ google home ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Akash Joshi ]]>
                </dc:creator>
                <pubDate>Mon, 12 Aug 2019 22:03:57 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/08/4x3-2.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Voice apps completely change the way we interact with the digital world. Voice adds another dimension to human-computer interaction that developers are only beginning to explore.</p>
<p>In this article, I will show you how you can use your existing backend architecture &amp; APIs, connecting them with your voice apps to offer a new experience to your customers. Voice apps borrow a lot from our general development process, not requiring separate development resources.</p>
<h1 id="heading-what-we-are-building">What we are building</h1>
<p>We are going to build a superhero search app using the <a target="_blank" href="https://akabab.github.io/superhero-api/api/all.json">Open Source Superhero API</a>.</p>
<p>I have added a wrapper around this API to make it accessible from our Voice App. You can find the code in this gist - <a target="_blank" href="https://gist.github.com/akash-joshi/476ead410a244a48e037c138ba2387b0">https://gist.github.com/akash-joshi/476ead410a244a48e037c138ba2387b0</a>.</p>
<p>Take a look at the completed app below:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/5F20v5cIQts" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>We will build this for Voice apps (Alexa and Google). We will be using the platform <a target="_blank" href="http://voiceflow.com">VoiceFlow</a>, which allows us to build voice apps visually.</p>
<h1 id="heading-voiceflow-tutorial">Voiceflow Tutorial</h1>
<p>VoiceFlow is a visual way to create voice apps, and is very easy to use and understand.</p>
<p>Firstly, create an account there to get started.</p>
<p>After creating an account, create a new project, giving it an appropriate name. For the purpose of this tutorial, we have chosen all English regions as deployment regions.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/08/FCC_1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You will end up on a blank canvas after this. Don't be overwhelmed by all the options present on the screen, this tutorial will guide you through all the relevant blocks required.</p>
<p>In the blocks submenu on the left, you will see several blocks which can be used to build an Alexa or Google skill. Each block performs a certain function, and Voiceflow is based on building Voice apps by combining these blocks.</p>
<h3 id="heading-1-speak-block">1. Speak Block</h3>
<p>The first block that we will use is the Speak Block. We will use it to make Alexa say something to the user. Drag a speak blog onto the canvas, rename it to Introduction and write a suitable introduction to your app in the text area. I will use "Welcome to Superhero! Say the name of a hero to search!".</p>
<p>At any point, test out your app by clicking on the Play Button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/08/FCC_2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-2-capture-block">2. Capture Block</h3>
<p>The next block we will use is the Capture block. It is used to capture data from the user's voice and store it into a variable.</p>
<p>Firstly, create a new variable in the 'Variables' submenu on the left by typing a name and pressing enter. Use the name 'hero' for now.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/08/FCC_3.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Adding a capture block, name "Input Type" as "Actor" and "Capture input To" as "hero".</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/08/FCC_4.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Add a speech block after it, saying : "Searching for {hero}. ". We use curly brackets to use a variable in speech. Be sure to enter {hero} by hand so that Voiceflow detects it as a variable. The is a tag which is part of a language called Speech Synthesis Markup Language (SSML). You can read more about it on Amazon's <a target="_blank" href="https://developer.amazon.com/docs/custom-skills/speech-synthesis-markup-language-ssml-reference.html">official documentation page.</a></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/08/FCC_5.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-3-api-block">3. API Block</h3>
<p>Click on the Plus icon below your Speak block to add another step to the block. Add an Integration block from the list. After that, click on the integration block &amp; set up the options in this order:</p>
<ol>
<li>Choose an integration - "Custom API" since we will be using a custom API to get some data.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/08/FCC_6.png" alt="Image" width="600" height="400" loading="lazy"></p>
<ol start="2">
<li>I want to - "Make a GET request" since we are using a GET request to get JSON data from an API.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/08/FCC_7.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We will use a custom API (<code>https://super-search-akashjoshi.flexiple.now.sh/?hero=</code>)to get the superhero data.</p>
<p>Try navigating to <code>https://super-search-akashjoshi.flexiple.now.sh/?hero=superman</code> in your browser to see what kind of data is returned by the API. Replace <em>superman</em> with any hero that you want to search for.</p>
<p>We replace the hero name with the {hero} variable so that the API fetches the desired hero correctly.</p>
<p>Paste</p>
<p><code>https://super-search-akashjoshi.flexiple.now.sh/?hero={hero}</code></p>
<p>into the URL bar. Be sure to type in {hero} by yourself so that Voiceflow detects it as a variable.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/08/FCC_8.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>However, we aren't done yet. Click on Test Integration to test the API call.</p>
<p>The response from the API has to be mapped into output variables so that they are spoken to the user.</p>
<p>Add variables for name, fullName, born, alignment, work &amp; base from the variables side-bar.</p>
<p>Copy the output path of the JSON file by clicking on the response tab of the Test Integration tab and paste it into the output menu. Do this for all of the following - name, fullName, born, alignment, work &amp; base.</p>
<p>Check the short video below to understand how to map the JSON output with your Voiceflow variables:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/fDY_klt08mg" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/08/FCC_9.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In the image above, we can see that the Integration has 2 outputs, one without a prefix text, and one with fail as prefix. The one without the prefix text is a success state output, and the one with fail output is when our API call fails.</p>
<p>Add a speech block saying 'The hero was not found' connected to the fail state. If the API succeeds and a hero was found matching the {hero} variable, all the output variables will be set with the correct values. Otherwise, they will be to the default value of 0.</p>
<h3 id="heading-4-if-block">4. If Block</h3>
<p>Add an if block to the canvas, and check whether fullName = 0. If it is 0, connect it to the "Not Found" block.</p>
<p>Watch the short video below to understand how to add conditions to If blocks:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/gmS-NleBtl0" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>Else, the hero was found. So, speak the hero name by writing in a speech block: "Their hero name is {name}. Their full name is {fullName}. They were born in {born}. They are {alignment}. They work as a {work} from {base}. Do you want to search another hero?"</p>
<p>Again, be sure to type in the variable names so that Voiceflow detects them as variables.</p>
<p>To clear out the variables after the skill completes, add a "Set" block to the canvas and set fullName to 0. This step is necessary, because if the variables are not cleared, the previous answer will be repeated by the skill!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/08/FCC_11.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-5-choice-block">5. Choice Block</h3>
<p>We shouldn't end the skill here. We should allow the user a choice on whether they want to search for another superhero. Change the text in the "Not Found" block to ask whether the user wants to search for more at the end.</p>
<p>Add a Choice block to the canvas. The choice block allows us to perform certain actions based on user voice. This block checks whether the user wants to search for another hero. Enter synonyms of Yes for searching further.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/08/FCC_11-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>For else, add a Flow block, selecting Stop Flow as a flow.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/08/FCC_12.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Connect the ' 1 ' output of the Choice block to a speech block asking user to say another Hero name, and connect it to the Capture block. Look at the image below to understand how it's done.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/08/FCC_13.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>And we are done! Test out your app by clicking on the play button.</p>
<h3 id="heading-6-deployment">6. Deployment</h3>
<p><strong>a. Alexa</strong></p>
<p>To deploy your app to the Alexa platform, click on the Publish tab, connect your Amazon developer account and fill the form options according to relevance to your skill (like Description, Skill Name, etc.)</p>
<p>Be sure not to change any of the default invocations that may break your skill during deployment and cause you to resubmit it.</p>
<p>In case you get some part wrong while submitting, the review process is very helpful &amp; they will let you know what went wrong in the submission.</p>
<p><strong>b. Google</strong></p>
<p>Click on the instruction link to see <a target="_blank" href="https://learn.voiceflow.com/articles/2705386-uploading-your-project-to-google-assistant">instructions to add the Google Assistant file to Voiceflow</a>. After adding the file, follow the publish to production guide from <a target="_blank" href="https://learn.voiceflow.com/articles/2712178-deploying-your-google-assistant-project-to-production">here</a> . Few caveats in the Google deployment process:</p>
<ol>
<li><p>Your invocation name cannot have any keywords which may be used during invocation. Eg, you cannot name the action 'Superhero Search', because 'Search' may be used as a invocation name.</p>
</li>
<li><p>You need to add a custom privacy policy from Google. You can't use the one from Voiceflow as it has mentions of Alexa or skills, which will cause your action to be declined. You can use a template I built <a target="_blank" href="https://docs.google.com/document/d/1ZdI1m-6Vo46vSTeWs4pG8fDHV1n8McWgcZud3TGN5k0">here</a>. It has instructions on how to write your privacy policy and where to keep it.</p>
</li>
<li><p>The final point would be to not use the term 'Alexa' or 'skill' at any point in your action description or within the app. If there are any occurrences in the app, replace them with something more generic so you can use the same codebase for Alexa &amp; Google. Replace 'Alexa' &amp; 'skill' with 'Google' &amp; 'actions' in the description and similar places.</p>
</li>
</ol>
<h1 id="heading-what-next">What Next?</h1>
<p>App ideas:</p>
<p>The interesting point about voice apps is that you can use them as an extension for your existing apps. For example, If you have already built a messaging app like <a target="_blank" href="https://blog.flexiple.com/build-a-powerful-chat-application-using-react-hooks/">this one</a>, the voice platform can be an easy way of sending and reading messages on your app. For a blog writing platform, a voice app may be an easy way to take notes before actually sitting down to write an article. Even for a product posting platform like <a target="_blank" href="https://producthunt.com">ProductHunt</a> or <a target="_blank" href="https://remote.tools">Remote.tools</a>, you can easily integrate voice to read out description and other details on the products.</p>
<p>In such ways, voice apps can be used to enhance user experience.</p>
<p>Useful links:</p>
<p><a target="_blank" href="https://getvoiceflow.com">https://getvoiceflow.com</a></p>
<p><a target="_blank" href="https://learn.voiceflow.com/articles/2705386-uploading-your-project-to-google-assistant">https://learn.voiceflow.com/articles/2705386-uploading-your-project-to-google-assistant</a></p>
<p><a target="_blank" href="https://learn.voiceflow.com">https://learn.voiceflow.com</a></p>
<p><a target="_blank" href="https://developer.amazon.com/docs/custom-skills/speech-synthesis-markup-language-ssml-reference.html">https://developer.amazon.com/docs/custom-skills/speech-synthesis-markup-language-ssml-reference.html</a></p>
<p>Hope you liked this article. I have also written a <a target="_blank" href="https://blog.flexiple.com/building-a-web-and-voice-app-ecosystem-amazon-alexa-google-home-react-node/">more extensive article</a> which adds a web-based frontend to this app making it a complete ecosystem.</p>
<p>Happy Coding!</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
