<?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: Israel Muñoz</title>
    <description>The latest articles on DEV Community by Israel Muñoz (@israelmuca).</description>
    <link>https://dev.to/israelmuca</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%2F120734%2F3fbf630d-d034-4c0a-9fc0-71bcf3601dbc.jpg</url>
      <title>DEV Community: Israel Muñoz</title>
      <link>https://dev.to/israelmuca</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/israelmuca"/>
    <language>en</language>
    <item>
      <title>Tutorial: International API - i18n + validation in Node.js' Express</title>
      <dc:creator>Israel Muñoz</dc:creator>
      <pubDate>Mon, 04 Mar 2019 08:04:41 +0000</pubDate>
      <link>https://dev.to/israelmuca/tutorial-international-api---i18n--validation-in-nodejs-express-4pn1</link>
      <guid>https://dev.to/israelmuca/tutorial-international-api---i18n--validation-in-nodejs-express-4pn1</guid>
      <description>

&lt;p&gt;&lt;em&gt;This post was originally published on &lt;a href="https://israelmuca.dev/blog/how-to-international-api-i18n-validation-in-node-js-for-your-api"&gt;israelmuca.dev&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Recently, I was working on a project that has an &lt;a href="https://en.wikipedia.org/wiki/Internationalization_and_localization"&gt;i18n&lt;/a&gt; requirement. I needed the API to validate incoming user data, and depending on that data, return the specific success or error messages in the user’s provided language.  &lt;/p&gt;

&lt;p&gt;Regarding the actual translations, I wanted to easily provide the backend with the messages in both languages (Spanish and English to begin with), and I wanted to be able to eventually support more languages, being able to hire a translator if needed, and having him modify them “on the go” without requiring help from a developer.  &lt;/p&gt;

&lt;p&gt;So I started researching how to fulfill those requirements, and I ran into some hiccups along the way, thus, I thought it’d be nice to create a tutorial with my proposed (and implemented) solution.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s code!
&lt;/h2&gt;

&lt;p&gt;This tutorial uses ES6, Node.js and Express, creating a server that will be responding the calls.&lt;br&gt;
I’ve included a working solution with basic testing, you can go ahead and check that out in this &lt;a href="https://github.com/israelmuca/express-i18n-api"&gt;repository&lt;/a&gt;, or work through the code step-by-step with me!  &lt;/p&gt;

&lt;h3&gt;
  
  
  Libraries
&lt;/h3&gt;

&lt;p&gt;We’ll be using some battle tested libraries to speed up our development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;express&lt;/strong&gt;, to create/manage the server&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;express-locale&lt;/strong&gt;, to get the user’s locale&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;body-parser&lt;/strong&gt;, to get the user’s input&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;express-validator&lt;/strong&gt;, to validate the user’s input&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;node-polyglot&lt;/strong&gt;, by Airbnb, to help us manage languages&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;object.fromentries&lt;/strong&gt;, to convert an Array into an Object
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And since we’ll be using ES6, we’ll also be needing babel!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;@babel/cli&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;@babel/core&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;@babel/preset-env&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So let’s get to the console and create the project&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;i18n-validation
&lt;span class="nb"&gt;cd &lt;/span&gt;i18n-validation
npm init
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For this use case, we'll leave all the defaults that npm gives us, except for the default entry which I changed to &lt;strong&gt;server.js&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;Now, lets install our main dependencies&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i express express-locale body-parser express-validator node-polyglot object.fromentries
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, let’s install our development dependencies&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i @babel/cli @babel/core @babel/preset-env &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, all we need to do is add another file:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch&lt;/span&gt; .babelrc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And inside, we’ll write:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"presets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"@babel/preset-env"&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you’re going to source control your project, don ’t forget to add a &lt;code&gt;.gitignore&lt;/code&gt; with &lt;code&gt;node_modules&lt;/code&gt; in it, to avoid committing them.  &lt;/p&gt;

&lt;p&gt;Remember that we'll be using ES6, and we need to do some extra steps to be able to do so, so let's go ahead and change our scripts in the &lt;code&gt;package.json&lt;/code&gt;:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"server.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"clean"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"rm -rf dist &amp;amp;&amp;amp; mkdir dist"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"transpile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"babel -d ./dist ./src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"npm run clean &amp;amp;&amp;amp; npm run transpile"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"npm run build &amp;amp;&amp;amp; node ./dist/server.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"echo &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Error: no test specified&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; exit 1"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;We’re using several scripts and daisy-chaining some of them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;clean&lt;/code&gt; to create the &lt;code&gt;dist&lt;/code&gt; folder that will hold the ES5 transpiled code.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;transpile&lt;/code&gt; to transpile the code from ES6 to ES5.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;build&lt;/code&gt; runs &lt;code&gt;clean&lt;/code&gt; and afterwards, &lt;code&gt;transpile&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;start&lt;/code&gt; runs &lt;code&gt;build&lt;/code&gt; and afterwards, the &lt;code&gt;server.js&lt;/code&gt; file with node from the new ES5 transpiled &lt;code&gt;dist&lt;/code&gt; folder.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;test&lt;/code&gt; is empty and won't be covered in the tutorial, but the &lt;a href="https://github.com/israelmuca/express-i18n-api/"&gt;repository&lt;/a&gt; includes &lt;a href="https://github.com/israelmuca/express-i18n-api/blob/master/src/tests/i18n.tests.js"&gt;basic tests&lt;/a&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Finally, let’s create the &lt;code&gt;src&lt;/code&gt; folder and inside, the &lt;code&gt;server.js&lt;/code&gt; file:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;src
&lt;span class="nb"&gt;cd &lt;/span&gt;src
&lt;span class="nb"&gt;touch &lt;/span&gt;server.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let’s now get express going by modifying the &lt;code&gt;server.js&lt;/code&gt;&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Import dependencies&lt;/span&gt;
&lt;span class="c1"&gt;// =============================================================&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'express'&lt;/span&gt;

&lt;span class="c1"&gt;// Setup the express router&lt;/span&gt;
&lt;span class="c1"&gt;// =============================================================&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;router&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="c1"&gt;// Set the port to be used&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;8080&lt;/span&gt;

&lt;span class="c1"&gt;// Start the server!&lt;/span&gt;
&lt;span class="c1"&gt;// =============================================================&lt;/span&gt;
&lt;span class="nx"&gt;router&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;`App running on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;By now, we can run:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If all’s good, the console should be telling us that we’re running on port 8080.&lt;br&gt;
And with that, we’ll have a server… &lt;em&gt;that does nothing!&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt;Now, we need to &lt;strong&gt;actually&lt;/strong&gt; get it going.&lt;br&gt;&lt;br&gt;
So we need to add more dependencies:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Import dependencies&lt;/span&gt;
&lt;span class="c1"&gt;// =============================================================&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'express'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;createLocaleMiddleware&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'express-locale'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;bodyParser&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'body-parser'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And we need to set them up on the server&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Setup the express router&lt;/span&gt;
&lt;span class="c1"&gt;// =============================================================&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;router&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="c1"&gt;// Set the port to be used&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;8080&lt;/span&gt;

&lt;span class="c1"&gt;// Add data parsing to express&lt;/span&gt;
&lt;span class="nx"&gt;router&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;bodyParser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;urlencoded&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;extended&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="nx"&gt;router&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;bodyParser&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="c1"&gt;// Get the user's locale, and set a default in case there's none&lt;/span&gt;
&lt;span class="nx"&gt;router&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;createLocaleMiddleware&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="s2"&gt;"priority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"accept-language"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"en_US"&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With these changes, now we’re checking on the user’s locale and parsing the data they’re sending. However, we need to add &lt;code&gt;polyglot&lt;/code&gt; to express.&lt;/p&gt;

&lt;p&gt;For that, we’ll first be creating our .js file where the translations will be living&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;i18n
&lt;span class="nb"&gt;cd &lt;/span&gt;i18n
&lt;span class="nb"&gt;touch &lt;/span&gt;i18n.js
&lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let’s open this new file, where we’ll have two constants, an array that will show what languages are available&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;availableLangs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'es'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'en'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And an object that will contain the actual translations&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;en&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Error messages&lt;/span&gt;
        &lt;span class="s1"&gt;'emailRequiredField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"'email' is a required field."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'emailIsEmail'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"This is not a valid email address."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'passwordRequiredField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"'password' is a required field."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="c1"&gt;// Success messages&lt;/span&gt;
        &lt;span class="s1"&gt;'loginSuccessful'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"You've successfully logged in."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'emailSent'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Your password recovery email was sent."&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;es&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Mensajes de error&lt;/span&gt;
        &lt;span class="s1"&gt;'emailRequiredField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"'email' es un campo requerido."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'emailIsEmail'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Este no es un email válido."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'passwordRequiredField'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"'password' es un campo requerido."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="c1"&gt;// Mensajes de éxito&lt;/span&gt;
        &lt;span class="s1"&gt;'loginSuccessful'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Has iniciado sesión exitosamente."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'emailSent'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Tu correo de recuperación de contraseña ha sido enviado."&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;With our messages ready, we’ll go ahead and create a middleware for express, that will import polyglot and these translations, to include them in the actual express request.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;utilities
&lt;span class="nb"&gt;cd &lt;/span&gt;utilities
&lt;span class="nb"&gt;touch &lt;/span&gt;startPolyglot.js
&lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Open this new file, where we’ll import both polyglot and the translations&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Polyglot&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'node-polyglot'&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;messages&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'../i18n/i18n'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And we’ll create a function that will be used on every request as an Express’ middleware. It will get the user’s locale (which we got in the &lt;code&gt;server.js&lt;/code&gt;), create an instance of Polyglot, and load it with the proper messages depending on the user’s language&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startPolyglot&lt;/span&gt; &lt;span class="o"&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="nx"&gt;next&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;// Get the locale from express-locale&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;locale&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;locale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;language&lt;/span&gt;

    &lt;span class="c1"&gt;// Start Polyglot and add it to the req&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;polyglot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Polyglot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;// Decide which phrases for polyglot&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;locale&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'es'&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;polyglot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;es&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="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;polyglot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;en&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you remember, our &lt;code&gt;server.js&lt;/code&gt; uses the &lt;code&gt;createLocaleMiddleware&lt;/code&gt; to set the current locale, which lives on &lt;code&gt;req.locale.language&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So we get that value, and for our use case, check if it is &lt;em&gt;es&lt;/em&gt; for Spanish or &lt;em&gt;en&lt;/em&gt; for English (our default in case it’s neither), and load the proper messages for the language, which are added to the Express’ ‘req’ object through polyglot’s &lt;em&gt;extend&lt;/em&gt; function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding Polyglot to Express
&lt;/h3&gt;

&lt;p&gt;Now, we need to add this middleware to Express on the &lt;code&gt;server.js&lt;/code&gt;, both by importing it, and adding it &lt;strong&gt;AFTER&lt;/strong&gt; we create the &lt;em&gt;locale middleware&lt;/em&gt;, as polyglot uses it.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;startPolyglot&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'./utilities/startPolyglot'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Add this line at the very top, with the rest of the imports.&lt;/p&gt;
&lt;/blockquote&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Start polyglot and set the language in the req with the phrases to be used&lt;/span&gt;
&lt;span class="nx"&gt;router&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;startPolyglot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Add this lines after the &lt;code&gt;createLocaleMiddleware&lt;/code&gt; function is called.  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There, now our server is ready to send error or success messages in either Spanish or English, however, where will these messages originate?&lt;/p&gt;

&lt;h3&gt;
  
  
  Routes
&lt;/h3&gt;

&lt;p&gt;So Express needs to know what to do with the different type of calls on the different routes.&lt;br&gt;
For that, we’ll start listening for calls in our server by first creating a routes folder and file.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;routes
&lt;span class="nb"&gt;cd &lt;/span&gt;routes
&lt;span class="nb"&gt;touch &lt;/span&gt;auth.routes.js
&lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let’s open this file and add the following code:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Routes =============================================================&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;router&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;// POST route to mock a log endpoint&lt;/span&gt;
    &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/api/login"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// POST route to mock a forgotten password endpoint&lt;/span&gt;
    &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/api/forgot-password"&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;What this code will do, is export a function that will take the Express instance as a parameter to create the actual routes we’ll be using in our test API. For now, it’s missing parameters, since it’s only adding the first one, which tells express the route to listen to. After that parameter, we may add as many Express’ middlewares as we need. We will be adding middleware to do the input data validation, the error processing in case there’s any, and finally, if all’s good, respond with a success message if there were no errors with the validation.&lt;/p&gt;

&lt;p&gt;Now, let’s go ahead and add it to the &lt;code&gt;server.js&lt;/code&gt; right before we start it&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Routes&lt;/span&gt;
&lt;span class="c1"&gt;// =============================================================&lt;/span&gt;
&lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"./routes/auth.routes"&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This line should be added right before we start our server with &lt;code&gt;router.listen&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So now our API is listening for POST requests on &lt;code&gt;localhost:8080/api/login&lt;/code&gt; and &lt;code&gt;localhost:8080/api/forgot-password&lt;/code&gt;, but we still have no functionality, let’s get there.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validating user’s input
&lt;/h3&gt;

&lt;p&gt;So it’s time to validate data, for that, we’ll be using express-validator, which is a handy middleware that lets us validate data as it comes from the req object, setting specific error messages for each of the parameters that we’re expecting.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;validator
&lt;span class="nb"&gt;cd &lt;/span&gt;validator
&lt;span class="nb"&gt;touch &lt;/span&gt;auth.validator.js
&lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, open &lt;code&gt;auth.validator.js&lt;/code&gt; and we’ll first import the &lt;code&gt;check&lt;/code&gt; function from &lt;code&gt;express-validator&lt;/code&gt;.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;check&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'express-validator/check'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next, we’ll create a function that will be exported, which we’ll be using as middleware in our &lt;code&gt;auth.routes.js&lt;/code&gt;. This function receives a String, which we define based on the use case of that route, inside we’ll use the check function that was just imported, to validate the data we’re receiving.&lt;br&gt;
We’ll be using a &lt;code&gt;switch&lt;/code&gt; for that, so we can reuse the same validator both for the &lt;code&gt;login&lt;/code&gt;, and the &lt;code&gt;forgot-password&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;Here’s the code:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;validator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;functionName&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;functionName&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="s1"&gt;'login'&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="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;withMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'emailRequiredField'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isEmail&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;withMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'emailIsEmail'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

                &lt;span class="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;withMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'passwordRequiredField'&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;case&lt;/span&gt; &lt;span class="s1"&gt;'forgotPassword'&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="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;withMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'emailRequiredField'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isEmail&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;withMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'emailIsEmail'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We won’t go deep into the details of how the &lt;code&gt;check&lt;/code&gt; function works, but it basically adds another object inside of the &lt;code&gt;req&lt;/code&gt; which will store the errors (if there’s any).  &lt;/p&gt;

&lt;p&gt;What’s important to note though, is the fact that instead of setting normal error messages, we’re using the variables that we created on our i18n file!  &lt;/p&gt;

&lt;p&gt;Why? Because we want to use those &lt;code&gt;keys&lt;/code&gt; from our &lt;code&gt;i18n.js&lt;/code&gt; in whatever language the user chooses, so we need to check the object for all the possible error messages, and check our translated errors object, and swap the error string with the actual error message that we wrote in the user’s language... but not yet.  &lt;/p&gt;

&lt;p&gt;For now, we’ll be adding this validator into our route file by going to &lt;code&gt;auth.routes.js&lt;/code&gt; and importing it:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;validator&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'../validator/auth.validator'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This line should go at the very top, before our &lt;code&gt;module.exports&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, we’ll use it on our actual routes:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// POST route to mock a login endpoint&lt;/span&gt;
&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/api/login"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'login'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;// POST route to mock a forgotten password endpoint&lt;/span&gt;
&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/api/forgot-password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'forgotPassword'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So now our server listens to post requests on those two routes, and validates the incoming payload.&lt;br&gt;
Now we need to make sure to transform those strings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Translating the errors
&lt;/h3&gt;

&lt;p&gt;For this, we’ll create another Express middleware which will check all the errors (if any) and convert them into strings in the user’s language.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;utilities
&lt;span class="nb"&gt;touch &lt;/span&gt;processErrors.js
&lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Go ahead and open this new file, where we’ll import another function from &lt;code&gt;express-validator&lt;/code&gt; and the npm package &lt;code&gt;object.fromentries&lt;/code&gt;.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;validationResult&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'express-validator/check'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fromEntries&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'object.fromentries'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, we need to create the function that will do the translation:&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;translateMessages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errObj&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Convert the errObj to an Array&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;errArr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errObj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// For each array(err), compare the error msg with the polyglot phrases, and replace it.&lt;/span&gt;
    &lt;span class="nx"&gt;errArr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&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;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&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;polyglot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;phrases&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;phrase&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;phrase&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;msg&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;polyglot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;phrase&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="c1"&gt;// Return a function that converts the Array to an Object&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;fromEntries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errArr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In this code, we’re receiving both the error Object created with &lt;code&gt;express-validator&lt;/code&gt; (which we’ll extract from the &lt;code&gt;req&lt;/code&gt; object with the &lt;code&gt;validationResult&lt;/code&gt; function in a bit), and the Express’ &lt;code&gt;req&lt;/code&gt; object.  &lt;/p&gt;

&lt;p&gt;We’re creating an &lt;code&gt;Array&lt;/code&gt; from the &lt;code&gt;errObj&lt;/code&gt;, and then, for each entry, we’re taking the string we set as the error variable, and comparing it with the keys from the translation messages, changing the string in the &lt;code&gt;errArr&lt;/code&gt; &lt;em&gt;(each "err[1].msg")&lt;/em&gt; to the actual phrase in polyglot in the desired language &lt;em&gt;(each "phrase")&lt;/em&gt;.  &lt;/p&gt;

&lt;p&gt;Finally, we use the imported &lt;code&gt;fromEntries&lt;/code&gt; function, to convert the Array back into an Object and return it.  &lt;/p&gt;

&lt;p&gt;Now, in that same file, we’ll export a middleware function that will be using this &lt;code&gt;translateMessages&lt;/code&gt; function to process the errors (if any).&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;procErr&lt;/span&gt; &lt;span class="o"&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="nx"&gt;next&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;// Verifies if there were validation errors added to the request&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validationErrors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;validationResult&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="c1"&gt;// If there were errors in the validation&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;validationErrors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Return the result of the function below&lt;/span&gt;
        &lt;span class="k"&gt;return&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;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&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="nx"&gt;translateMessages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;validationErrors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mapped&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="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="c1"&gt;// If no errors, go!&lt;/span&gt;
        &lt;span class="nx"&gt;next&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;In this code we receive the regular &lt;code&gt;req, res, next&lt;/code&gt; from Express, and we first verify if there were any errors using express-validator’s &lt;code&gt;validationResult&lt;/code&gt;.&lt;br&gt;
Then, we check if there are errors, and if there are any, we return them with Express’ response.&lt;br&gt;
Check that return closely, as you can see, we send the results of the &lt;code&gt;translateMessages&lt;/code&gt; function that is receiving the &lt;code&gt;validationErrors&lt;/code&gt;, and the &lt;code&gt;req&lt;/code&gt; object.&lt;br&gt;
We also have an &lt;code&gt;else&lt;/code&gt;, that when there are no validation errors, calls &lt;code&gt;next()&lt;/code&gt; to continue to the next Express middleware.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sending the errors
&lt;/h3&gt;

&lt;p&gt;So we're able to manage the errors by converting them from the string to their translated version, and packaging it in an object, ready to be sent back to the user if needed.  &lt;/p&gt;

&lt;p&gt;Now, we just need to use that file!&lt;br&gt;
Let's go back to our &lt;code&gt;auth.routes.js&lt;/code&gt; file and make use of this new function by importing it:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;procErr&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'../utilities/processErrors'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As I mentioned earlier, we built it as an Express Middleware, so we can just add it inside of our chain of events.  &lt;/p&gt;

&lt;p&gt;And then using it in the actual routes:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Routes =============================================================&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;router&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;// POST route to mock a login endpoint&lt;/span&gt;
    &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/api/login"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'login'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;procErr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// POST route to mock a forgotten password endpoint&lt;/span&gt;
    &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/api/forgot-password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'forgotPassword'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;procErr&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;
  
  
  Moving past errors
&lt;/h3&gt;

&lt;p&gt;So now, our code is ready to handle errors in both languages, but what about success messages?  &lt;/p&gt;

&lt;p&gt;We already have those in the i18n.js file, but we’re not using them.&lt;br&gt;
Lets write the final piece of code:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;controller
&lt;span class="nb"&gt;cd &lt;/span&gt;controller
&lt;span class="nb"&gt;touch &lt;/span&gt;auth.controller.js
&lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Open this new file, where we’ll create a couple of exports to handle the final steps of the &lt;code&gt;login&lt;/code&gt; and &lt;code&gt;forgot-password&lt;/code&gt; processes.&lt;br&gt;
If express didn’t return an error on the last step, theoretically, there are no errors on the user's data, so we’ll go ahead and send success messages here.  &lt;/p&gt;

&lt;p&gt;Of course, on a real world application we’d go to the database and check the user’s data and confirm it is actually correct and &lt;em&gt;not just valid&lt;/em&gt;, but that’s beyond the scope of this tutorial.  &lt;/p&gt;

&lt;p&gt;So let’s write some code on the &lt;code&gt;auth.controller.js&lt;/code&gt;.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;login&lt;/span&gt; &lt;span class="o"&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="c1"&gt;// If no validation errors, get the req.body objects that were validated and are needed&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;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="p"&gt;}&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="c1"&gt;// Here, we would make use of that data, validating it against our database, creating a JWT token, etc...&lt;/span&gt;

    &lt;span class="c1"&gt;// Since all the validations passed, we send the loginSuccessful message, which would normally include a JWT or some other form of authorization&lt;/span&gt;
    &lt;span class="k"&gt;return&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;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&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;auth&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;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;polyglot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'loginSuccessful'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="na"&gt;token&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="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forgotPassword&lt;/span&gt; &lt;span class="o"&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="c1"&gt;// If no validation errors, get the req.body objects that were validated and are needed&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;email&lt;/span&gt; &lt;span class="p"&gt;}&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="c1"&gt;// Here, we would make use of that data, validating it against our database, creating a JWT token, etc...&lt;/span&gt;

    &lt;span class="c1"&gt;// Since all the validations passed, we send the emailSent message&lt;/span&gt;
    &lt;span class="k"&gt;return&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;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&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;auth&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;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;polyglot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'emailSent'&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;As you can see, both functions are exported to be used in the &lt;code&gt;routes&lt;/code&gt; file, and both deconstruct the &lt;code&gt;req.body&lt;/code&gt; to get the values we need to use.  &lt;/p&gt;

&lt;p&gt;I should emphasize that in both cases, further validation would be done in the controller, such as going to the database and checking if the user’s actually exist and are authorized to either login (and their password is correct) or if they’re not banned and are authorized to request a new password.  &lt;/p&gt;

&lt;p&gt;We’re assuming all of those things happened already, and just sending the response using Express’ &lt;code&gt;res&lt;/code&gt; which includes the message with:&lt;br&gt;
&lt;code&gt;req.polyglot.t('key')&lt;/code&gt;.&lt;br&gt;
This will take the value assigned to that key in the user’s selected language, and return that message.  &lt;/p&gt;

&lt;p&gt;Now, we need to go back to our &lt;code&gt;routes&lt;/code&gt; to add this two functions there.&lt;br&gt;
The final version of &lt;code&gt;auth.routes.js&lt;/code&gt; should now look something like this:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;validator&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'../validator/auth.validator'&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;procErr&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'../utilities/processErrors'&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;login&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;forgotPassword&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'../controller/auth.controller'&lt;/span&gt;

&lt;span class="c1"&gt;// Routes =============================================================&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;router&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;// POST route to mock a log endpoint&lt;/span&gt;
    &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/api/login"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'login'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;procErr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// POST route to mock a forgotten password endpoint&lt;/span&gt;
    &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/api/forgot-password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'forgotPassword'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;procErr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;forgotPassword&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As you can see, we’re importing both &lt;code&gt;login&lt;/code&gt; and &lt;code&gt;forgotPassword&lt;/code&gt;, and adding them in the &lt;code&gt;post&lt;/code&gt; as the final parameter.&lt;br&gt;
These last functions respond with the success messages when everything is ok!&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;p&gt;Let's check that our API is working as expected.  &lt;/p&gt;

&lt;p&gt;Go ahead and run &lt;code&gt;npm run start&lt;/code&gt;. This will build our transpile our code and start the server. If we followed all steps, we should see: &lt;code&gt;App running on port 8080&lt;/code&gt; in our console.  &lt;/p&gt;

&lt;p&gt;Now open up &lt;strong&gt;Postman&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set the &lt;em&gt;Method&lt;/em&gt; to &lt;strong&gt;POST&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Set the &lt;em&gt;Request URL&lt;/em&gt; to &lt;strong&gt;localhost:8080/api/login&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Set the &lt;em&gt;Headers&lt;/em&gt; key to &lt;strong&gt;Accept-Language&lt;/strong&gt; and the value to &lt;strong&gt;es_MX&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Set the &lt;em&gt;Body&lt;/em&gt; to {
"email": "&lt;a href="mailto:test@email.com"&gt;test@email.com&lt;/a&gt;"
}&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And click on &lt;strong&gt;Send&lt;/strong&gt;. If all went well, you should see this response:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"param"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"msg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"'password' es un campo requerido."&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;You can play around with the &lt;em&gt;Request URL&lt;/em&gt; trying both routes or the &lt;em&gt;Headers&lt;/em&gt; setting either &lt;code&gt;en_US&lt;/code&gt; or &lt;code&gt;es_MX&lt;/code&gt; or another option, also, try and modify the &lt;em&gt;Body&lt;/em&gt; to see the different responses from the API.  &lt;/p&gt;

&lt;p&gt;So that's it!&lt;br&gt;
Now, hopefully you have a clear understanding of how to set up an Express API that responds properly whether your &lt;code&gt;headers&lt;/code&gt; are set to &lt;code&gt;es_MX&lt;/code&gt; or &lt;code&gt;en_US&lt;/code&gt;. Both for error and success messages.  &lt;/p&gt;

&lt;p&gt;If you have any questions, please go ahead and leave a comment below, or create an issue on the repository, or send me a &lt;a href="https://twitter.com/IsraelMuCa/"&gt;tweet&lt;/a&gt;.&lt;br&gt;
I'm more than glad to help.  &lt;/p&gt;

&lt;p&gt;Read you soon!&lt;/p&gt;


</description>
      <category>express</category>
      <category>i18n</category>
      <category>tutorial</category>
      <category>node</category>
    </item>
    <item>
      <title>JAMstack and CD pipelines: Create a blog with Nuxt, Netlify CMS and Netlify</title>
      <dc:creator>Israel Muñoz</dc:creator>
      <pubDate>Sat, 02 Mar 2019 04:04:01 +0000</pubDate>
      <link>https://dev.to/israelmuca/jamstack-and-cd-pipelines-create-a-blog-with-nuxt-netlify-cms-and-netlify-2mml</link>
      <guid>https://dev.to/israelmuca/jamstack-and-cd-pipelines-create-a-blog-with-nuxt-netlify-cms-and-netlify-2mml</guid>
      <description>&lt;p&gt;&lt;em&gt;This post was originally published on &lt;a href="https://israelmuca.dev/blog/jamstack-and-cd-pipelines-create-a-blog-with-nuxt-netlify-cms-and-netlify/"&gt;israelmuca.dev&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The "old" ways
&lt;/h2&gt;

&lt;p&gt;Say you wanted to create a blog, you could easily run a Wordpress site, with a Linux server distributing your content. On each page load, the server would generate the webpages, and serve them to the user.&lt;br&gt;
Every request puts the server to work.&lt;br&gt;
It's a perfectly viable option, although slower compared to more modern options, more insecure as you have to be doing the updates on your server (or paying more for a managed server), and it requires using PHP and having a database running.  &lt;/p&gt;
&lt;h2&gt;
  
  
  JAMstack to the rescue!
&lt;/h2&gt;

&lt;p&gt;So what is JAMstack? It stands for &lt;strong&gt;J&lt;/strong&gt;avaScript, &lt;strong&gt;A&lt;/strong&gt;PIs and &lt;strong&gt;M&lt;/strong&gt;arkup. A modern way of writing webpages that are compiled to static assets right before deploying. JavaScript handles the dynamics in your page, what were server-side processes, are now abstracted into APIs if needed, and your markup is compiled during deploys. Go ahead and read all about it on the &lt;a href="https://jamstack.org/"&gt;official webpage&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;The benefits that this approach has is that your webpage ends up being blazing fast and with all of your content precompiled, nothing has to be fetched every time the page is served and, you can host it in many many more places (and it's way cheaper (or even free, with &lt;a href="https://netlify.com"&gt;Netlify&lt;/a&gt;), as it is only HTML and JS files all while getting improved SEO with your page.&lt;br&gt;
Your page is also more secure! Since you don't have exposed APIs, you could even use Wordpress as a CMS but without the security risks or performance problems of running Wordpress itself.&lt;br&gt;
The performance is definitely worth mentioning again, as it is quite easy to make your site super fast.  &lt;/p&gt;

&lt;p&gt;There is one caveat though. Every time you change anything, you have to rebuild your assets, and deploy them... ugh... &lt;strong&gt;but wait!&lt;/strong&gt;, as that's where a CD pipeline comes into play!  &lt;/p&gt;
&lt;h2&gt;
  
  
  CD pipelines...?
&lt;/h2&gt;

&lt;p&gt;You've probably heard the terms CI/CD being thrown around, with CD sometimes referring to Continuous Delivery or Continuous Deployment. Arguments get quite long when debating about the PRECISE meaning of these words, as you can see in &lt;a href="https://stackoverflow.com/questions/28608015/continuous-integration-vs-continuous-delivery-vs-continuous-deployment"&gt;this Stack Overflow&lt;/a&gt; question.  &lt;/p&gt;

&lt;p&gt;In my case, I'm talking about Continuous Deployment, as explained by Netlify &lt;a href="https://www.netlify.com/docs/continuous-deployment/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Continuous deployment works by connecting a Git repository to a Netlify site and keeping the two in sync.&lt;/em&gt;   &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Easy peasy. We want our repo to be in sync with our site.  &lt;/p&gt;
&lt;h3&gt;
  
  
  But how?
&lt;/h3&gt;

&lt;p&gt;Netlify is an amazing &lt;a href="https://en.wikipedia.org/wiki/Platform_as_a_service/"&gt;PaaS&lt;/a&gt; that has SO MANY FEATURES, really, just to mention a few:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automated builds and deployments via webhooks straight from your Git repository.&lt;/li&gt;
&lt;li&gt;Rollbacks, as previous deployments are not erased.&lt;/li&gt;
&lt;li&gt;Continuous Integration tests.&lt;/li&gt;
&lt;li&gt;Deployment previews from Pull Requests.&lt;/li&gt;
&lt;li&gt;Free SSL certificates.&lt;/li&gt;
&lt;li&gt;A CDN.&lt;/li&gt;
&lt;li&gt;AND S O, M U C H, M O R E.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check out their &lt;a href="https://netlify.com/features/"&gt;features&lt;/a&gt; or dive straight into the &lt;a href="https://www.netlify.com/docs/"&gt;documentation&lt;/a&gt; pleeeeeaaaase. As everything I mentioned is included in their VERY generous free tier.&lt;br&gt;
So for our use case, we'll be using their automated build and deployment (as I am).  &lt;/p&gt;
&lt;h2&gt;
  
  
  Nuxt.js + Netlify, a match made in heaven
&lt;/h2&gt;

&lt;p&gt;In my case, I've been working with &lt;a href="https://vuejs.org"&gt;Vue.js&lt;/a&gt; and I wanted to build my blog with Vue, so for that, I used &lt;a href="https://nuxtjs.org"&gt;Nuxt.js&lt;/a&gt; which is a framework built on top of Vue that offers both Server Side Rendering (you need a Nuxt instance running, thus a server as well, a no-go for our project) and also offers Static Site Generator, which &lt;strong&gt;compiles&lt;/strong&gt; all of your fancy Vue code into plain HTML and JS. That's exactly what we need for Netlify! &lt;em&gt;OH YEAH!&lt;/em&gt;.  &lt;/p&gt;

&lt;p&gt;Every time you push your code to the repo, Netlify pulls the latest version, and in my case, runs &lt;code&gt;nuxt generate&lt;/code&gt; and then uploads the &lt;code&gt;/dist&lt;/code&gt; folder into their CDN. And that's it! Your latest version is live in a minute or two. No need to upload anything manually or check what version is uploaded... Everything is &lt;em&gt;automated&lt;/em&gt; now... Continuous Deployment FTW!  &lt;/p&gt;
&lt;h2&gt;
  
  
  Netlify CMS
&lt;/h2&gt;

&lt;p&gt;Last but not least. How can you manage your content like this?&lt;br&gt;
Remember that the &lt;a href="https://jamstack.org/best-practices/"&gt;JAMstack best practices&lt;/a&gt; mention that ideally, everything lives on your git, so anyone can, with a couple of clicks, get going and contribute to your project.  &lt;/p&gt;

&lt;p&gt;That's where &lt;a href="https://www.netlifycms.org/"&gt;Netlify's CMS&lt;/a&gt; comes in. It's an Open Source Software, that helps you use your Github as a 'database' in a sense. Allowing you to create blog posts directly into &lt;code&gt;.md&lt;/code&gt; files, which you can push into the repo to trigger the builds, creating new blog posts just like that.&lt;br&gt;
They have an easy to use interface, and even have an editorial workflow, that set articles to be deployed as Pull Requests on your Github, allowing you or your team to review them (using Netlify) before merging them.  &lt;/p&gt;

&lt;p&gt;All in all, these are amazing tools that let us create blazing fast sites, in a modern environment and require very little configuration for such an amazing final product.  &lt;/p&gt;
&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;For this, we'll only be needing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Github account&lt;/li&gt;
&lt;li&gt;Netlify account&lt;/li&gt;
&lt;li&gt;Vue/Nuxt understanding &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Fork the repo
&lt;/h2&gt;

&lt;p&gt;Using your Github account, go ahead and &lt;a href="https://github.com/israelmuca/israelmuca.dev/fork"&gt;click here&lt;/a&gt; to fork the repo or just &lt;a href="https://github.com/israelmuca/israelmuca.dev"&gt;clone it&lt;/a&gt;.  &lt;/p&gt;
&lt;h2&gt;
  
  
  Build Setup
&lt;/h2&gt;

&lt;p&gt;Install all the dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, you can run the code in development with:&lt;br&gt;
&lt;/p&gt;

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



&lt;p&gt;This will serve your page in &lt;code&gt;localhost:3000&lt;/code&gt; with hot reload.  &lt;/p&gt;

&lt;p&gt;Once you're ready to generate your static assets for production:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run generate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This will create a &lt;code&gt;/dist&lt;/code&gt; folder with the assets. This folder is not committed.&lt;br&gt;
This is what Netlify will be building on their server, and then uploading the results to their CDN. &lt;em&gt;We don't need to do this manually ever.&lt;/em&gt; We just do it for the sake of watching what happens inside Netlify.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Configure your &lt;em&gt;new&lt;/em&gt; repo
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Netlify CMS
&lt;/h3&gt;

&lt;p&gt;You'll need to define your fields and files for your content. I'm using defaults very similar to what you can see in here, &lt;a href="https://dev.to"&gt;dev.to&lt;/a&gt;. Mostly covering the title, description, and keywords for SEO purposes, also a little summary of the post as well as the main image which is used both in the ArticleCard.vue and the Header.vue in the blog post page.  &lt;/p&gt;

&lt;p&gt;You can configure these fields in: &lt;code&gt;static/admin/config.yml&lt;/code&gt;, and feel free to check the &lt;a href="https://www.netlifycms.org/docs/configuration-options/"&gt;Netlify CMS Documentation&lt;/a&gt; for extra customization.  &lt;/p&gt;

&lt;p&gt;While your local server is running, you can access &lt;a href="https://dev.tolocalhost:3000/admin/"&gt;localhost:3000/admin/&lt;/a&gt; to modify the content of your blog. You can also do it once it's deployed when you have the Netlify's address that's given to you.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Routes
&lt;/h3&gt;

&lt;p&gt;In here, both Nuxt and Nuxtdown work together to create the routes in the website.  &lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;pages&lt;/code&gt; directory, you'll find an &lt;code&gt;index.vue&lt;/code&gt; which is, as the name implies, the index of our site.&lt;br&gt;
&lt;strong&gt;This is handled by Nuxt&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;pages/blog/&lt;/code&gt; directory will work as a directory in our site as well (israelmuca.dev/blog/... in my case), which will hold all the blog posts that are created using the &lt;code&gt;_blogpost.vue&lt;/code&gt; template inside. It will be compiled once for each &lt;code&gt;.md&lt;/code&gt; in the &lt;code&gt;content/blog/&lt;/code&gt; directory. You can see how the content is fetched inside of that &lt;code&gt;.vue&lt;/code&gt; file.&lt;br&gt;
&lt;strong&gt;This is handled by Nuxtdown&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;You can configure Nuxtdown in: &lt;code&gt;nuxtdown.config.js&lt;/code&gt;, and please go ahead and check the &lt;a href="https://github.com/joostdecock/nuxtdown-module/blob/master/README.md"&gt;Nuxtdown Documentation&lt;/a&gt; to further understand what is happening or to change the functionality.  &lt;/p&gt;

&lt;h3&gt;
  
  
  The rest of the site
&lt;/h3&gt;

&lt;p&gt;The rest of the site is a regular Vue + Nuxt app, I tried to comment the code where I think it's needed the most, and you can configure Nuxt in: &lt;code&gt;nuxt.config.js&lt;/code&gt;, also, as usual, please check the &lt;a href="https://vuejs.org/v2/guide/"&gt;Vue.js&lt;/a&gt; and &lt;a href="https://nuxtjs.org/guide/"&gt;Nuxt.js&lt;/a&gt; documentation to further understand this code if you have any questions.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Congratulations
&lt;/h2&gt;

&lt;p&gt;By this point, you should have a fully functional Nuxt generated, Netlify hosted, blog site.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Issues
&lt;/h2&gt;

&lt;p&gt;If you have any problems implementing this, please don't hesitate and create a Github Issue or send me a &lt;a href="https://twitter.com/IsraelMuCa"&gt;tweet&lt;/a&gt;.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Thanks
&lt;/h2&gt;

&lt;p&gt;There's a phrase that I love and always try and remember:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If I have seen further it is by standing in the shoulders of Giants&lt;/em&gt;&lt;br&gt;
Isaac Newton&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Being true to that phrase, I have to acknowledge the many people that in one way or another contributed to this specific repo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/acgomezu"&gt;Andrea Gomez - with her design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://vuejs.org/"&gt;Vue.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nuxtjs.org/"&gt;Nuxt.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.netlifycms.org/"&gt;Netlify CMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/nuxtdown"&gt;Nuxtdown&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bulma.io"&gt;Bulma&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://prismjs.com/"&gt;Prism&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/renestalder/nuxt-netlify-cms-starter-template"&gt;renestalder's template&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.netlify.com/"&gt;Netlify&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks again, and read ya'll soon!  &lt;/p&gt;

</description>
      <category>jamstack</category>
      <category>nuxt</category>
      <category>netlify</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Hi! I'm Israel, and I'll introduce you to my corner of the web</title>
      <dc:creator>Israel Muñoz</dc:creator>
      <pubDate>Fri, 01 Mar 2019 17:46:24 +0000</pubDate>
      <link>https://dev.to/israelmuca/hi-im-israel-and-ill-introduce-you-to-my-corner-of-the-web-21po</link>
      <guid>https://dev.to/israelmuca/hi-im-israel-and-ill-introduce-you-to-my-corner-of-the-web-21po</guid>
      <description>&lt;p&gt;&lt;em&gt;This post was originally published on &lt;a href="https://israelmuca.dev/blog/hi-i-m-israel-and-this-is-my-corner-of-the-web"&gt;israelmuca.dev&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Who am I?
&lt;/h2&gt;

&lt;p&gt;My name is Israel, born and raised in Monterrey, México, currently, more and more Chicago based. I studied Engineering in Software Development back in 2007, worked as an intern for a couple of years, before focusing mostly on my own IT Business for over 10 years!&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a blog?
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Why not...?&lt;/em&gt;&lt;br&gt;&lt;br&gt;
Jk, I'm not sure really, I guess it all started when I began reading this site. I realized that writing for the sake of writing is ok, and if I can help anyone out with what I'm writing, even better.&lt;br&gt;
Afterward, I read &lt;a href="https://twitter.com/SaraSoueidan"&gt;Sara Soueidan's&lt;/a&gt; &lt;a href="https://www.sarasoueidan.com/desk/just-write/"&gt;&lt;strong&gt;Just Write&lt;/strong&gt;&lt;/a&gt; article and I felt that I should definitely create my own blog.&lt;br&gt;
Also, I love googling about a new technology stack or library and finding amazing how-tos, guides, and tutorials online, which I invariably read, regardless if I'll actually use the library, so I guess I decided to also pay back some of that amazing content with some made by myself.&lt;/p&gt;

&lt;h2&gt;
  
  
  What will I be writing about?
&lt;/h2&gt;

&lt;p&gt;Mostly, WebDev stuff. I've had different roles through the years, mostly Project Management and Business Analyst but since late 2017 I've gotten back into writing code myself, focusing on both backend and frontend.&lt;br&gt;
I've also worked on Education, and my current startup is helping Mexican schools get up-to-date with their Computer Science curriculum, so some stuff about schools as well.&lt;br&gt;
And last but not least, entrepreneurship. I've been involved in a number of startups throughout the years. Some have flunked badly, some are alive and well, so I guess I have some insight into that as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is 42 the answer to life... the universe... everything?
&lt;/h2&gt;

&lt;p&gt;Regardless of what many people claim, Douglas Adams once claimed in a quite nonchalant way in an interview:&lt;br&gt;&lt;br&gt;
&lt;em&gt;"The answer to this is very simple,"&lt;/em&gt; Adams said. &lt;em&gt;"It was a joke. It had to be a number, an ordinary, smallish number, and I chose that one. Binary representations, base 13, Tibetan monks are all complete nonsense. I sat on my desk, stared into the garden and thought 42 will do. I typed it out. End of story."&lt;/em&gt;&lt;br&gt;&lt;br&gt;
So much for all the crazy hypothesis.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closure
&lt;/h2&gt;

&lt;p&gt;So there's that! My first few articles will all be WebDev related, with the first one being a little something about the JAMstack, Netlify, and Nuxt.js, which are the backbone of this blog.&lt;/p&gt;

&lt;p&gt;So thanks for reading and see you soon!&lt;/p&gt;

</description>
      <category>blog</category>
      <category>entrepreneurship</category>
      <category>education</category>
      <category>fullstack</category>
    </item>
  </channel>
</rss>
