<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Luke Frauhiger</title>
    <description>The latest articles on DEV Community by Luke Frauhiger (@lukefrogger).</description>
    <link>https://dev.to/lukefrogger</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%2F5745%2F01df0c4c-2591-429f-9572-7b6badad918c.png</url>
      <title>DEV Community: Luke Frauhiger</title>
      <link>https://dev.to/lukefrogger</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lukefrogger"/>
    <language>en</language>
    <item>
      <title>The Form Builder for Developers</title>
      <dc:creator>Luke Frauhiger</dc:creator>
      <pubDate>Fri, 01 Apr 2022 16:23:17 +0000</pubDate>
      <link>https://dev.to/lukefrogger/the-form-builder-for-developers-5afc</link>
      <guid>https://dev.to/lukefrogger/the-form-builder-for-developers-5afc</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The form building gap&lt;/li&gt;
&lt;li&gt;Fetch Forms intro&lt;/li&gt;
&lt;li&gt;The form building process&lt;/li&gt;
&lt;li&gt;
Code examples

&lt;ul&gt;
&lt;li&gt;Javascript &amp;amp; html&lt;/li&gt;
&lt;li&gt;React example&lt;/li&gt;
&lt;li&gt;React w/custom components&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The problem with current developer form tools
&lt;/h3&gt;

&lt;p&gt;There are lots of form builders and form tools available today. Whether you need to share a simple form with family members, build a complex registration form, or gather payment information, there is a form builder or tool for you. Or is there...I see a gap.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Form backend services&lt;/strong&gt; help JAMstack websites collect form submissions without a server and connect data to 3rd party systems. But you still have to hand build the HTML form and its supporting functions like client-side validation. On top of that, if you want to use the form submissions locally in your code, as well as use a backend service, you can’t!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code libraries&lt;/strong&gt; like Formik and Angular Forms are incredibly helpful for managing form state and validation. You can use your own components and build a high-quality form much quicker than with standard HTML. Unfortunately, you still have to spend time hand-building every single form and its validation rules. You also have to spend time creating a backend to handle form submissions and integrate the data.&lt;/p&gt;



&lt;h4&gt;
  
  
  Forms are too repetitive and time consuming for developers to constantly be hand-building them.
&lt;/h4&gt;



&lt;h3&gt;
  
  
  Fetch Forms
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://fetchforms.io?ref=devto"&gt;fetchforms.io&lt;/a&gt;&lt;br&gt;
That’s why I built Fetch Forms. I wanted the benefits of a form backend service and to be able to build the forms in a form builder that would remove the repetitive aspects.&lt;/p&gt;

&lt;p&gt;The Fetch form builder’s defaults and templates will help you build and collaborate on forms in record time.&lt;/p&gt;

&lt;p&gt;The Fetch API will help you integrate high-quality forms with client-side validation into your application in a matter of minutes.&lt;/p&gt;

&lt;p&gt;Updates are just as easy. Complete your changes and publish them with a single click. All applications using the updated Fetch form will begin to pull the new form.&lt;/p&gt;
&lt;h2&gt;
  
  
  Get started with Fetch Forms
&lt;/h2&gt;

&lt;p&gt;Get the speed of a form builder with the control of code. Here’s how:&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Build
&lt;/h3&gt;

&lt;p&gt;Use the Fetch form builder to create and build your form. It’s packed with templates and defaults to make building forms painless.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select validation rules and input masking&lt;/li&gt;
&lt;li&gt;Choose whether to save submissions to Fetch Forms&lt;/li&gt;
&lt;li&gt;Use form and field templates to build forms in record time
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XBDUYY6_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xq8ohm2ualvd9gwxrz2e.png" alt="Fetch form builder" width="880" height="506"&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  2. Deploy
&lt;/h3&gt;

&lt;p&gt;Deploy your form using any of our NPM modules, the embed script, or by simply using the native fetch API. The possibilities are endless!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install and use the Javascript or React library&lt;/li&gt;
&lt;li&gt;Use the embed script to drop a form into any web-based tool&lt;/li&gt;
&lt;li&gt;Extend your own component library
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--klBPZLoK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/56a8pwjganm83gedb11f.png" alt="A fetch form in code" width="766" height="491"&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  3. Submissions
&lt;/h3&gt;

&lt;p&gt;You don’t have to send submissions to Fetch Forms — all data submitted is available to your local code no matter what.&lt;/p&gt;

&lt;p&gt;If you configured the form to save submissions to the Fetch Forms library, they will be &lt;strong&gt;validated on the server&lt;/strong&gt; and sent through &lt;strong&gt;spam filtering&lt;/strong&gt;. Submissions will then activate any connections you have set up.&lt;/p&gt;



&lt;h2&gt;
  
  
  How about we look at some code?
&lt;/h2&gt;

&lt;p&gt;Using Fetch Forms can be as simple or as complex as you need. The first two examples are using a styled component provided by Fetch Forms. You can also implement a Fetch form with your own component library - see example 3.&lt;/p&gt;

&lt;p&gt;You watch me talk through building and deploying a form in &lt;a href="https://www.fetchforms.io/video-walkthrough"&gt;the walkthrough here&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Simple Javascript &amp;amp; HTML example
&lt;/h3&gt;

&lt;p&gt;See more at &lt;a href="https://www.fetchforms.io/docs/fetch-forms-javascript"&gt;www.fetchforms.io/docs/fetch-forms-javascript&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;main&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"max-width: 600px; margin: auto"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Fetch Forms Javascript&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;hr&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"form_name"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"margin-bottom: 25px"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"fetch_form"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;pre&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"result"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/pre&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script&amp;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;renderForm&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@fetchforms/core&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Called when data is submitted&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onComplete&lt;/span&gt; &lt;span class="o"&gt;=&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="o"&gt;=&amp;gt;&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="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;result&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&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="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="c1"&gt;// Called when the Fetch form is loaded from the API&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onLoad&lt;/span&gt; &lt;span class="o"&gt;=&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Set the form name on the HTML &lt;/span&gt;
      &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;form_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="c1"&gt;// Pass in the form slug, element Id to attach the form to, and optional utility functions&lt;/span&gt;
    &lt;span class="nx"&gt;renderForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;__form_slug__&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;fetch_form&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;onComplete&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;onLoad&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Simple React example
&lt;/h3&gt;

&lt;p&gt;See more at &lt;a href="https://www.fetchforms.io/docs/fetch-forms-react"&gt;www.fetchforms.io/docs/fetch-forms-react&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;FetchForm&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@fetchforms/react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ManagedForm&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;formSubmission&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFormSubmission&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&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;formName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFormName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onSubmit&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;values&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="cm"&gt;/* To show an error on the form, uncomment the line below */&lt;/span&gt;
    &lt;span class="c1"&gt;// return 'There was an error submitting the form.';&lt;/span&gt;
    &lt;span class="nx"&gt;setFormSubmission&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onLoad&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;values&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;setFormName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-3xl mb-2"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Component Form&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-gray-600"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        The easiest way to use Fetch Forms. Pass in a form slug and we'll handle
        client-side validation, input formatting, submissions, and styling.
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;br&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-2xl"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;formName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FetchForm&lt;/span&gt; &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;__form_slug__&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;onLoad&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onLoad&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;br&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;formSubmission&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;pre&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formSubmission&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;pre&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  With custom components example
&lt;/h3&gt;

&lt;p&gt;This example is using Ant Design as the component library.&lt;/p&gt;

&lt;p&gt;See a full working example at &lt;a href="https://www.fetchforms.io/docs/fetch-forms-react"&gt;www.fetchforms.io/docs/fetch-forms-react&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;antd/dist/antd.css&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;useFetchForms&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@fetchforms/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;Form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Checkbox&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Radio&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;InputNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Alert&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;antd&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;CustomFetchForm&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;fetchForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;doCloudSubmit&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useFetchForms&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;__form_slug__&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Called when submission passes client-side validation&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onFinish&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;values&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;fetchForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cloudSave&lt;/span&gt;&lt;span class="p"&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Saving to the Fetch Form's cloud&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;try&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;isSaved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;doCloudSubmit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fetchForm&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;values&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;isSaved&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;There was an error submitting your form.&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="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&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="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onFinishFailed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errorInfo&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Failed:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;errorInfo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// This takes the validation rules from the Fetch form and formats them for &lt;/span&gt;
  &lt;span class="c1"&gt;// the Ant Design form component.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createValidationRules&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fieldType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;validations&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;rules&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;validations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;validation&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;validation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;required&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;regex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;RegExp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="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="nx"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&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="nx"&gt;fieldType&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&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;number&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;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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// Builds out the field based on it's configuration&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dynamicField&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&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;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fieldType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;select&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;Option&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Select&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Option&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Option&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;option&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Option&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Option&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;checkbox&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Checkbox&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;textarea&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;TextArea&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TextArea&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;InputNumber&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;radio&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Radio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Group&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Radio&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Radio&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Radio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Group&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Input&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fieldHtml&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;fetchForm&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Form&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"HookForm"&lt;/span&gt;
            &lt;span class="na"&gt;labelCol&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;span&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;wrapperCol&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;span&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;onFinish&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onFinish&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;onFinishFailed&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onFinishFailed&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;autoComplete&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"off"&lt;/span&gt;
            &lt;span class="na"&gt;noValidate&lt;/span&gt;
          &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;fetchForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;formItems&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;
                &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;valuePropName&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;
                  &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fieldType&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;checkbox&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;checked&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;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;createValidationRules&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fieldType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;validateTrigger&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"onBlur"&lt;/span&gt;
              &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;dynamicField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;
              &lt;span class="na"&gt;wrapperCol&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;span&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="na"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
              &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"primary"&lt;/span&gt; &lt;span class="na"&gt;htmlType&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;fetchForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;submitText&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Fetch Forms is a headless form builder that exists to help developers build and manage forms easily so they can focus on more important things. It’s perfect for headless websites, JAMstack websites, and web apps.&lt;/p&gt;

&lt;p&gt;Website: &lt;a href="https://fetchforms.io?ref=devto"&gt;www.fetchforms.io&lt;/a&gt;&lt;br&gt;
Docs: &lt;a href="https://fetchforms.io/docs/overview?ref=devto"&gt;www.fetchforms.io/docs&lt;/a&gt;&lt;br&gt;
Twitter: &lt;a href="https://twitter.com/FetchForms"&gt;www.twitter.com/FetchForms&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>formbuilder</category>
      <category>react</category>
      <category>developertools</category>
    </item>
    <item>
      <title>What are webhooks and how to get started?</title>
      <dc:creator>Luke Frauhiger</dc:creator>
      <pubDate>Mon, 04 Oct 2021 17:21:35 +0000</pubDate>
      <link>https://dev.to/lukefrogger/what-are-webhooks-and-how-to-get-started-1di</link>
      <guid>https://dev.to/lukefrogger/what-are-webhooks-and-how-to-get-started-1di</guid>
      <description>&lt;p&gt;&lt;strong&gt;Let’s start off by getting straight to the point:&lt;/strong&gt; Webhooks are a way for one system to send updates to one or many other systems.&lt;/p&gt;

&lt;p&gt;That’s it! That’s all they are.&lt;/p&gt;

&lt;p&gt;Have you ever made an API call? Webhooks are very similar, but instead of making a call to an API endpoint, a webhook calls one of you’re endpoints.&lt;/p&gt;

&lt;p&gt;How about a real-world situation: You’re using a payment provider, let’s say, Stripe, to manage your subscriptions in a SaaS platform. The recurring monthly charges happen behind the scenes, but you need to record the data about each subscription in your CRM.&lt;/p&gt;

&lt;p&gt;To achieve this you can create a webhook in Stripe that will fire every time a subscription is paid. This webhook calls an API endpoint in your system — from there you can add the data to your database!&lt;/p&gt;

&lt;h2&gt;
  
  
  Webhooks vs APIs
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“What’s the difference between a webhook and an API?”, you might ask.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This comes down to who is “calling” who. When you make an API call, you are calling a system and asking for data. However, a webhook calls you and throws the data at you.&lt;/p&gt;

&lt;p&gt;I use the term “throw” because webhooks don’t want to wait until your code is done processing before they are given a successful or failed return status.&lt;/p&gt;

&lt;p&gt;Using the above example with Stripe subscriptions, to get data each time a subscription is paid you have to create a webhook in Stripe and an endpoint in your system.&lt;/p&gt;

&lt;p&gt;To get the same data with an API call you’d have to write code to constantly poll Stripe. Since you are constantly polling you’ll have to manage the polling code as well as the other functional code.&lt;/p&gt;

&lt;p&gt;At the end of the day, both solutions work! But the event-driven nature of webhooks makes receiving and working with data much easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  The right and wrong time to use webhooks
&lt;/h2&gt;

&lt;p&gt;No matter how great a tool is, it might not be the right choice for every situation. Webhooks are no exception - they can be a helpful tool, but if used in the wrong situation, they can become a hindrance. &lt;/p&gt;

&lt;h3&gt;
  
  
  When to use webhooks
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;My personal opinion:&lt;/strong&gt; if you can use webhooks, do it! Not all systems can send or receive webhooks, though.&lt;/p&gt;

&lt;p&gt;Webhooks are great for working with time dependent data or apps where you’d have to constantly poll to get data.&lt;/p&gt;

&lt;p&gt;Webhooks have lots of indirect positive implications as well. For example — the less code a developer has to write, test, and maintain, the faster they can ship features. Webhooks can help you remove boilerplate code, cron jobs, and some duplication-checking, allowing you to complete features faster.&lt;/p&gt;

&lt;h3&gt;
  
  
  When to not use webhook
&lt;/h3&gt;

&lt;p&gt;On occasion, processing data can take a long time. If that’s the case, a webhook may not be the answer. Webhooks generally need a quick response based on if the data was received or not. Long-running processes can cause webhooks to time out if they wait too long. The sending platform should have guidelines on what is “too long” for a webhook to wait.&lt;/p&gt;

&lt;p&gt;Webhooks may also not be the answer if the system you are sending data to has strict API limits. As an example, Salesforce has strict limits on calling its API. Using webhooks that push data into Salesforce could cause you to unknowingly break these limits and have to wait until they reset.&lt;/p&gt;

&lt;p&gt;If you are trying to integrate a webhook with Salesforce, using a tool like &lt;a href="https://quickfreeze.io"&gt;Quick Freeze&lt;/a&gt; will be a good call. It’ll allow you to batch the webhooks and use a single API call from within Salesforce to get the data so you stay well within your org’s API limits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--d-jolCVb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mfzwmyn7kowqtum7gj7m.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d-jolCVb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mfzwmyn7kowqtum7gj7m.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Get started with webhooks
&lt;/h2&gt;

&lt;p&gt;To get started with a webhook you’ll need two things.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A system that has the ability to send webhooks&lt;/li&gt;
&lt;li&gt;An API endpoint in a system you control&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once you’ve got the sending system setup to send the data to your endpoint, you’re good to go! No cron jobs, polling functions, or deduplication checks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Local development with webhooks
&lt;/h2&gt;

&lt;p&gt;One of the challenges with webhooks is being able to use them while developing locally. Most platforms won’t allow you to send webhooks to non-secure URLs or localhost. Luckily there are quite a few tools out there to help with this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Three of the best webhook tools:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://ngrok.com/"&gt;Ngrok&lt;/a&gt; — ngrok creates a public URL that forwards traffic to your localhost. This is a great option to use when developing locally because it allows you to test your webhook endpoints like they’ll be used in production&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://quickfreeze.io"&gt;Quick Freeze&lt;/a&gt; — Quick Freeze can act as a bridge between the sending system and the receiving system. If the receiving system has API limits, doesn’t have an inbound API, or can’t be accessed by external systems, Quick Feeze can catch and hold data until it’s ready to be moved out.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://requestbin.com/"&gt;RequestBin&lt;/a&gt; — Request bin allows you to receive API calls and webhooks events from a generated URL, similar to ngrok. You can also view the data, integrate with other apps/platforms, and execute steps on the data.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>webhooks</category>
      <category>salesforce</category>
      <category>indiedevelopment</category>
    </item>
    <item>
      <title>Why My Tech Startup is Failing</title>
      <dc:creator>Luke Frauhiger</dc:creator>
      <pubDate>Wed, 26 Aug 2020 13:45:42 +0000</pubDate>
      <link>https://dev.to/lukefrogger/why-my-tech-startup-is-failing-2cbp</link>
      <guid>https://dev.to/lukefrogger/why-my-tech-startup-is-failing-2cbp</guid>
      <description>&lt;h3&gt;
  
  
  Spoiler - it’s not COVID.
&lt;/h3&gt;

&lt;p&gt;If I knew exactly why my startup was failing, then it would not be failing...Right?&lt;/p&gt;

&lt;p&gt;But one thing is without a doubt; my failure so far is not COVID’s fault. Believe it or not, this startup actually came to fruition because of COVID. Granted, starting a business during a pandemic might not be advisable, but my business is failing for one reason alone – me.&lt;/p&gt;

&lt;p&gt;Now, before you start to feel sorry for me, let me share a bit about myself.&lt;/p&gt;

&lt;p&gt;I subscribe to a worldview of radical responsibility. In the book, The 10X Rule, Grant Cardone put it like this, &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Nothing happens to you; it happens because of you.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I think this statement is a window into each of our worldviews. Each of us has the ability to add value and goodness to those around us through our relationships. Playing the victim and constantly blaming something else for our failings isn’t helpful to anyone.&lt;/p&gt;

&lt;p&gt;Jocko Willink calls this “Extreme Ownership” – and wrote a book about it. Simon Sinek even talks about it in his book, Start with Why, when he says,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Leadership requires two things: a vision of the world that does not yet exist and the ability to communicate it.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What is your vision of the world? I see a world that isn’t continually ravaged by COVID-19. That’s not to say that I hope it quickly fades into history – actually quite the opposite. I hope that we grow and unite and become the types of people that can thrive through any adversity. Most importantly, I know that I have a part in that change by taking responsibility for all of my actions – failures and successes alike. &lt;/p&gt;

&lt;h2&gt;
  
  
  Before you read any further
&lt;/h2&gt;

&lt;p&gt;This is one of my attempts at communicating my vision of the world with you. So far, my attempts at building a business have gone pretty poorly, but I’ll happily take full responsibility for all the failures. &lt;/p&gt;

&lt;p&gt;This is not a sob story or an analytical breakdown of all the business and marketing principles I broke. More than anything else, this is an amusing tale of my first attempt at starting a business. I’m masking the name of the business, and I’m not going into detail about my team to add a layer of privacy for us all.&lt;/p&gt;

&lt;p&gt;I sincerely hope this inspires you to spread your vision of a better world! I’m learning that failure is ok – it happens to everyone. Quitting, on the other hand, is something else entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  How my failure started
&lt;/h2&gt;

&lt;p&gt;Everyone's life has been a whirlwind since COVID-19 dug its claws into the world. Like a lot of people, I lost my job early on in the pandemic. I had been a software and web developer for the previous seven years, so I figured it would be easy to jump into the freelance world. After all, the entire world was going online – so how hard could it be?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Hard...it was very hard. You’ll notice my blind optimism will be a common trend.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I struggled to quickly learn all of the auxiliary skills that it takes to be a freelancer. The truth is that I didn't really want to learn them. I didn't want to be a freelancer and work by myself all the time. I wanted to lead and develop a team and start my own business.&lt;/p&gt;

&lt;h3&gt;
  
  
  Books fueled the fire
&lt;/h3&gt;

&lt;p&gt;A couple of years ago, I resolved that I wanted to be more active in self-growth, so I started reading. I hated reading in high school and college, but I've come to love the ability to reach into people's minds and learn from their experiences. I quickly found my favorite type of book: “straight-talk” about leadership and business.&lt;/p&gt;

&lt;p&gt;I've always been a little taken by the topic of leadership. Maybe because I've encountered so many poor leaders in my life and that makes me want to be an amazing one. Maybe because there is no right way to be a great leader. Maybe because I enjoy power and prefer to be in the driver's seat most of the time.&lt;/p&gt;

&lt;p&gt;These books opened my eyes to a world that was so much bigger than the one in which I lived. It was a world of radical responsibility, business ownership, discipline, and continual learning. But the intelligent and passionate minds I was reading didn't have it all figured out. They had been tested by fire and struggled just like the rest of us mortals. The more I read, the more humanized these individuals became, and I began to realize that I could learn from their stories and forge my own path.&lt;/p&gt;

&lt;h3&gt;
  
  
  Success was going to be easy
&lt;/h3&gt;

&lt;p&gt;The idea of being a self-made man and a great leader is intoxicating to me! So when I was let go from my job of seven years, I knew I wanted to become an entrepreneur and start my own business. I wanted to test out all of the things I had read about and learned over the past couple of years.&lt;/p&gt;

&lt;p&gt;The word “entrepreneur” is a super-buzz-word right now. It seems like everyone wants to be an entrepreneur, and the one million people selling courses on (use your infomercial voice) "How to make $1 million dollars with THIS SIMPLE HACK" seem to be making it easier than ever. I figured with my driven nature, desire to hustle hard, and book knowledge, it would only take a great idea before I was a success.&lt;/p&gt;

&lt;h2&gt;
  
  
  I found the million dollar idea!
&lt;/h2&gt;

&lt;p&gt;Not too long into my freelancing career, in which I had booked zero gigs, an old friend asked if I could build a web app for his non-profit organization. They wanted to have in-person events and needed a tool that would help them socially distance their seating and limit their capacity. I thought it was an incredible idea! During our second meeting, I negotiated owning the intellectual property (IP) to help other non-profit organizations with the idea. He was happy to relinquish the IP, and I was off to change the world! &lt;/p&gt;

&lt;p&gt;His organization, however, was not thrilled with the amount of money I was requesting to build the application. Even with a heavily discounted price, almost 50% and free lifetime use, the organization said no; they opted to wait until I had built the program on my own. Needless to say, that was not the outcome I had hoped for, but I was excited to have a seemingly great idea to work with.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;In hindsight, this was a sign of the struggle to come. Even the originator of the idea didn’t believe in it enough to invest. They quickly found a cheaper solution that seemed to solve the problem.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But I was convinced that if I could build this web application and provide it as a subscription service, my friend’s organization and hundreds – maybe even thousands – of other non-profits would love it and, most importantly, subscribe to it. It didn’t take long before I completed all of the legal documents and signed the forms that legitimized my new business. &lt;/p&gt;

&lt;p&gt;I began to rapidly flesh out the idea. My experience in full stack web development was paying off. I was able to plan out the database architecture, design high fidelity mockups, and code the entire thing. Very quickly, however, I realized that there was too much work for one person to do. I had to bring someone else onboard. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;At least I got that part right!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Avengers, assemble!
&lt;/h2&gt;

&lt;p&gt;With the realization that I couldn’t do everything by myself, I started looking for people to bring on and help me. Luckily, I had a good friend who had been working at the same non-profit as I, pre-COVID. He was let go from his job, as well, and I knew he would have his interest piqued at the prospect of this new adventure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Let me preface something before you read further. I know the startup lifecycle as well as anyone. I know that market research and validation are foundational to starting an online business. And it makes 100% sense, right? If the market you are trying to sell to doesn't have the particular problem you are trying to solve, then you don't have a business. Somehow I seemed to have forgotten this...&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;My friend was a talented salesman and had been working with non-profit organizations for the past several years. He had deep connections, and we were both absolutely convinced that we could bring the service to hundreds of organizations easily. He signed on as my Co-Founder, and we were off the races. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Literally... races. We both agreed that this service needed to be done yesterday. I rallied a few other developers I knew had been let go from their jobs because of COVID and I temporarily brought them onboard with my vision. Our goal was to build, test, and launch two web apps required for our service within four weeks.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Feature Creep
&lt;/h3&gt;

&lt;p&gt;Being in software development for a while, I knew that feature creep was a problem that we’d run into and a huge threat to launching on time. &lt;br&gt;
If you don’t know what it is, feature creep is the act of adding additional functionality to a feature or product during its development that detrimentally pushes back its release. The continual addition of new things to the project makes it very difficult to find a stopping point and can easily kill a project by never allowing it to be “done”. &lt;/p&gt;

&lt;p&gt;I wasn’t about to let Feature Creep get its hands on my project. I fought hard to keep our launch date realistic and only let in features that were required for our MLP - Minimum Lovable Product. Aka - the smallest and least feature rich product that will still have value for the customer. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Did you notice my HUGE misstep? This is probably the single biggest reason for its failing so far. No market research or due diligence, of any kind, was done. We jumped into building and marketing so quickly that we forgot to see if the market was interested in this type of solution. I didn’t realize it then, but we were flying blind. This is made even more evident when we get to pricing the service. Stay tuned.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I rarely shy away from a bit of hard work so I relished the idea of working really hard to start my business. It seemed like a rite of passage based on the stories I had read. Plus, my team and I loved building the web apps – the sense of urgency was a welcomed change from quarantine and unemployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  It’s alive!
&lt;/h2&gt;

&lt;p&gt;Six weeks later and around 500 hours of work from myself alone, and the service was built and stable. I was so proud – and so almost-kinda-sort-of-burnt-out. &lt;/p&gt;

&lt;h3&gt;
  
  
  “Can we stop talking about money?”
&lt;/h3&gt;

&lt;p&gt;Over the entirety of development, my co-founder and I had gone back and forth on how much to charge for the service. We had changed the pricing several times and even had transitioned from a flat monthly fee to a pay-per-use model. The pay-per-use model was super confusing and required an explanation from one of us to be understood. Nonetheless, it was a great offering for scaling and made sure we covered our baseline costs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Pricing was so hard for us to nail down because we had no idea how valuable our solution was. Since we hadn’t done any research, we had no idea how customers were viewing this problem and how much they would pay for a solution. We didn’t even know if our type of solution would be desired by our customers! We were basing the price purely on how amazing we thought our solution was.&lt;/em&gt;&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Once the service was stable and we figured out the pricing, we decided to launch! Why hadn’t we “launched” long before that, you ask? Well, we had to make sure we were 100% ready because customers were going to sign up in droves. We were absolutely certain of it. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;I don’t know why I thought we had to have a completed product before we could start marketing and getting leads. Marketing and sales can be rather difficult and they take time. It was a bit insane to think that we were going to have loads of sign-ups with no marketing and only a dozen 1-on-1 meetings with potential customers. So the tale continues...&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Launch Day!
&lt;/h3&gt;

&lt;p&gt;We launched on a Tuesday with a barebones website, no active marketing of any kind, and no budget to scale with. Surprise, surprise – nothing happened. &lt;/p&gt;

&lt;p&gt;My co-founder and I kept working really hard, almost doubling our efforts. He kept reaching out directly to customers and scheduling demos, and I was implementing group marketing while also continuing to build and improve the service. &lt;/p&gt;

&lt;p&gt;Unfortunately, sales were still going nowhere. Even with a talented salesman and a deep network, we couldn’t get traction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;GET THIS – even before launching, we had leads! Quite a few of them, actually. But none of them took the plunge and signed up. Business 101 – understand your market! We actually had a great service that our customers thought would be helpful, but the onboarding was a little too difficult and the price tag gave them sticker shock.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Being a web developer, my first priority was the marketing website. It wasn’t a great sales funnel, and I figured that redesigning it would help bring in numerous more sales. &lt;/p&gt;

&lt;p&gt;Once again, I put my head down and worked hard to build a stunning website that would drive traffic to demo requests and make sales. But upon completion – nothing happened. Turns out, you need traffic to your website to make sales on your website.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to get traffic when you are not a marketer
&lt;/h2&gt;

&lt;p&gt;I’ve built websites and sales funnels before. I knew good practices for conversions, and I even knew a bit about Facebook ads. But I would not call myself a marketer, by any means. I was hesitant to lean into marketing and sales because I didn't want to step on my co-founder’s toes. He was good at sales and, most importantly, he was my entire outbound marketing strategy. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Have you heard the saying “Don’t put all of your eggs in one basket?” It exemplifies this situation and how I treated outbound marketing. Our Plan A was to make initial sales through my co-founder’s non-profit network. We both thought it would be easy with his relationships and history. But we quickly found out that it was not going to be easy! Our plan B was… there was no plan B.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  I think I’m learning!
&lt;/h3&gt;

&lt;p&gt;I wised up a bit and began doing market research by reaching out to influencers, Facebook groups, Reddit threads, and online magazines. I wasn’t even looking to sell; I was hoping that talking to people about the service would simply generate traffic and that that traffic would generate customers. &lt;/p&gt;

&lt;p&gt;What I found through my research was a massive gamut of opinions on COVID-19 and the tools being used to solve social distancing and capacity limits for live events. I can’t go into details about the market, but the diversity of opinions illuminated a lot about why we had been struggling to get traction. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;At this point I began to realize a few things. 1) We were very overpriced, 2) we needed more features to be attractive and 3) We needed to find more effective verbiage so we could showcase our value more effectively.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Talking directly to people in the market wasn’t very helpful, initially. Each organization was looking for something different, and most that wanted to hold live events had figured out a solution already. This left very little room for a premium-priced service. &lt;/p&gt;

&lt;p&gt;To combat one of those problems, we changed our pricing from the confusing pay-per-use model to a monthly, flat fee and dropped the price by almost 50%. Our service was now slightly lower but appropriately priced against its competitors – a change that would undeniably make the service more attractive and bring in sales. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Can you guess what I’m about to say? Unfortunately, the change did not boost sales. We had a few more leads, but no one was converted into a customer. We still weren’t able to get any traction.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The beginning of failure
&lt;/h2&gt;

&lt;p&gt;I’m a strategist at heart, but for whatever reason, I wasn’t able to see that I didn’t have any kind of plan. I was being purely reactive – changing things week to week or day to day because nothing was working. I never took the time to get the altitude I needed to make long-term and thought-out decisions.  &lt;/p&gt;

&lt;h3&gt;
  
  
  All of those eggs in one basket
&lt;/h3&gt;

&lt;p&gt;At this point, it had been around two and a half months since launch day, and my co-founder told me he had some bad news to share. He had to pick up another job to keep his house. That means he has very little time to work on our business. It took courage to have that hard conversation with me, but his decision was completely understandable. Life during COVID-19 is hard and ever-changing and it often requires hard sacrifices. Nonetheless, I all but lost my teammate when he cut his hours back.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;One of the things I’m proud of is the way I handled that situation. I would never have asked or expected him to sacrifice his home for our business. I wanted our business to be successful more than I wanted most things, but people will always be more important than business or money in my book. I was disappointed when he stepped back, but I recognized the hard situation he was in and didn’t hold his decision against him.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Putting more pressure on me, the developer I had on contract was very close to getting a full-time gig. His contract was written so that he was paid based on how much money the business had made and at this point, we had made $0. He had rent and groceries to pay for, just like the rest of us! When he was hired for his new full-time job,  he stepped back and cut his hours down to under 10 per week.&lt;/p&gt;

&lt;p&gt;That week ended with zero sales and with the entire weight of a failing business on my shoulders. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;I know I said this isn’t a sob story, but that is pretty sad, huh? But that’s as low as it goes. The only direction to go is up!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Who's to blame?
&lt;/h3&gt;

&lt;p&gt;It would be easy to blame this failure on COVID or even on my teammates. After all, they did choose other priorities over our business. But I think there’s much more in their decisions than meets the eye. &lt;/p&gt;

&lt;p&gt;They cut back hours and choose other priorities because I was unable to lead them in a successful launch or post-launch sales campaign. Jocko Willink’s words in Extreme Ownership are ringing true in my ears:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“There are no bad teams, only bad leaders.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  “I’m going on an adventure!”
&lt;/h3&gt;

&lt;p&gt;It doesn’t end there, Bilbo Baggins. We’re now several months post-launch (at the time of writing), and we are still going. My co-founder is working really hard and making time for our business, which has breathed new life back into me and the business. If nothing else, all his hard work is an incredible blessing to me. &lt;/p&gt;

&lt;p&gt;And me? I’ve been taking some time and learning from my mistakes - hence this article. It hasn’t been easy, but I’m doing my best to be patient and develop a great strategy for scaling up and gaining traction. &lt;/p&gt;

&lt;p&gt;Also - we have customers and demo requests coming in - it’s slow, but we’re trending upwards! Maybe time will turn out to be the secret sauce to it after all. &lt;/p&gt;

&lt;h2&gt;
  
  
  Failure isn’t always bad
&lt;/h2&gt;

&lt;p&gt;Here’s the short of it - failing isn’t objectively bad. It’s hard and can feel terrible when you’re in it, but it is the best teacher. I don’t think you are a “failure” when you make mistakes and “fail”. I think what makes you a true failure is when you give up.&lt;/p&gt;

&lt;p&gt;Because of that, I’m not giving up. I have an abundance of things to learn and it would be wrong for me to quit now. I’ve failed to launch this business well, but there is life left in it! I think the idea behind this service is incredibly helpful and I think that the longer COVID sticks around, the more organizations will realize they need a solid, long-term solution. &lt;/p&gt;

&lt;p&gt;I’ve made a lot of mistakes to get myself here. Ironically, I feel more prepared to take on any future businesses now that I have taken time to slow down, and can clearly see where I’ve failed in the past.&lt;/p&gt;

&lt;h2&gt;
  
  
  At the end of the day
&lt;/h2&gt;

&lt;p&gt;I did something that most never will – I started. I’ve had a hell of a go so far on this business and I’m sure it'll be laborious going forward but I’ll pay that price to bring value and safety to non-profit organizations. &lt;/p&gt;

&lt;p&gt;At the heart of this is my desire to better the world around me; to add value to people’s lives so they have more energy and life to give to others. That’s my mission and it’s worth a lot of hard work and sacrifice. &lt;/p&gt;

</description>
      <category>startup</category>
      <category>business</category>
    </item>
    <item>
      <title>Get started with full-stack development - Svelte and Express</title>
      <dc:creator>Luke Frauhiger</dc:creator>
      <pubDate>Tue, 11 Aug 2020 17:52:11 +0000</pubDate>
      <link>https://dev.to/lukefrogger/get-started-with-full-stack-development-svelte-and-express-7gn</link>
      <guid>https://dev.to/lukefrogger/get-started-with-full-stack-development-svelte-and-express-7gn</guid>
      <description>&lt;h1&gt;
  
  
  Full Stack Development Starter - Svelte and Express
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Svelte and Node.js
&lt;/h3&gt;

&lt;p&gt;Knowing how to build either a frontend or backend is a valuable skill. I started my career in technology as a UI/UX designer, but I hated that I couldn't help turn my designs into a functional app. That's when I jumped into frontend development! I desperately wanted to do more than design the interactions - I wanted to be able to build them!&lt;/p&gt;

&lt;p&gt;Learning frontend design was a great challenge and it was amazing how much it affected my designs. Knowing more about data structures, data manipulation, and the capabilities of various frameworks forced me to think critically about the designs I was doing. It especially helped with the hand-off between myself and developers. Terms like, "I don't know how to do it, just do it", left my vocabulary and I was much more helpful in the implementation. Something my fellow developers are thankful for to this day.&lt;/p&gt;

&lt;p&gt;However, for most people learning just frontend or just backend isn't enough. To put a website or web app on the internet for all to see, you have to know more than just one discipline. That's why I'm writing this! I hope this article helps you with your journey of building and deploying a Svelte app. There are other ways to deploy Svelte and the other SPA frameworks, but using an application server is one of my favorites if you need to do backend &amp;amp; API work. &lt;/p&gt;

&lt;h2&gt;
  
  
  Before we begin
&lt;/h2&gt;

&lt;p&gt;Before we jump in let's go over some details.&lt;/p&gt;

&lt;p&gt;You'll need Node.js installed - you can &lt;a href="https://nodejs.org/en/download/"&gt;download it here&lt;/a&gt; if you haven't already. &lt;/p&gt;

&lt;p&gt;You can access my &lt;a href="https://github.com/lukefrogger/full-stack-starter-svelte-express-app"&gt;template repo with the completed files here&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  The plan
&lt;/h4&gt;

&lt;p&gt;The plan is to create a Svelte frontend, a Node &amp;amp; Express backend, and wire them together so that our frontend can search for gifs from the GIPHY API. This will be a great example of why using an application server can be so great for your full-stack development. It keeps all the files in one place and sensitive data, like API keys, are hidden in the server and not your frontend. &lt;/p&gt;

&lt;h4&gt;
  
  
  So...Svelte is awesome, right?
&lt;/h4&gt;

&lt;p&gt;As a full-stack developer of 7 years, I honestly say that Svelte is pretty amazing...but not for everything. Here is a saying that I've said far too often in my career&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Anything can be used as a hammer"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'm a huge advocate for using the right tool for the job. Sometimes that means it's going to be Svelte, sometimes it won't. You could choose to use Svelte for all your projects and that might be a great call for you. It might not be a good call for someone else.&lt;/p&gt;

&lt;p&gt;My personal opinion - I wouldn't use Svelte for bigger applications. It's not because Svelte can't handle bigger projects! It's because I think tools like React or Angular provide much better tooling and organizational potential than Svelte does. For our small example today, I think Svelte is perfect! &lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s jump in
&lt;/h2&gt;

&lt;p&gt;The first thing we’ll do is create our Svelte app. To do that, we’ll follow the &lt;a href="https://svelte.dev/blog/the-easiest-way-to-get-started"&gt;instructions on this page&lt;/a&gt; and run the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npx degit sveltejs/template svelte-express-app
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you haven’t used &lt;code&gt;npx&lt;/code&gt; before, it’s an executable package, baked into NPM, that enables one-time use of an npm package. In this case, &lt;code&gt;npx&lt;/code&gt; is executing the tool degit to pull down and clone the Svelte template repo. You can read more info about the &lt;a href="https://www.npmjs.com/package/degit"&gt;degit project here.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This command clones the Svelte template repo and names it “svelte-express-app”. Once the command completes, install the project, and you’re ready to begin developing with Svelte! Let’s run the following commands to get our Svelte app 100% ready.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;svelte-express-app
&lt;span class="nv"&gt;$ &lt;/span&gt;yarn
&lt;span class="nv"&gt;$ &lt;/span&gt;yarn dev
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We can now begin to develop our Svelte app! Let's move to the Node.js backend. &lt;/p&gt;

&lt;p&gt;We’ll use Express on top of Node.js to make building the API super easy. To get this started, we'll first install Express and CORS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;yarn add express &lt;span class="nt"&gt;--save&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;yarn add cors &lt;span class="nt"&gt;--save&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now that we have Express added to our project, let's create the server file and get it set up so that it can serve the Svelte app. It's important that the server file is outside of the "src" folder. Since the Svelte app is within the "src" folder, everything within it gets compiled and bundled through Rollup - the bundler that Svelte uses. Since we want our server to be separate and serve the frontend to the browser, we need to make sure that the server file is outside of any directory that's being compiled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: You could write Node.js and Express with Typescript and need it to be compiled. But that's a slightly different process and one we're not going over in this article. If that's something you'd like to see, let me know!&lt;/p&gt;

&lt;p&gt;Let's create our file at the root of our project. I'm going to name my file "server" - I'm really creative, I know! You can create the file with the following command or however you're favorite editor allows you to.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;server.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Open that file up and add the boilerplate code for Express&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&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;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="nx"&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="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&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;5000&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;cors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&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;cors&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;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&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="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;These lines of boilerplate do several things. They set up the express app, assign a port if the application doesn't have one, import the CORS and Path libraries from npm, and finally, it assigns the Express app to use CORS instead of the baked in security. Cors is really helpful in fine-tuning the security of your application in regards to what domains, outside of your hosting domain, can be used to access the server.&lt;/p&gt;

&lt;p&gt;Just a few more lines before we're ready to use the server!&lt;br&gt;
&lt;/p&gt;

&lt;div class="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="nx"&gt;use&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="kd"&gt;static&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;public&lt;/span&gt;&lt;span class="dl"&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="kd"&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="nx"&gt;sendFile&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;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;public&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;index.html&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="nx"&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server is up at 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;The first two functions are used to serve the index.html in the public directory to the browser. If you'd like to read more on how the Path library works &lt;a href="https://nodejs.org/api/path.html"&gt;take a look here&lt;/a&gt;, but It's essentially a baked in library that allows Node.js to read and write files!&lt;/p&gt;

&lt;p&gt;The last function is a listener that prints out a statement about the port number of the server! This is a really quick way to know if the server is up when developing locally.&lt;/p&gt;

&lt;h4&gt;
  
  
  Let's Test
&lt;/h4&gt;

&lt;p&gt;Let's test each app separately to make sure they're working. Make sure you kill the process before you run another one.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn dev&lt;/code&gt; to start the Svelte app. Go to your browser and check it out!&lt;/p&gt;

&lt;p&gt;&lt;code&gt;node server.js&lt;/code&gt; to start the express app. The console should read &lt;code&gt;Server is up at port 5000&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting Both With One Command
&lt;/h2&gt;

&lt;p&gt;Now that we have our frontend and backend configured, we need to spin them up! There are differences in the build process between development and production. To serve this in a production environment, it's a pretty straightforward process.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Build the Svelte app &lt;code&gt;yarn build&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start the server.  &lt;code&gt;yarn start&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's so simple because we don't want the Svelte app to be hot reloading. For production, we want a super-performant, minified bundle that will load in the browser quickly.&lt;/p&gt;

&lt;p&gt;But for development, hot reloading is a must for the Svelte side of things! We'll have to adjust the package.json scripts so we can re-compile the Svelte every time we make changes. And we need to serve the Svelte app from our Express server instead of Svelte's default serve library.&lt;/p&gt;

&lt;p&gt;Svelte uses the library "sirv" to deliver the compiled bundle of Javascript to your browser. Let's open the package.json file and take a look at the "scripts" part of the file. You'll find a "start" command that uses the sirv library to serve the public folder. Let's change that &lt;strong&gt;FROM&lt;/strong&gt; "sirv public" &lt;strong&gt;TO&lt;/strong&gt; "node server.js". This creates a single command that will hot-reload the Svelte app and use our Express app as the server. Let's give it a go!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn dev
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Go to your browser at localhost:5000 and see it work! You should also see the console print out the port number. &lt;/p&gt;

&lt;h4&gt;
  
  
  You're done! But there's more
&lt;/h4&gt;

&lt;p&gt;Congratulations, you've built a full-stack web app that is incredibly easy to develop! But we're not going stop there. Let's add an API endpoint to our Express app and use the GIPHY API to search for gifs. &lt;/p&gt;

&lt;h2&gt;
  
  
  Adding a route
&lt;/h2&gt;

&lt;p&gt;The first thing we're going to do is add a new route to our Express.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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="kd"&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;/giphy&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Searching for a gif with the term: &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;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;term&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&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;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It's incredibly important to note that this function MUST BE BEFORE the app.use() function that sends the index.html to the frontend. If you place this function after that app.use() function, nothing will happen on your request.&lt;/p&gt;

&lt;p&gt;The first line is the Express function that declares the URL path of the endpoint and which HTTP verbs can be used for it. This endpoint can be accessed through localhost:5000/giphy and it's a "GET" function only. You can also use other HTTP verbs like POST, PUT, and DELETE. If you'd like to use an endpoint for everything, the "USE" function is the perfect choice.&lt;/p&gt;

&lt;p&gt;The next line is a console log to print out the search term and then we have the &lt;code&gt;res.send()&lt;/code&gt; function that sends our data back to the frontend. There's no special sauce here - you can return whatever you'd like from your endpoint. In my experience creating an object that has a success flag and then a property with the data makes it easy to do success/fail conditionals in the front end.&lt;/p&gt;

&lt;h4&gt;
  
  
  Making the request from Svelte
&lt;/h4&gt;

&lt;p&gt;Now to Svelte! Open up App.svelte and replace the paragraph after "Hello World" with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"search-block"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Search for gif"&lt;/span&gt; &lt;span class="na"&gt;bind:value=&lt;/span&gt;&lt;span class="s"&gt;{searchTerm}&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;on:click=&lt;/span&gt;&lt;span class="s"&gt;{searchForGif}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Search&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"gifs"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    {#if gifs.length &amp;gt; 0}
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"gifs-grid"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            {#each gifs as gif}
                &lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;{gif.embed_url}&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;{gif.title}&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            {/each}
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
     {:else}
         No gifs to show yet
     {/if}
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, add this javascript in the script tag.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;gifs&lt;/span&gt; &lt;span class="o"&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;searchTerm&lt;/span&gt; &lt;span class="o"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;searchForGif&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&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;returnValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/giphy?term=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;searchTerm&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;returnValue&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="nx"&gt;gifs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&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="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;At this point, I'm assuming you know Svelte and it's flavor of syntax, so I'm not going to talk in detail about how this works. From a high level, the button calls a function that uses the value bound to the input field and calls to our Express endpoint. On return, the code is formatted and assigned to a variable. Once all that code is added, you should be able to type something in the input field, click the button and see the Express server log out the search term. Since we're not returning any data from our endpoint, the Svelte won't change or display anything. &lt;/p&gt;

&lt;h4&gt;
  
  
  Using the GIPHY API
&lt;/h4&gt;

&lt;p&gt;Let's change that - let's add the GIPHY API. To make API calls from Express, we'll need to add a library. I like axios, but node-fetch is another popular one. Run &lt;code&gt;$ yarn add axios&lt;/code&gt; to install axios and then add the require() to the server &lt;code&gt;const axios = require('axios');&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now we're ready to add the API call. In the &lt;code&gt;/giphy&lt;/code&gt; endpoint replace the contents with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Searching for a gif with the term: &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;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;term&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&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;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;term&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/ /g&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="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;amp;api_key=YOUR_API_KEY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;amp;limit=10&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`https://api.giphy.com/v1/gifs/search?q=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&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="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;response&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="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;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&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="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;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;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The first part of this code takes the &lt;code&gt;term&lt;/code&gt; variable and replaces any spaces with a plus sign. The next two lines add the API key and a query limiter. These are all well documented in &lt;a href="https://developers.giphy.com/docs/resource/#code-examples"&gt;GIPHY's doc here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The axios function will make a GET request to the endpoint and then resolve or reject, sending the appropriate response back to the client.&lt;/p&gt;

&lt;p&gt;Before you can query the GIPHY API, you'll need to get your own API key. Head over to their &lt;a href="https://developers.giphy.com/docs/sdk"&gt;developer page and create an account&lt;/a&gt; and an app. Make sure you select API when you are generating a key. Then copy and paste that bad boy after the &lt;code&gt;YOUR_API_KEY&lt;/code&gt; param in the code above!&lt;/p&gt;

&lt;h2&gt;
  
  
  Search for Gifs!
&lt;/h2&gt;

&lt;p&gt;Once you've added your API key to the endpoint you're ready to use the search functionality! &lt;br&gt;
Restart your server with &lt;code&gt;yarn dev&lt;/code&gt; and type something in the search box and hit the button! A grid of 10 gifs should popup! This project is super extensible, so feel free to hack around and explore it on your own.&lt;/p&gt;

&lt;p&gt;You can access my template repo with the [completed files here.]((&lt;a href="https://github.com/lukefrogger/full-stack-starter-svelte-express-app"&gt;https://github.com/lukefrogger/full-stack-starter-svelte-express-app&lt;/a&gt;)&lt;/p&gt;

</description>
      <category>fullstack</category>
      <category>express</category>
      <category>node</category>
      <category>svelte</category>
    </item>
    <item>
      <title>Options for Deploying Full Stack React App</title>
      <dc:creator>Luke Frauhiger</dc:creator>
      <pubDate>Wed, 05 Aug 2020 15:21:47 +0000</pubDate>
      <link>https://dev.to/lukefrogger/options-for-deploying-full-stack-react-app-f2l</link>
      <guid>https://dev.to/lukefrogger/options-for-deploying-full-stack-react-app-f2l</guid>
      <description>&lt;p&gt;One of the greatest things about programming is that there are a huge number of ways to do things. There often is no right or wrong way. I would argue that there is a better and worse way to do things, but that is beside the point. The ability of us, as developers, to create something out of code that can add value to people’s life is second to none! &lt;/p&gt;

&lt;h3&gt;
  
  
  So. Many. Options
&lt;/h3&gt;

&lt;p&gt;With all the building and deployment options afforded to developers, choosing the right one can become incredibly overwhelming. Ben Schwartz, a well-known psychologist, calls this "choice paralysis". He argues that more choices make us less likely to take action and to be less satisfied with our eventual decision.&lt;/p&gt;

&lt;p&gt;With so many options and services in the deployment landscape, it can be quite difficult to narrow them down and make a good choice on what platform, price point, and availability are right for your application. To make matters worse, you might get so caught up in researching the options that you lose all momentum on your project.&lt;/p&gt;

&lt;p&gt;That might be where you’re at now, or you might just be starting out and need some direction. Either way, let’s keep you moving forward and get your deployment started. Just one thing before we start...you have to promise me that once you read this article, you’ll choose a platform and deploy. Deal?&lt;br&gt;
Deal!&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep Moving Forward
&lt;/h3&gt;

&lt;p&gt;Below I’ll share some helpful guidance on how to deploy your React app and a comparison between a few of the most popular platforms and their pros and cons. This isn’t an exhaustive list nor an in-depth how-to guide. But I hope it helps you along your development journey. &lt;/p&gt;

&lt;p&gt;With the advent of FaaS or “serverless”, the use of application servers has fallen pretty dramatically. If you aren’t sure what the difference is, let me fill you in. An application server is a server that runs to serve your frontend application (React in our case) and act as middleware. Middleware can be used for a whole host of things, but I tend to use it as a light-weight backend for code that is specifically used in the frontend it’s serving.&lt;/p&gt;

&lt;p&gt;Because of the different needs of serverless and application servers, I’m going to make a list for each type. &lt;/p&gt;

&lt;h2&gt;
  
  
  Deploy an application server
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kqYaICuu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3mk4t6wxthxhcfezomxd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kqYaICuu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3mk4t6wxthxhcfezomxd.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Render&lt;/strong&gt;&lt;br&gt;
My first choice is Render, which is the new kid on the block. They’re a fledgling startup that won the 2019 Startup Battlefield at Disrupt. They provide a host of tools including databases, disks, and web hosting with very little or no vendor lock-in. They are also very straight forward about the resources you are paying for and are incredibly easy to use. Render will only deploy with GitHub or GitLab, but it automatically connects to the repo and will auto-deploy on push!&lt;br&gt;
For use with an application server, their pricing starts at $7 as of the writing of this article.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Heroku&lt;/strong&gt;&lt;br&gt;
My second choice is Heroku. My least favorite thing about Heroku is that it’s super shady about their servers, or as they call them, Dynos.  Nobody really knows what a dyno is, but they’re known for not scaling poorly. Bigger apps can slow down on Heroku, even though you’re paying a premium. &lt;br&gt;
Similar to Render, you can use Heroku with no vendor lock-in and auto-deploy from your Github, but not GitLab. Heroku does have a free version, which is great for prototyping or side projects, but their paid tier starts at $7 at the time writing. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Back4App&lt;/strong&gt;&lt;br&gt;
I have Back4App on this list because it’s widely used and I’ve heard lots of good things about it. To get a picture of how it works I created an account and went to deploy one of my projects. Long story short, I stopped before I got it deployed. Back4 is an astonishingly deep tool that is more than capable to handle an entire enterprise stack. But if you’re looking for an easy and simple process to get your app deployed - this isn’t it. Use Render instead :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploy a serverless app
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KKCgB_8n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fu6at6zl1bwmj7ch3ksm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KKCgB_8n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fu6at6zl1bwmj7ch3ksm.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Netlify&lt;/strong&gt;&lt;br&gt;
My go-to option for serverless or static site deployments is Netlify. Their free tier is awesome! The platform has an astonishingly large amount of features and they've all been easy to use - something I cannot say about all platforms in this list(Back4App). For example, you can integrate a form in your project with Netlify’s form handler giving you the ability to send notifications when a form is submitted and storing them in Netlify for future viewing. All for free! You can also connect Github, GitLab, and BitBucket with subsequent auto-deploys. Easy and free with tons of options - my top choice!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Render&lt;/strong&gt;&lt;br&gt;
The second place goes to Render. It’s easy to use and you can connect Github or GitLab for auto-deploys. They’re the 2019 Startup Battlefield at Disrupt and are taking on giants like AWS and GCP to simplify the developer experience in regards to deployment and hosting. Since Render also can host things like servers and databases, it would make for a great place to host if you’re expanding with an Expressjs API or database. Most things in Render are paid, so if you’d like to spend $0 on your entire full-stack, Firebase might be your jam. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Firebase&lt;/strong&gt;&lt;br&gt;
Firebase is pretty incredible. It’s only last because, as far as hosting goes, you might have to pay for it if your app is used enough. Hosting your frontend on either Render or Netlify can be 100% free, whereas Firebase might charge you. Firebase will charge if the data transferred or hosted is larger than a specific limit. Meaning that you could get charged or your app shut down if you hit that limit. &lt;br&gt;
I actually love Firebase! I use Firestore and Cloud Functions in a lot of my projects, but I’ve never hosted using Firebase because I think there are better options out there. I have a production app that is hosted in Render but uses Firebase for the database and backend. It’s my favorite combination! &lt;/p&gt;

&lt;h2&gt;
  
  
  Full Stack Considerations
&lt;/h2&gt;

&lt;p&gt;Since your Fullstack application isn’t just the frontend there are few things to consider when deploying. Whether you’re using an application server or going serverless, the needs on your application are the same. You’ll need some kind of API to connect to a backend and database to store your data. &lt;/p&gt;

&lt;p&gt;I typically advocate for devs to try managed backends first. Databases like Firebase’s firestore, or AWS Amplify (DynamoDB) can help you move quickly and have to manage less infrastructure. With that in mind below is my top choice for an inexpensive and fast deployment stack. &lt;/p&gt;

&lt;p&gt;Here is my top pick for hosting &amp;amp; deployments for your full-stack application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Render Hosting &amp;amp; Firebase Backend&lt;/strong&gt;&lt;br&gt;
What's it for: Serverless hosting &amp;amp; managed backend&lt;/p&gt;

&lt;p&gt;It’s no secret that I love Render’s hosting and platform. It takes all the great features from bigger competitors like AWS or Google Cloud and simplifies them down so you don’t need an MBA and 7 days to figure them out. Using Firebase’s Firestore and Cloud Functions as the backend provides you a huge amount of flexibility and takes the complexity of managing a database and API off of you.&lt;/p&gt;

&lt;p&gt;Using Firebase does lock you in, but if you have a well-designed app, changing over to MongoDB with a streaming library like RXJS, won’t be too terribly painful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why I love it&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;100% frontend hosting&lt;/li&gt;
&lt;li&gt;Huge free tier for database and API (Firestore &amp;amp; Cloud Functions)&lt;/li&gt;
&lt;li&gt;Backend is managed for you&lt;/li&gt;
&lt;li&gt;Get started very quickly&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrap up
&lt;/h2&gt;

&lt;p&gt;There are all kinds of amazing options there for deploying your full-stack application. When I look for a platform to host and deploy, I focus on ease and simplicity. That’s why I haven’t included some tools like Amplify or GCP in my comparison. They are incredible tools, but they have a steep learning curve and require you to take substantial amounts of time learning them. &lt;/p&gt;

&lt;p&gt;I want my deployments and hosting to be quick and easy. After all the work you’ve put into building and testing your app, the last thing you should be doing is learning how to create and manage a VM before you deploy. There is a time and place for VMs and enterprise tooling, but often we just need a simple way to get our ideas and code to the public. &lt;/p&gt;

&lt;p&gt;I hope you found this helpful! Now...go forth and deploy! &lt;/p&gt;

</description>
      <category>fullstack</category>
      <category>deployment</category>
      <category>react</category>
      <category>serverless</category>
    </item>
    <item>
      <title>Analyze My UI: Behance.net</title>
      <dc:creator>Luke Frauhiger</dc:creator>
      <pubDate>Fri, 31 Jul 2020 19:30:29 +0000</pubDate>
      <link>https://dev.to/lukefrogger/analyze-my-ui-behance-net-16dk</link>
      <guid>https://dev.to/lukefrogger/analyze-my-ui-behance-net-16dk</guid>
      <description>&lt;p&gt;Analyze My UI is a series where I breakdown the UI design of web apps and mobile apps. We’ll talk about the design and usability priorities, the hierarchy, the colors, and just about anything else that impacts the way that users interact with the application. &lt;/p&gt;

&lt;p&gt;UI design is a balance of priorities and it can be difficult to find the proper balance for your application or product. Hopefully, this series helps you define the various priorities and make better decisions in your designs. &lt;/p&gt;

&lt;p&gt;Today we’ll be going over Behance.net. The popular portfolio website does some interesting things to put it’s content in the spotlight and not distract from the primary purpose of the application. Let’s jump in.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cards
&lt;/h3&gt;

&lt;p&gt;Behance uses several different card layouts throughout their site. On the Home page, they already have two different layouts: a categorical filter and their flagship, “project” card. &lt;br&gt;
&lt;em&gt;Home Page&lt;/em&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dNpoXnSx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/m2hfew8n9lhyssf50kom.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dNpoXnSx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/m2hfew8n9lhyssf50kom.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;They also have a slightly different project card for the Search and Filter page. The differences make sense - just keep reading!&lt;br&gt;
&lt;em&gt;Search &amp;amp; Filter page&lt;/em&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nMOZbRW0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/k0og561bo205lqyfr764.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nMOZbRW0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/k0og561bo205lqyfr764.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But in both the project cards, you can quickly see what Behance thinks is the most important data for you to see:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Design&lt;/li&gt;
&lt;li&gt;Creators name&lt;/li&gt;
&lt;li&gt;The Design's Name (only on the filter page)&lt;/li&gt;
&lt;li&gt;Number of likes&lt;/li&gt;
&lt;li&gt;Number of views&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I think these make sense for a portfolio platform. Since you can’t do much on Behance but look at designs and follow designers, the emphasis on views, likes, and users make sense to me. They try to drive engagement through the few interactions they have on each post. &lt;/p&gt;

&lt;p&gt;Let's walk through each one of the above a bit more:&lt;/p&gt;
&lt;h4&gt;
  
  
  1. Design
&lt;/h4&gt;

&lt;p&gt;The backbone of the platform and the most important content. The rest of the data could be removed and the platform would still have some level of usefulness and relevance.&lt;/p&gt;

&lt;p&gt;You might have missed the gravity of that statement. If Behance took away everything on their home page except the images of uploaded designs, their platform would still be useful! All the other stuff on the site is fluff...helpful fluff. But still fluff. It’s a lesson in radical prioritization as Behance has clearly made everything about the projects it hosts. Even it’s branding gives clues to this, but we’ll get to that in a sec.&lt;/p&gt;
&lt;h4&gt;
  
  
  2. Creators Name
&lt;/h4&gt;

&lt;p&gt;Since it's a social platform, Behance has the creator's name on the card so that people can build a reputation and quickly navigate to other designers’ account pages. This shows us that Behance thinks that it's users, their reputation, and the ability for designers to follow each other is very important. They want people to connect person-to-person not just person-to-design.&lt;/p&gt;

&lt;p&gt;Behance is a portfolio site which means there’s not much engagement to be had between users. But they try to drive engagement through the Follow, Save and Appreciate buttons within the design page. It’s completely normal for us to see actions like this nowadays, but I point it out to make you think about where you can add helpful and valuable, micro-engagements in your designs. &lt;/p&gt;
&lt;h4&gt;
  
  
  3. Design's Name
&lt;/h4&gt;

&lt;p&gt;This one is funky. On the home page, the card doesn’t display the design name. But on the Search and Filter page, it does. What do you think that means?&lt;/p&gt;

&lt;p&gt;I don’t work for Behance, so I can’t tell you why they made that decision, but I can tell you what I think. The home page and the Search and Filter page are about two different purposes. The home page is 100% presentation and ease of access. It’s heavily curated for showing the “best of” categories! Sounds like it’s the perfect place to quickly and easily get inspiration and see fellow designers work. &lt;/p&gt;

&lt;p&gt;The Search and Filter page is for...well, searching for projects. The curation gives way to a  giant search bar and secondary filters. This page needs more data on the card because here users are looking for in-depth content that matches a specific search query. &lt;/p&gt;

&lt;p&gt;You might also notice the priority and ease of access to the text search versus secondary filters like "Tools" and "Creative Fields". This, in combination with the “more data” paradigm on the search and filter page, tells us that Behance thinks that users will find it easier to use the text search over other filtering tools.&lt;/p&gt;
&lt;h4&gt;
  
  
  4. Number of Likes
&lt;/h4&gt;

&lt;p&gt;Similar to Instagram, displaying likes is a way to gamify or psychologize engagement. Based on how users interact with the platform they might want to follow designers with a huge amount of likes or they may search for lesser-known designers and give them likes. Regardless, it's a bit of a measuring stick that Behance thinks it important to drive engagement - probably since it's the only way to interact with a design outside of being able to "follow" another designer.&lt;/p&gt;
&lt;h4&gt;
  
  
  5. Number of Views
&lt;/h4&gt;

&lt;p&gt;Views are the foundation of most things on the web. If you are particularly cruel to yourself you might compare views to likes and base your worth on the corresponding percentage. Don’t do that - you’re amazing as you are :)&lt;/p&gt;

&lt;p&gt;Views are another way of driving engagement on content that is generally non-interactable as well.&lt;/p&gt;
&lt;h4&gt;
  
  
  Overall Priorities
&lt;/h4&gt;

&lt;p&gt;The cards on Behance do two things. They present the most important data to the users and they show just enough data to entice engagement and curiosity. &lt;/p&gt;

&lt;p&gt;I’d like to point out there at there is not “Show More” or “More Details” on the cards. Behance has shown it’s commitment to &lt;a href="https://lawsofux.com/hicks-law"&gt;Hick’s Law&lt;/a&gt; by restricting the amount of data you see on the cards. Generally speaking, when in doubt, show less data.&lt;/p&gt;
&lt;h3&gt;
  
  
  Branding
&lt;/h3&gt;

&lt;p&gt;Behance’s branding is very minimal. Being part of Adobe, even the Create Account and Login pages have creative designs but have very small amounts of standalone branding. This is not on accident, I’m sure. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Everything you do as a designer should have a purpose. Every color, placement, line, and character should have a meaning you can define.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Behance knows that it will be very difficult to have a strongly colored or designed brand while facilitating the curation of other designers’ work. Behance wants it’s branding to fall into the background and be invisible. You can tell this first and foremost by their use of color.&lt;br&gt;
&lt;strong&gt;Black&lt;/strong&gt;&lt;br&gt;
Or Blackish….technically it’s &lt;code&gt;#191919&lt;/code&gt; which is few steps above black. &lt;/p&gt;

&lt;p&gt;Their primary use of black in the header and solid white as the body background tells us that they don’t want users to be distracted by their branding. They once again focus their users wholeheartedly on their content. &lt;/p&gt;

&lt;p&gt;The only other color I’ve seen them use is a primary-blue which contrasts nicely with the black and has enough contrast to stand out from white. &lt;/p&gt;
&lt;h4&gt;
  
  
  Branding and You
&lt;/h4&gt;

&lt;p&gt;Branding and color are a hot topic. Every business wants an amazing brand that sets them apart. Something that isn’t readily thought of by most brands is how their brand interacts with their business. If you are a solo freelancer and your brand is your name, then a flashy and highly stylized brand &amp;amp; color guide would great! But for a company like Behance, that wouldn’t work at all.&lt;/p&gt;

&lt;p&gt;Behance is a platform that helps designers through curation and promotion. It would be conflicting if they tried to step into center stage and took the focus off of their content.&lt;/p&gt;
&lt;h3&gt;
  
  
  Finally...
&lt;/h3&gt;

&lt;p&gt;Behance is a pretty simple website. Or at least their superb use of design and navigation make it feel that way. Over and over again Behance has made design decisions that make its visitors focus on the content they host - at the very cost of Behance’s own identity. Imagine trying to explain that your non-designer boss, “I want to remove most of our branding and make our color palette pretty lame, so visitors don’t get distracted by it”. &lt;/p&gt;

&lt;p&gt;But designing UIs is all about priorities. What your business deems the most important will be pushed up the hierarchy whether it’s your brand, your content, or your products.&lt;/p&gt;

&lt;p&gt;If you’ve enjoyed this post and want to read more, let me know what website or app you’d like me to analyze next!&lt;/p&gt;


&lt;div class="ltag__user ltag__user__id__5745"&gt;
  
    .ltag__user__id__5745 .follow-action-button {
      background-color: #0D58A6 !important;
      color: #FF9900 !important;
      border-color: #0D58A6 !important;
    }
  
    &lt;a href="/lukefrogger" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hGRq3EFd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--Uep_Vzma--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/5745/01df0c4c-2591-429f-9572-7b6badad918c.png" alt="lukefrogger image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/lukefrogger"&gt;Luke Frauhiger&lt;/a&gt;
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/lukefrogger"&gt;I'm a full-stack developer, a web designer, and a software architect. I'm seeking to help other developers and businesses grow in their knowledge and use of technology. &lt;/a&gt;
    &lt;/div&gt;
    &lt;p class="ltag__user__social"&gt;
        &lt;a href="https://github.com/lukefrogger" rel="noopener"&gt;
          &lt;img class="icon-img" alt="github logo" src="https://res.cloudinary.com/practicaldev/image/fetch/s--C74Jn3f1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo.svg"&gt;lukefrogger
        &lt;/a&gt;
        &lt;a href="https://lukefrauhiger.com" rel="noopener"&gt;
          &lt;img class="icon-img" alt="external link icon" src="https://res.cloudinary.com/practicaldev/image/fetch/s--WsHTbjfA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/link.svg"&gt;https://lukefrauhiger.com
        &lt;/a&gt;
    &lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>ui</category>
      <category>webdesign</category>
      <category>designprinciples</category>
      <category>analyzemyui</category>
    </item>
    <item>
      <title>Full Stack Development Starter 1 - React and Nodejs</title>
      <dc:creator>Luke Frauhiger</dc:creator>
      <pubDate>Mon, 13 Apr 2020 16:13:36 +0000</pubDate>
      <link>https://dev.to/lukefrogger/full-stack-development-starter-1-react-and-nodejs-a16</link>
      <guid>https://dev.to/lukefrogger/full-stack-development-starter-1-react-and-nodejs-a16</guid>
      <description>&lt;p&gt;When I went from being a UI &amp;amp; UX designer to a programmer I had literally no idea what I was doing. What made it worse was that I didn’t have any mentorship or guidance on how to move forward. All of my coworkers were Salesforce developers and hadn’t built any full-stack web apps with industry standard technology. It was up to me to pave the way forward with a new technology stack and deployment strategy.&lt;/p&gt;

&lt;p&gt;With no idea of what to even Google and almost no concept of what it takes to build a full-stack application, I headed into the technological wilderness to find my path. After several weeks of research about coding languages and hosting platforms I finally had a full-stack application completed and running on Node.js and Angular 2+. &lt;/p&gt;

&lt;p&gt;I often wonder what this project, or even the next couple of years of development, would have looked like if I had mentorship while figuring all of this out. That’s my goal with this article - to act as a simple mentor and get you started down the full stack trail. &lt;/p&gt;

&lt;h4&gt;
  
  
  Three Part Series
&lt;/h4&gt;

&lt;p&gt;We’re gonna be working with React and using three different server-side languages: Javascript(Node.js), Ruby, and Python. Node, Ruby, and Python are some of the most widely used server-side languages in full-stack development because they’re very easy to spin-up on and are quite fast to develop on. Each of them also has a tightly bound middleware that makes serving HTTP(s) requests incredibly easy. For Node this is Express.js, for Ruby it’s Rails and for Python it’s Django. We’ll get into this more later on. But I’ll stop gabbing now and we can get to the 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fidxoksa7xlxdi0yn5q27.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fidxoksa7xlxdi0yn5q27.jpg" alt="nodejs plus reacts"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  React and Node.js
&lt;/h4&gt;

&lt;p&gt;We’re gonna start with a full javascript stack. This can make developing and deploying full-stack applications a breeze since you only need to know one language. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: I’m primarily a javascript developer but it’s beneficial to learn a scripting language like Python or Java. But you do you. Javascript all-the-way does work!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There are several ways you can structure the client and server folders, but for today’s example, we’re going to keep it as simple as possible! That way you can expand it on your own in the future!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;br&gt;
Node.js installed - &lt;a href="https://nodejs.org/en/download/" rel="noopener noreferrer"&gt;You can download it here&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  Get Started
&lt;/h4&gt;

&lt;p&gt;First things first - let’s create our React app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npx create-react-app react-node
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;react-node
&lt;span class="nv"&gt;$ &lt;/span&gt;yarn build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you’ve never used npx before - it’s basically an execution library. Instead of having to install create-react-app globally and then use the global command to create the app, you can use npx!&lt;/p&gt;

&lt;p&gt;At this point our React app is ready to go! We’re not going to do anything else with it right now since all we’re trying to do is serve it from a server.&lt;/p&gt;

&lt;p&gt;We’ll need to add Express to our project and then create a file. I’ll name mine server.js.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;yarn add express
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, open the file and paste these lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&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;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// instantiates express so we can use the middleware functions&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="c1"&gt;// Node’s native tool for working with files. &lt;/span&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="c1"&gt;// set a default port in case the host isn’t configured with one&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="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&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;use&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;build&lt;/span&gt;&lt;span class="dl"&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;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;sendFile&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="o"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;build/index.html&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="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;`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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since the file is a javascript file and we’ll  the &lt;code&gt;node&lt;/code&gt; command to start it up, the runtime is established as Node.js. &lt;/p&gt;

&lt;p&gt;On 2 two we’ve instantiated “app” as our Express application. Just like REST requests, Express has &lt;code&gt;get&lt;/code&gt;, &lt;code&gt;post&lt;/code&gt;, &lt;code&gt;put&lt;/code&gt;, and &lt;code&gt;delete&lt;/code&gt; functions. But if you’d like to use a single middleware function for all of the HTTP verbs, the &lt;code&gt;use&lt;/code&gt; function is your jam. &lt;/p&gt;

&lt;p&gt;On line 6 the Express app loads the build folder. Without this line the code would fail since Express wouldn’t be able to send the index.html file to the browser. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;app.use(...)&lt;/code&gt; function is what actually serves the root of our React app to the browser. Notice that it’s only being served when on a GET request, but it is serving the file at all routes. This way when our React app begins routing, the server is returning the index.html file and making sure the React app is running. &lt;/p&gt;

&lt;p&gt;To serve your app, make sure you’re in the root of the project and type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;node server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whala! Full-stack app - done. You’re serving your pre-built React app with Express.&lt;br&gt;
But let’s add one more route to make sure you’re well on your way to becoming a full-stack developer. &lt;/p&gt;

&lt;p&gt;First, let’s add the body-parser library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;yarn add body-parser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s import it and setup our new route:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&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;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="o"&gt;+&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bodyParser&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;body-parser&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;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;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&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;use&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;build&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;span class="o"&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;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bodyParser&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="o"&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;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/new-route&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="o"&gt;+&lt;/span&gt;   &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&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;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;   &lt;span class="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="o"&gt;+&lt;/span&gt;       &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;greeting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Hello &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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;   &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&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;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;sendFile&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="o"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;build/index.html&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="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;`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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This new route will take a POST request at a route matching “/new-route” and return an object with a greeting. Notice that we’ve also added another &lt;code&gt;app.use(...)&lt;/code&gt; function that will parse the value of the body in the req object. &lt;/p&gt;

&lt;p&gt;Now onto the React!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="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="nx"&gt;logo&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;./logo.svg&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="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;greeting&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setGreeting&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="o"&gt;+&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="s2"&gt;/new-route&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="o"&gt;+&lt;/span&gt;   &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;   &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&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;Content-Type&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;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;   &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;   &lt;span class="na"&gt;body&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Luke Duke&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="o"&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="o"&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="o"&gt;+&lt;/span&gt;       &lt;span class="nf"&gt;setGreeting&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;greeting&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;   &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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;error&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
 &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
     &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;header&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App-header"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
       &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;logo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App-logo"&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"logo"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
       &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
         Edit &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;code&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;src/App.js&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;code&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; and save to reload.
       &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
       + &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;greeting&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
       &lt;span class="o"&gt;+&lt;/span&gt;  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;greeting&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
       &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt;
       &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;
         &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App-link"&lt;/span&gt;
         &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"https://reactjs.org"&lt;/span&gt;
         &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"_blank"&lt;/span&gt;
         &lt;span class="na"&gt;rel&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"noopener noreferrer"&lt;/span&gt;
       &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
         Learn React
       &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
     &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;We added the “useState” import and added a hook for the response from the server. We also added a &lt;code&gt;fetch()&lt;/code&gt; function that POSTs into our server with a name. The JSX renders the greeting when it’s set. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: You do not have to return an object from the Express app. Typically real world applications return a non-string variable, but you can return any type from Express.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Finally, rebuild the React and start up the server to see your app work!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;yarn build
&lt;span class="nv"&gt;$ &lt;/span&gt;node server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that is our Javascript all-the-way example! There is a ton of great documentation on the Express.js Framework page to help you along on your way. &lt;/p&gt;

&lt;p&gt;Stay tuned for articles on serving React with Ruby and Python.&lt;/p&gt;

&lt;p&gt;This article is cross-posted &lt;a href="https://lukefrauhiger.com/blog/full-stack-development-starter-1-react-and-nodejs" rel="noopener noreferrer"&gt;on my website as well.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>react</category>
      <category>fullstackdevelopment</category>
    </item>
  </channel>
</rss>
