<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Imad</title>
    <description>The latest articles on Forem by Imad (@2imad).</description>
    <link>https://forem.com/2imad</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%2F261845%2Fc8713aae-e006-4517-a4b5-2832defddb13.PNG</url>
      <title>Forem: Imad</title>
      <link>https://forem.com/2imad</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/2imad"/>
    <language>en</language>
    <item>
      <title>User authentication with Node.js (reading series part 2): MongoDB setup</title>
      <dc:creator>Imad</dc:creator>
      <pubDate>Thu, 12 Nov 2020 21:42:30 +0000</pubDate>
      <link>https://forem.com/2imad/user-authentication-with-node-js-reading-series-part-2-mongodb-setup-2d56</link>
      <guid>https://forem.com/2imad/user-authentication-with-node-js-reading-series-part-2-mongodb-setup-2d56</guid>
      <description>&lt;p&gt;In the last post, we cloned the project repository and briefly talked about the project's essential dependencies. &lt;/p&gt;

&lt;p&gt;In this part, we will cover the following points: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
What is MongoDB + tutorial &lt;/li&gt;
&lt;li&gt;
Open MongoDB cloud account
&lt;/li&gt;
&lt;li&gt;Connect to MongoDB with mongoose&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  MongoDB setup
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;What is MongoDB? &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MongoDB is an open-source cross-platform database and is currently the most popular NoSQL architecture.&lt;br&gt;&lt;br&gt;
MongoDB uses JSON-documents and schemas to store data.   &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you want to learn more about MongoDB, here is a crash course   &lt;a href="https://www.youtube.com/watch?v=S3D5suhZ4bs"&gt;tutorial from Travesty Media on Youtube&lt;/a&gt;.   &lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Open MongoDB account&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;
  
  
  1- Head over to &lt;a href="https://cloud.mongodb.com/"&gt;mongodb cloud&lt;/a&gt; and create an account.
&lt;/h5&gt;
&lt;h5&gt;
  
  
  2- Next, in the main dashboard click &lt;code&gt;New Project&lt;/code&gt; from the top right.
&lt;/h5&gt;
&lt;h5&gt;
  
  
  3- Give your project a name and click &lt;code&gt;Next&lt;/code&gt;, now your dashboard should look like this:
&lt;/h5&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--N0iSUctu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1605205940816/fC_Se8268.png" alt="mongodb cloud dashboard"&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;h5&gt;
  
  
  4- Click &lt;code&gt;Build a Cluster&lt;/code&gt;.
&lt;/h5&gt;

&lt;p&gt;From the list below, select a cloud provider and region, you can optionally give your cluster another name from &lt;code&gt;Cluster Name tab&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
 &lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;
&lt;br&gt;
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vzrnaPBR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1605206275401/PY0BZo8Kj.png" alt="MongoDB cloud region page"&gt;&lt;br&gt;&lt;br&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;h5&gt;
  
  
  5- MongoDB will offer you the choice between &lt;code&gt;Shared Cluster&lt;/code&gt; and &lt;code&gt;Dedicated Cluster&lt;/code&gt;,   for this test project make sure to select a &lt;strong&gt;&lt;em&gt;FREE&lt;/em&gt;&lt;/strong&gt; option and Click &lt;code&gt;Create a Cluster&lt;/code&gt;.
&lt;/h5&gt;
&lt;h5&gt;
  
  
  6- It can take up to 10 min (depending on where you are) for the cluster to complete, now it's time to grab a cup of tea! :)
&lt;/h5&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--onH94Ohh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1605207021182/whgwo4f6o.png" alt="mongodb cluster created"&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;h5&gt;
  
  
  7- When the cluster is ready, click the &lt;code&gt;connect&lt;/code&gt; button on the left pane.
&lt;/h5&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--coNDjKE6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1605207297092/zAzYN1EX0.png" alt="mongodb cluster selection"&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;h5&gt;
  
  
  8- Next we need to whitelist our IP address, click &lt;code&gt;Add Your Current IP Address&lt;/code&gt;.
&lt;/h5&gt;
&lt;h5&gt;
  
  
  9- Enter a database &lt;code&gt;Username&lt;/code&gt; and &lt;code&gt;Password&lt;/code&gt; and click &lt;code&gt;Create Database User&lt;/code&gt;
&lt;/h5&gt;
&lt;h5&gt;
  
  
  10- Next, click &lt;code&gt;Choose a connection method&lt;/code&gt;
&lt;/h5&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8AzJ0xqq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1605207402583/ZEc3rUp0i.png" alt="Connection page mongodb cloud"&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;h5&gt;
  
  
  11- Next, click &lt;code&gt;Connect your application&lt;/code&gt;
&lt;/h5&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;

&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z_dd2NPQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1605208714648/RcVSKd1PL.png" alt="connecting to mongodb"&gt;

&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;h5&gt;
  
  
  12- &lt;code&gt;Copy&lt;/code&gt; your connection string
&lt;/h5&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EdOaoSaL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1605209084479/-sAGZtqTU.png" alt="connection string mongodb"&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Connect to MongoDB with mongoose.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MongoDB cloud account and the cluster are all set, we only need to find a way to connect the server application to our database.&lt;/p&gt;
&lt;h4&gt;
  
  
  In this application, we will make use of &lt;strong&gt;&lt;em&gt;mongoose&lt;/em&gt;&lt;/strong&gt;, an excellent MongoDB client.
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;I highly recommend going through mongoose docs, they offer extensive query guides and API resources. &lt;a href="https://mongoosejs.com/docs/guide.html"&gt;Find them here&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h5&gt;
  
  
  Open the project with your favorite text editor
&lt;/h5&gt;

&lt;p&gt;You can find the starter project repository here :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/2imad/node-js-authentication/tree/boilerplate
&lt;span class="nb"&gt;cd &lt;/span&gt;node-js-authentication
npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  in &lt;code&gt;db&lt;/code&gt; folder, find and open &lt;code&gt;mongoose.js&lt;/code&gt; file
&lt;/h5&gt;

&lt;p&gt;In this file we will :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Require in the mongoose module &lt;/li&gt;
&lt;li&gt;Construct the connection URI and hide our credentials with &lt;em&gt;dotenv&lt;/em&gt; &lt;/li&gt;
&lt;li&gt;Attempt to connect to MongoDB with the URI&lt;/li&gt;
&lt;li&gt;Handle connection errors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;First, we need to create a &lt;code&gt;.env&lt;/code&gt; file at the project root level to store our environment variables. &lt;/p&gt;

&lt;h5&gt;
  
  
  Open the &lt;code&gt;.env&lt;/code&gt; file and set the following environment variables corresponding to your  cluster's connection string, it should be like this :
&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;mongodb+srv://&amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;hostname&amp;gt;/&amp;lt;dbname&amp;gt;?retryWrites=true&amp;amp;w=majority&lt;/code&gt;&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;DB_USER_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;username
&lt;span class="nv"&gt;DB_USER_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;password
&lt;span class="nv"&gt;DB_HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;hostname
&lt;/span&gt;&lt;span class="nv"&gt;DB_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dbname   // you can choose any name you like. ex. &lt;span class="s2"&gt;"users"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The environment variables will be automatically stored in &lt;strong&gt;process.env&lt;/strong&gt; object once we start our server.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;A server restart is required each time the content of &lt;code&gt;.env&lt;/code&gt; file is changed.&lt;/em&gt;  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h5&gt;
  
  
  Save the file and make sure to include it in  &lt;strong&gt;.gitignore&lt;/strong&gt; .
&lt;/h5&gt;

&lt;p&gt;The content of this file should never be committed to the remote code base, we will insert these environment variables directly in &lt;strong&gt;&lt;em&gt;Heroku&lt;/em&gt;&lt;/strong&gt; when we deploy to production.&lt;/p&gt;

&lt;p&gt;Now we are ready to write some code, in &lt;code&gt;mongoose.js&lt;/code&gt; write the following :&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="c1"&gt;// require mongoose module&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mongoose&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="s2"&gt;mongoose&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// require dotenv module &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="s2"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// construct connection URI with environment variables stored in .env&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;URI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`mongodb+srv://&lt;/span&gt;&lt;span class="p"&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;DB_USER_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="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;DB_USER_PASSWORD&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;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;DB_HOST&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;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;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;?retryWrites=true&amp;amp;w=majority`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Attempt to connect to MongoDB using mongoose client &lt;/span&gt;
&lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;URI&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 the URI as first argument &lt;/span&gt;
  &lt;span class="na"&gt;useNewUrlParser&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="c1"&gt;// pass an options object with default mognodb parameters  &lt;/span&gt;
  &lt;span class="na"&gt;useUnifiedTopology&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;useCreateIndex&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="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// listen to "connected event" and log "Connected to MongoDb"&lt;/span&gt;
&lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;connected&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;=&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;Connected to MongoDb&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="c1"&gt;// listen to "error event" and log "Error connecting to MongoDb" + error message&lt;/span&gt;
&lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&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;e&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;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;Error connecting to MongoDb&lt;/span&gt;&lt;span class="dl"&gt;"&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="nx"&gt;message&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;h5&gt;
  
  
  At the top of the &lt;code&gt;index.js&lt;/code&gt; file, add the following:
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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="s2"&gt;./db/mongoose&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// require mongoose.js file &lt;/span&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="s2"&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;8000&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="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;`Listening on &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;h5&gt;
  
  
  Finally, run the following command to test the connection:
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output :&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="o"&gt;[&lt;/span&gt;0] Listening on 8000
&lt;span class="o"&gt;[&lt;/span&gt;0] Connected to MongoDb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Troubleshooting
&lt;/h1&gt;

&lt;p&gt;It is very common for Mongodb to throw an error the first time you run it. &lt;br&gt;
Here are some tips to solve any problems you might face. &lt;/p&gt;

&lt;p&gt;1- Read carefully the error message, most of the time, the MongoDB team adds the solution right after the error.&lt;br&gt;&lt;br&gt;
2- Copy the entire error message and paste it into google, the chance that somebody else had the same problem as you is very high.&lt;br&gt;&lt;br&gt;
3- Some companies, schools, public networks, institutions, &lt;strong&gt;&lt;em&gt;block&lt;/em&gt;&lt;/strong&gt; the type of connection we are making to &lt;strong&gt;&lt;em&gt;MongoDB&lt;/em&gt;&lt;/strong&gt;, if you are using a VPN or proxy, you might face some issues.&lt;br&gt;&lt;br&gt;
4- If the problem persists, try connecting from another location.&lt;br&gt;&lt;br&gt;
5- Contact me on  &lt;a href="https://twitter.com/iyo_bemoore"&gt;Twitter&lt;/a&gt;, I will do my best to help you out.&lt;/p&gt;




&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;In this section, we set up an account on the MongoDB cloud platform, learned how to hide sensitive credentials using &lt;code&gt;.env&lt;/code&gt; file  and &lt;code&gt;dotenv&lt;/code&gt; module.&lt;br&gt;&lt;br&gt;
Finally, we created &lt;code&gt;mongoose.js&lt;/code&gt; file and successfully connected our app to the database. &lt;/p&gt;

&lt;p&gt;In the next module, we will create the &lt;code&gt;User&lt;/code&gt; schema with &lt;strong&gt;&lt;em&gt;mongoose&lt;/em&gt;&lt;/strong&gt; and learn how safely store users credentials with &lt;strong&gt;&lt;em&gt;JSON web token&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;bcrypt&lt;/em&gt;&lt;/strong&gt;   &lt;/p&gt;

&lt;p&gt;Thank you very much for reading! &lt;/p&gt;

&lt;p&gt;Cheers &lt;/p&gt;

&lt;p&gt;IYO&lt;br&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Bemoore&lt;/em&gt;&lt;/strong&gt;   &lt;/p&gt;

</description>
      <category>node</category>
      <category>mongodb</category>
      <category>react</category>
      <category>100daysofcode</category>
    </item>
    <item>
      <title>User authentication with Node.js series: boilerplate</title>
      <dc:creator>Imad</dc:creator>
      <pubDate>Mon, 09 Nov 2020 20:31:55 +0000</pubDate>
      <link>https://forem.com/2imad/user-authentication-with-node-js-series-boilerplate-34o3</link>
      <guid>https://forem.com/2imad/user-authentication-with-node-js-series-boilerplate-34o3</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;User authentication is the core feature of every website and mobile application. Writing authentication the correct and secure way prevents malicious users from accessing sensitive application data.&lt;/p&gt;

&lt;p&gt;There are many technologies we can use to enforce secure access to application resources, the most common one is &lt;strong&gt;OAuth&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can read more about &lt;strong&gt;OAuth&lt;/strong&gt; &lt;a href="https://oauth.net/2/"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But, for this series, we will build the authentication system from scratch, and make it as simple as possible so it can be further customized and &lt;em&gt;“plugged”&lt;/em&gt; with any existing application.    &lt;/p&gt;




&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;p&gt;To ensure a smooth and pleasant experience, please make sure before cloning the starter repository to have the following tools installed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;latest version of &lt;a href="https://nodejs.org/en/"&gt;Node.js&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;latest version of &lt;a href="https://www.npmjs.com/"&gt;npm&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;git &lt;/li&gt;
&lt;li&gt;Text editor &lt;/li&gt;
&lt;li&gt;Terminal&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Project repository
&lt;/h1&gt;

&lt;p&gt;In this section, we will clone the starter project hosted on  &lt;a href="https://github.com/2imad/node-js-authentication"&gt;Github&lt;/a&gt;, get familiar with the folder structure, and explore the project dependencies.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Open a Terminal session and run&lt;/strong&gt;
&amp;gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/2imad/node-js-authentication.git
&lt;span class="nb"&gt;cd &lt;/span&gt;node-js-authentication
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install server dependencies&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install client dependencies&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;client
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Git checkout &lt;em&gt;boilerplate&lt;/em&gt; branch&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout boilerplate
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Open the project with your favorite text editor, at this stage it should look like this:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;|-- node-js-authentication
|-- config
|-- db
|-- mailer
|-- middlewares
|-- routes
|-- .env
|-- .gitignore
|-- index.js
|-- LICENSE
|-- package-lock.json
|-- package.json
|-- README.md
|-- client
|   |-- .gitignore
|   |-- package-lock.json
|   |-- package.json
|   |-- README.md
|   |-- public
|   |   |-- favicon.ico
|   |   |-- index.html
|   |   |-- logo192.png
|   |   |-- logo512.png
|   |   |-- manifest.json
|   |   |-- robots.txt
|   |-- src
|       |-- App.css
|       |-- App.js
|       |-- App.test.js
|       |-- index.css
|       |-- index.js
|       |-- logo.svg
|       |-- reportWebVitals.js
|       |-- setupTests.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Start the development server&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;

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

&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you see output like below, it means you are ready to roll :) &lt;/p&gt;

&lt;blockquote&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;nodemon] 2.0.6
&lt;span class="o"&gt;[&lt;/span&gt;nodemon] to restart at any &lt;span class="nb"&gt;time&lt;/span&gt;, enter &lt;span class="sb"&gt;`&lt;/span&gt;rs&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;nodemon] watching path&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="k"&gt;*&lt;/span&gt;.&lt;span class="k"&gt;*&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;nodemon] watching extensions: js,mjs,json  
&lt;span class="o"&gt;[&lt;/span&gt;nodemon] starting &lt;span class="sb"&gt;`&lt;/span&gt;node index.js&lt;span class="sb"&gt;`&lt;/span&gt;
Listening on 8000
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  Project dependencies
&lt;/h1&gt;

&lt;p&gt;Here is the current dependency list as found on &lt;strong&gt;&lt;em&gt;package.json&lt;/em&gt;&lt;/strong&gt;. &lt;br&gt;
With each list item, you find a link to the package homepage on &lt;strong&gt;&lt;em&gt;npm&lt;/em&gt;&lt;/strong&gt; and a brief introduction. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/bcrypt"&gt;bcrypt&lt;/a&gt;
bcrypt is a powerful hashing function, we will make use of its power to add hashing and salting to user passwords.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/concurrently"&gt;concurrently&lt;/a&gt;
This package enables running multiple commands simultaneously.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/cors"&gt;cors&lt;/a&gt;
Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any other origins (domain, protocol, or port) than its own from which a browser should permit loading of resources. CORS also relies on a mechanism by which browsers make a “preflight” request to the server hosting the cross-origin resource, in order to check that the server will permit the actual request. In that preflight, the browser sends headers that indicate the HTTP method and headers that will be used in the actual request.
During development, our client and server are both running on &lt;strong&gt;&lt;em&gt;localhost&lt;/em&gt;&lt;/strong&gt;. Most browsers deny cross-origin requests for security reasons, but &lt;strong&gt;&lt;em&gt;Cors&lt;/em&gt;&lt;/strong&gt; will help us get around that.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/dotenv"&gt;dotenv&lt;/a&gt;
This package enables retrieving environment variables stored in the &lt;strong&gt;.env&lt;/strong&gt; file and using them without risking sensitive data exposure.
&amp;gt; &lt;strong&gt;&lt;em&gt;Important note:&lt;/em&gt;&lt;/strong&gt;
&lt;strong&gt;&lt;em&gt;.dotenv&lt;/em&gt;&lt;/strong&gt; file should always be included in &lt;strong&gt;&lt;em&gt;.gitignore&lt;/em&gt;&lt;/strong&gt; before committing the code.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/express"&gt;express&lt;/a&gt;
express is the module we are using to create a server and configure authentication routes.
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/jsonwebtoken"&gt;jsonwebtoken&lt;/a&gt;
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.  - &lt;a href="https://jwt.io/introduction/"&gt;source&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://mongoosejs.com/"&gt;mongoose&lt;/a&gt;
Mongoose provides a straight-forward, schema-based solution to model our application data. It includes built-in type casting, validation, query building, business logic hooks, and more, out of the box. &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nodemailer.com/about/"&gt;nodemailer&lt;/a&gt;
Nodemailer is a module for Node.js applications to allow easy email sending.&lt;/li&gt;
&lt;li&gt;
&lt;a href="//A%20library%20of%20string%20validators%20and%20sanitizers."&gt;validator&lt;/a&gt;
This library validates and sanitizes strings.&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Resources
&lt;/h1&gt;

&lt;p&gt;Finally, some additional resources to help you understand the functionality of each dependency we are using in the project, in case you know any other resources, please do let me know!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.npmjs.com/package/bcrypt"&gt;bcrypt&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Article:&lt;a href="https://auth0.com/blog/hashing-in-action-understanding-bcrypt/"&gt;Hashing in action&lt;/a&gt;&lt;br&gt;&lt;br&gt;
NPM: &lt;a href="https://www.npmjs.com/package/bcrypt"&gt;bcrypt&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Playground: &lt;a href="https://bcrypt-generator.com/"&gt;bcrypt generator&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.npmjs.com/package/cors"&gt;cors&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Article: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS"&gt;MDN&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Definition: &lt;a href="https://www.w3.org/wiki/CORS_Enabled"&gt;W3C&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Article: &lt;a href="https://auth0.com/blog/cors-tutorial-a-guide-to-cross-origin-resource-sharing/"&gt;What is Cors&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.npmjs.com/package/express"&gt;express&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Homepage: &lt;a href="https://expressjs.com/"&gt;Express&lt;/a&gt;&lt;br&gt;&lt;br&gt;
NPM: &lt;a href="https://www.npmjs.com/package/express"&gt;express&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Article: &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/Introduction"&gt;MDN&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.npmjs.com/package/jsonwebtoken"&gt;jsonwebtoken&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Homepage: &lt;a href="https://jwt.io/"&gt;jwt&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Playground: &lt;a href="https://www.jsonwebtoken.io/"&gt;jwt&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Source code: &lt;a href="https://github.com/auth0/node-jsonwebtoken"&gt;jwt&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://mongoosejs.com/"&gt;mongoose&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Homepage:  &lt;a href="https://mongoosejs.com/"&gt;mongoose&lt;/a&gt;&lt;br&gt;&lt;br&gt;
NPM: &lt;a href="https://www.npmjs.com/package/mongoose"&gt;mongoose&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Tutorial:&lt;a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/mongoose"&gt;MDN&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://nodemailer.com/about/"&gt;nodemailer&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Homepage:&lt;a href="https://nodemailer.com/about/"&gt;Nodemailer&lt;/a&gt;&lt;br&gt;
Full tutorial:&lt;a href="https://blog.mailtrap.io/sending-emails-with-nodemailer/"&gt;Nodemailer&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;In this first part of the series, we talked about authentication with Node.js, cloned the starter repository, and installed the dependencies. Hopefully, you are as excited as I am to get to the next chapter where we will create a &lt;strong&gt;MongoDB&lt;/strong&gt; database and connect it to our project with &lt;strong&gt;mongoose&lt;/strong&gt;, and finally create the &lt;strong&gt;signup&lt;/strong&gt;  route.&lt;/p&gt;

&lt;p&gt;The next chapter should appear soon, so stay tuned! or follow me and receive it immediately in your mailbox  :) &lt;/p&gt;

&lt;p&gt;Cheers! &lt;/p&gt;

&lt;p&gt;IYO&lt;br&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Bemoore&lt;/em&gt;&lt;/strong&gt;  &lt;/p&gt;

</description>
      <category>node</category>
      <category>mongodb</category>
      <category>react</category>
      <category>100daysofcode</category>
    </item>
    <item>
      <title>6 Tips to improve your search engine results</title>
      <dc:creator>Imad</dc:creator>
      <pubDate>Tue, 06 Oct 2020 12:55:10 +0000</pubDate>
      <link>https://forem.com/2imad/6-tips-to-improve-your-search-engine-results-1kkn</link>
      <guid>https://forem.com/2imad/6-tips-to-improve-your-search-engine-results-1kkn</guid>
      <description>&lt;p&gt;Search engines are the most commonly used tools by developers when working on solving programming problems.&lt;/p&gt;

&lt;p&gt;Routine tasks such as running &lt;strong&gt;“How to”&lt;/strong&gt; and &lt;strong&gt;“plugin XYZ for...”&lt;/strong&gt; search queries play a significant part in our daily lives as programmers.&lt;/p&gt;

&lt;p&gt;Thanks to advanced technologies running behind the scenes, popular search engines like &lt;strong&gt;Google&lt;/strong&gt;, &lt;strong&gt;DuckDuckGo&lt;/strong&gt; often give a quick and accurate answer to most queries.&lt;/p&gt;

&lt;p&gt;Yet, there are many query options you can use to unlock the search engine’s full potential.&lt;/p&gt;

&lt;h3&gt;
  
  
  Here are some tips to make the most of your search results :
&lt;/h3&gt;




&lt;p&gt;&lt;strong&gt;1. Asterisk wildcard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is a very powerful feature for enabling partial search, it can come in handy when you are not sure about the full query or just want to browse a certain topic.&lt;/p&gt;

&lt;p&gt;The browser will take the asterisk &lt;strong&gt;(*)&lt;/strong&gt; and replace it dynamically with all possible hits.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1601985682326%2F6LAnxfpVo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1601985682326%2F6LAnxfpVo.png" alt="asterisk.PNG"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Google top results:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;How to create pages dynamically in gatsby.js.&lt;/li&gt;
&lt;li&gt;How to get started with gatsby.js 2 and Redux.&lt;/li&gt;
&lt;li&gt;How to source content with gatsby.js.&lt;/li&gt;
&lt;li&gt;How to use images in gatsby.js.&lt;/li&gt;
&lt;li&gt;How to secure gatsby.js. &lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;2. Colon&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The use of a colon &lt;strong&gt;(:)&lt;/strong&gt; enables adding specificity to the query, it tells the browser to run the search term only on a specific website.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1601985702497%2F8xbF4nkQF.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1601985702497%2F8xbF4nkQF.png" alt="colon.PNG"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The list will contain &lt;strong&gt;only&lt;/strong&gt; posts from stackoverflow.com.&lt;br&gt;
At the time of the writing, google found &lt;strong&gt;1.2M&lt;/strong&gt; results for the query above.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;3. Hyphen&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The hyphen  &lt;strong&gt;(-)&lt;/strong&gt; is used to exclude a certain category from the search results, this can be used when a term has different meanings.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1601985726295%2F60iRqOZhe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1601985726295%2F60iRqOZhe.png" alt="hyphen.PNG"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The query above will return all results related to “Mocha” excluding anything related to -coffee. as mocha is a coffee variant.&lt;/p&gt;

&lt;p&gt;This query will return results related to &lt;strong&gt;Mocha&lt;/strong&gt;, the Javascript testing framework.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;4. The "OR" operator&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, OR operator works the same way in google search as in programming languages, this feature enables you, you guessed it, to run multiple queries in a single search term.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1601985749305%2Fsvj1io4Yu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1601985749305%2Fsvj1io4Yu.png" alt="or_operator.PNG"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;5. Quotes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Adding quotes &lt;strong&gt;(" ")&lt;/strong&gt; around the query tells the search engine to search for that exact term.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1601985761016%2Fj8HkkL3uI.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1601985761016%2Fj8HkkL3uI.png" alt="quotes.PNG"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;6. Image size&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Adding image dimensions in your image search query will reduce your search time significantly, this feature allows you to add the &lt;strong&gt;widthxheight&lt;/strong&gt; option to your query.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1601985787722%2Fq-Y09o-ub.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1601985787722%2Fq-Y09o-ub.png" alt="img_resize.PNG"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This query will return filtered cat images to &lt;strong&gt;500px width&lt;/strong&gt; and &lt;strong&gt;500px height&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;These tips are only a few of very powerful options you can pass to your query, in case you  would like to explore more, here is a link to &lt;a href="https://support.google.com/websearch/answer/2466433?hl=en" rel="noopener noreferrer"&gt;google search help documentation&lt;/a&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Thank you for reading, if you liked this article, do not hesitate to share it with your friends. &lt;br&gt;
Follow me on &lt;a href="https://twitter.com/iyo_bemoore" rel="noopener noreferrer"&gt;twitter&lt;/a&gt; for daily programming tips. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Have a nice day!&lt;/p&gt;

&lt;p&gt;IYO &lt;/p&gt;

</description>
      <category>100daysofcode</category>
      <category>codenewbie</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Free online tools for fast and easy image optimization</title>
      <dc:creator>Imad</dc:creator>
      <pubDate>Sat, 03 Oct 2020 08:17:53 +0000</pubDate>
      <link>https://forem.com/2imad/free-online-tools-for-fast-and-easy-image-optimization-1bm9</link>
      <guid>https://forem.com/2imad/free-online-tools-for-fast-and-easy-image-optimization-1bm9</guid>
      <description>&lt;p&gt;As web developers, we are often given the task to load assets to websites and applications.&lt;/p&gt;

&lt;p&gt;Most of the time, unless you are working with a dream team of designers, the assets available are often either too large or incorrectly formatted. &lt;/p&gt;

&lt;p&gt;Likely there are so many ways for developers to manipulate assets, before shipping them to the browser. &lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Here is a short list of free online tools I use myself on daily basis for image compressing&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Image processing&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;1.Tiny PNG *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Tiny PNG is a super powerful fast online tool to compress your .png or even .jpg files, you just need to drag and drop your photo and it compresses it automatically, with up to 60% of file size reduction.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tinypng.com/"&gt;Tiny PNG&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;2.JPEG-optimizer *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;JPEG optimizer is another great tool to compress jpg files, in the UI you can upload your photo and make and customize the compression level ( custom width in pixels  ).&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.jpeg-optimizer.com/"&gt;JPEG optimizer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Resizing&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Picresize is my favorite tool, I use it almost every day, ( i used it to resize the header image of this post). &lt;br&gt;
In this tool you can do the following : &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Crop &lt;/li&gt;
&lt;li&gt;Rotate&lt;/li&gt;
&lt;li&gt;Flip on both axis&lt;/li&gt;
&lt;li&gt;Resize with given % or custom values &lt;/li&gt;
&lt;li&gt;Save the file in different format including png | jpg | gif &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I highly recommend you to try it out and bookmark it on your favorite browser, it will come in handy, trust me.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://picresize.com/"&gt;picresize&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The last but not least good practice to optimize images in your website is knowing what format to use for which kind of asset,  there are plenty of resources out there explaining the difference between png and jpg, if you are curious about the topic let me know on twitter or email, I will be glad to point them out. &lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Here is a good resource to test the loading time of your assets: *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pageweight.imgix.com/"&gt;imgix&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On imgx you just need to copy-paste the URL of your website and receive a detailed report of your website load speed. Highly recommended&lt;/p&gt;

&lt;p&gt;That's all folks, &lt;/p&gt;

&lt;p&gt;**If you liked this post or you feel a good free resource ( no signup required) should be added to this list, please let me know in the comment section or on   &lt;a href="https://twitter.com/iyo_bemoore"&gt;twitter&lt;/a&gt;.&lt;br&gt;
Also please share the post with your friends :) * *&lt;/p&gt;

</description>
      <category>100daysofcode</category>
      <category>webdev</category>
      <category>codenewbie</category>
      <category>design</category>
    </item>
    <item>
      <title>The best Udemy courses to fast forward yourself from a beginner to lead react.js developer.</title>
      <dc:creator>Imad</dc:creator>
      <pubDate>Thu, 17 Sep 2020 20:44:01 +0000</pubDate>
      <link>https://forem.com/2imad/the-best-udemy-courses-to-fast-forward-yourself-from-a-beginner-to-lead-react-js-developer-n9n</link>
      <guid>https://forem.com/2imad/the-best-udemy-courses-to-fast-forward-yourself-from-a-beginner-to-lead-react-js-developer-n9n</guid>
      <description>&lt;p&gt;Udemy is by far the most popular learning platform, offering a massive amount of video content from awesome creators. &lt;/p&gt;

&lt;p&gt;Due to this massive offer, the platform might become overwhelming, especially if you are a beginner with no idea where to begin.  &lt;/p&gt;




&lt;p&gt;I still remember the time when I started using the platform back in 2017, at the time, I only knew some HTML and all I could do with CSS was change the text color. &lt;/p&gt;

&lt;p&gt;It took me almost a month of research before finding the best and most valuable resources to expand my knowledge on HTML - CSS - JavaScript and finally React.js. &lt;/p&gt;




&lt;p&gt;Here is the list of the courses I personally took and achieved my goal of becoming a lead developer working for one of the big 4 consultancy companies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt;&lt;br&gt;
Following a self-teaching path is hard, but doable. You need a good dose of discipline, willpower, dedication, and perseverance.&lt;/p&gt;

&lt;p&gt;In the following days, I will publish a full blog on how I organized my studies, tools, and tricks I used to stay focused. &lt;/p&gt;

&lt;h2&gt;
  
  
  The List
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;HTML - CSS&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.udemy.com/course/design-and-develop-a-killer-website-with-html5-and-css3/"&gt;https://www.udemy.com/course/design-and-develop-a-killer-website-with-html5-and-css3/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When it comes to web development and design, you have to give it to Jonas, after finishing this 12hours course you will have a solid HTML and CSS knowledge foundation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CSS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.udemy.com/course/advanced-css-and-sass/"&gt;https://www.udemy.com/course/advanced-css-and-sass/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My styling really sucked until I took this course, Jonas explains in detail the most advanced CSS topics, project structure, CSS pre-processors, and compilers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Javascript&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.udemy.com/course/the-complete-javascript-course/"&gt;https://www.udemy.com/course/the-complete-javascript-course/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This one is the top Javascript course on Udemy, it covers all topics from primitives to hardcore topics such as closures, prototypal chain, IEFE, etc… &lt;br&gt;
Jonas just published a new update, and the course is now 28h long!! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;React&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.udemy.com/course/react-redux/"&gt;https://www.udemy.com/course/react-redux/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When it comes to React, Stephen is arguably the best teacher out there.&lt;br&gt;&lt;br&gt;
The foundation of my career as a developer is built thanks to his knowledge. &lt;/p&gt;

&lt;p&gt;Stephen explains every tiny piece of React in detail and keeps hammering on it until you get it. &lt;/p&gt;

&lt;p&gt;Stephen’s teaching signature is highly effective, his videos do not exceed +/- 5min, this gives you the ability to absorb the content, and also reference a topic easily after you finish the course.&lt;/p&gt;

&lt;p&gt;Stephen is one of the few teachers who I never heard saying “do it like this because it works that way”. Every single topic comes with a thorough explanation. &lt;/p&gt;

&lt;p&gt;Stephen utilizes diagrams to help visual learners, like myself, get a good grasp of the topic. &lt;br&gt;
You receive the diagrams together with the course repository for free. &lt;/p&gt;

&lt;h2&gt;
  
  
  Important note :
&lt;/h2&gt;

&lt;p&gt;I’m not making paid marketing for any of the creators mentioned above, I don't think they need marketing after all. &lt;br&gt;
The sole intention of my post is to share my learning path and help aspiring web developers. &lt;/p&gt;

&lt;p&gt;Liked the article? Please share it with others.&lt;br&gt;&lt;br&gt;
Do you have a suggestion or a question? &lt;br&gt;
Contact me on   &lt;a href="https://twitter.com/iyo_bemoore"&gt;twitter&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Thank you for your time! &lt;/p&gt;

&lt;p&gt;Cheers &lt;/p&gt;

&lt;p&gt;IYO&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>codenewbie</category>
      <category>100daysofcode</category>
    </item>
    <item>
      <title>Bash functions to level up your aliases game! </title>
      <dc:creator>Imad</dc:creator>
      <pubDate>Thu, 10 Sep 2020 21:06:50 +0000</pubDate>
      <link>https://forem.com/2imad/bash-functions-to-level-up-your-aliases-game-4hac</link>
      <guid>https://forem.com/2imad/bash-functions-to-level-up-your-aliases-game-4hac</guid>
      <description>&lt;p&gt;Do you use bash aliases to customise your commands?&lt;br&gt;
Of course you do!&lt;/p&gt;

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

&lt;p&gt;But, did you know you can extend aliases to use bash functions and pass arguments? &lt;/p&gt;

&lt;p&gt;bash functions enable you to concatenate multiple commands and add as many arguments as you can. Well, just like any function in any programming language. &lt;/p&gt;

&lt;p&gt;I came across this when I was looking into condensing git commands. I AM EXTREMELY LAZY and running git add + git commit + git push every time, really hurts.&lt;/p&gt;

&lt;p&gt;So let's make a function that does just that.&lt;/p&gt;

&lt;h2&gt;
  
  
  STEP 1 
&lt;/h2&gt;

&lt;p&gt;We need to make the alias persistent in bash profile.&lt;br&gt;
Open a new bash terminal window and run : &lt;/p&gt;

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

&lt;h2&gt;
  
  
  STEP 2 
&lt;/h2&gt;

&lt;p&gt;Anywhere in your bashrc file, declare the function as shown below.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  STEP 3 
&lt;/h2&gt;

&lt;p&gt;Save and exit nano.&lt;/p&gt;

&lt;p&gt;Here is what we did, we declared &lt;code&gt;pushtoremote&lt;/code&gt; function, which runs git add . git commit -m &lt;code&gt;message&lt;/code&gt; and git push &lt;code&gt;repository&lt;/code&gt; &lt;code&gt;branch&lt;/code&gt; &lt;strong&gt;consecutively&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;code&gt;$1&lt;/code&gt; &lt;code&gt;$2&lt;/code&gt; &lt;code&gt;$3&lt;/code&gt; are placeholders for the variables passed to the alias upon executing. &lt;code&gt;message&lt;/code&gt; &lt;code&gt;repository&lt;/code&gt; &lt;code&gt;branch&lt;/code&gt;  (example follows).  &lt;/p&gt;

&lt;h2&gt;
  
  
  STEP 4 
&lt;/h2&gt;

&lt;p&gt;We need to link the alias to the current session, so we can immediately start using it. &lt;/p&gt;

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

&lt;h2&gt;
  
  
  STEP 5 
&lt;/h2&gt;

&lt;p&gt;Here is a sample command with &lt;code&gt;pushtoremote&lt;/code&gt; alias. &lt;/p&gt;

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

&lt;p&gt;&lt;em&gt;Note&lt;/em&gt; : some terminals like &lt;code&gt;fish&lt;/code&gt; do not support &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; so you will have to replace it with &lt;code&gt;and&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you make something extra cool with bash functions, please do let me know. :)))              &lt;/p&gt;

&lt;p&gt;I post snippets every day on twitter, join me there! &lt;/p&gt;

&lt;p&gt;Cheers! &lt;/p&gt;

&lt;p&gt;Imad&lt;/p&gt;

</description>
      <category>codenewbie</category>
      <category>100daysofcode</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to add custom fonts to a React Native project with Expo and React Navigation!</title>
      <dc:creator>Imad</dc:creator>
      <pubDate>Tue, 04 Aug 2020 08:27:50 +0000</pubDate>
      <link>https://forem.com/2imad/how-to-add-custom-fonts-to-a-react-native-project-with-expo-and-react-navigation-195d</link>
      <guid>https://forem.com/2imad/how-to-add-custom-fonts-to-a-react-native-project-with-expo-and-react-navigation-195d</guid>
      <description>&lt;h3&gt;
  
  
  &lt;strong&gt;To achieve our goal, we will take the following steps :&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Generate a new test project with Expo-CLI.&lt;/li&gt;
&lt;li&gt;Install and import react-navigation, react-navigation-stack modules.&lt;/li&gt;
&lt;li&gt;Create 2 screens and display some dummy text.&lt;/li&gt;
&lt;li&gt;Download a Font and add it to the project.&lt;/li&gt;
&lt;li&gt;Import and use loadAsync helper from Expo&lt;/li&gt;
&lt;li&gt;Wire up the newly added font and use it in the project.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;1- Generate a new Expo project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Head over to a directory of your choice and run :&lt;/p&gt;

&lt;p&gt;Using npx:  &lt;code&gt;npx expo-cli init test-custom-font&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;OR&lt;/strong&gt;&lt;br&gt;
Using expo-cli:  &lt;code&gt;expo init test-custom-font&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2- Install the dependencies&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;run the following to install react-navigation dependencies:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i react-navigation react-navigation-stack react-navigation-gesture-handler&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;While the installation is running, let’s open the project and add some boilerplate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3- Create the screens and display some text&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To keep this article short, i will skip the how-to-create-and-import-export-your-components section, and head over to the adding the Font.&lt;/p&gt;

&lt;p&gt;At this point, your files should look like this :&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;App.js&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import { createAppContainer } from "react-navigation";
import { createStackNavigator } from "react-navigation-stack";
import HomeScreen from "./src/screens/HomeScreen";
import DetailScreen from "./src/screens/DetailScreen";
const AppNavigation  = createStackNavigator(
  {
    Home: HomeScreen,
    Details: DetailScreen
  }
);
export default createAppContainer(AppNavigation);

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;HomeScreen.js&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { View, Text, StyleSheet, Button } from "react-native";

const HomeScreen = ({ navigation }) =&amp;gt; {
  return (
    &amp;lt;View style={styles.container}&amp;gt;
      &amp;lt;Text style={styles.textStyle}&amp;gt; Welcome to the Home Screen &amp;lt;/Text&amp;gt;
      &amp;lt;Button
        title="See Details"
        onPress={() =&amp;gt; navigation.navigate("Details")}
      /&amp;gt;
    &amp;lt;/View&amp;gt;
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center"
  }
});

export default HomeScreen;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;DetailScreen.js&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { View, Text, StyleSheet } from "react-native";

const DetailScreen = () =&amp;gt; {
  return (
    &amp;lt;View style={styles.container}&amp;gt;
      &amp;lt;Text style={styles.textStyle}&amp;gt;
        Lorem Ipsum is simply dummy text of the printing and typesetting
        industry. Lorem Ipsum has been the industry's standard dummy text ever
        since the 1500s, when an unknown printer took a galley of type and
        scrambled it to make a type specimen book. It has survived not only five
        centuries, but also the leap into electronic typesetting, remaining
        essentially unchanged. It was popularised in the 1960s with the release
        of Letraset sheets containing Lorem Ipsum passages, and more recently
        with desktop publishing software like Aldus PageMaker including versions
        of Lorem Ipsum.
      &amp;lt;/Text&amp;gt;
    &amp;lt;/View&amp;gt;
  );
};
const styles = StyleSheet.create({
  container: {
    padding: 12,
    flex: 1,
    justifyContent: "center",
    alignItems: "center"
  }
});
export default DetailScreen;
```




run `expo start` the result should look like this : 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/go6ifzyv7yc751kp9k15.png)


**3- Download a Font and add it to the project.**


* Inside the assets folder, create a fonts folder.
* Head over to [google fonts](https://fonts.google.com).
* Download and unzip a font of your choice in any location on your machine.
* Copy/paste the .ttf file inside the font folder in the project.
* In this demo we will use "montserrat"

By now, the project structure should look like this :




![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/scfs2m5rykfo0orswoha.png)

**3- Import Expo Font module and wire up the custom font.**

Depending on whether you are using classes or functional components, loading the font is slightly different, let's have a look at both : 



According to Expo documentation, loading a custom font should be done using the built-in `Font.loadAsync` helper method, and since "as it's name suggests" its an `async` function, we should invoke it inside a life cycle method.

---

**Class based approach**


The current implementation of our App.js does not support a life cycle method, as the root component (App.js line 11)is created and exported immediately.

Likely for us, the only thing Expo expects from our App.js is a valid React component.
So let’s build and export a custom App component with our loaded font.

Your App.js should look like this now,



```
// import React 
import React, { Component } from "react";
// import Expo Font module 
import * as Font from "expo-font";
import { createAppContainer } from "react-navigation";
import { createStackNavigator } from "react-navigation-stack";
import HomeScreen from "./src/screens/HomeScreen";
import DetailScreen from "./src/screens/DetailScreen";
// import AppLoading helper 
//https://docs.expo.io/versions/latest/sdk/app-loading/
import { AppLoading } from "expo";

const appNavigator = createStackNavigator(
  {
    Home: HomeScreen,
    Details: DetailScreen
  },
  {
    initialRouteName: "Home"
  }
);

// instead of immediately exporting the AppNavigator component we assign in to a constant. 
const RootApp = createAppContainer(appNavigator);


// we create and export our own custom App component 
export default class App extends Component {

  state = {
    loaded: false
  };
// create a helper function to load the font 
  _loadFontsAsync = async () =&amp;gt; {
// loadAsync returns true | error
    let isLoaded = await Font.loadAsync({
      // add as many fonts as you want here .... 
      Montserrat: require("./assets/fonts/montserrat.ttf")
    });
    this.setState({ loaded: isLoaded });
  };

// call _loadFontsAsync 
  componentDidMount() {
    this._loadFontsAsync();
  }

  render() {
    if (!this.state.loaded) {
      return &amp;lt;AppLoading /&amp;gt;;
    }
    // from the custom App we return the component we assigned to RootApp.
    return &amp;lt;RootApp /&amp;gt;;
  }
}
```



---

**Functional approach**

In functional components, we can make use of React hooks to solve this problem, likely for us, a font loading hook already exist and we do not have to build our own. 

We will make use of `@use-expo/font` from Expo to load our Font. 

lets install the package first, run `npm i @use-expo/font`

Next, let's implement it :



```
// import React 
import React from "react";
// import Expo Font module 
import * as Font from "expo-font";
// import useFonts hook  
import { useFonts } from "@use-expo/font";
import { createAppContainer } from "react-navigation";
import { createStackNavigator } from "react-navigation-stack";
import HomeScreen from "./src/screens/HomeScreen";
import DetailScreen from "./src/screens/DetailScreen";
// import AppLoading helper 
//https://docs.expo.io/versions/latest/sdk/app-loading/
import { AppLoading } from "expo";

const appNavigator = createStackNavigator(
  {
    Home: HomeScreen,
    Details: DetailScreen
  },
  {
    initialRouteName: "Home"
  }
);

// instead of immediately exporting the AppNavigator component we assign in to a constant. 
const RootApp = createAppContainer(appNavigator);
// require in the font 
const customFonts = {
  Montserrat: require("./assets/fonts/montserrat.ttf"),
};

const App = () =&amp;gt; {
    // the same as Font.loadAsync , the hook returns  true | error 
    const [isLoaded] = useFonts(customFonts);


    if (!isLoaded) {
        return &amp;lt;AppLoading /&amp;gt;;
    }
    // from the custom App we return the component we assigned to RootApp.
    return &amp;lt;RootApp /&amp;gt;;

}

export default App
```



--- 

As you can see, the functional approach is way cleaner and more readable. 

---


**5- Use the newly added font:**

Now, all we have to do is add the font family to our style object, in both HomeScreen.js and DetailScreen.js :

`textStyle:{ fontFamily:'Montserrat'}`


**Result:**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/5mc6ov4s1ale0qs9dboo.png)

---

Like this post ? let me know, i will be posting about advanced topics on React, React Native or Node.js. 

You can find me on twitter too ! :)  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>reactnative</category>
      <category>react</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
