<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Okoro Emmanuel Nzube - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Okoro Emmanuel Nzube - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 24 May 2026 16:29:36 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/Derekvibe/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Bypass Cloud SMTP Restrictions Using Brevo and HTTP APIs ]]>
                </title>
                <description>
                    <![CDATA[ Being able to communicate by sending emails through web applications is important these days. It helps businesses stay connected with their potential customers, securely verify user identities, and de ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-bypass-cloud-smtp-restrictions-using-brevo-and-http-apis/</link>
                <guid isPermaLink="false">69fe2a2ef239332df4f7f8b9</guid>
                
                    <category>
                        <![CDATA[ api ]]>
                    </category>
                
                    <category>
                        <![CDATA[ brevo ]]>
                    </category>
                
                    <category>
                        <![CDATA[ google smtp ]]>
                    </category>
                
                    <category>
                        <![CDATA[ cloud-smtp ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Okoro Emmanuel Nzube ]]>
                </dc:creator>
                <pubDate>Fri, 08 May 2026 18:23:42 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/64f68792-e18c-4b90-9c65-c6d9884ab191.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Being able to communicate by sending emails through web applications is important these days. It helps businesses stay connected with their potential customers, securely verify user identities, and deliver crucial notifications like password resets.</p>
<p>But sometimes, deploying your perfectly working email function to the cloud leads to unexpected and frustrating errors. You build your backend, test it locally, and it works flawlessly. Then you deploy to the cloud, and suddenly your app stops sending emails completely.</p>
<p>In this article, you’ll learn exactly why your email setup fails on cloud platforms like Render or Heroku, the underlying networking rules causing the issue, and how to elegantly bypass these restrictions using Brevo's HTTP API.</p>
<p>Let’s dive right in.</p>
<h2 id="heading-outline">Outline</h2>
<ul>
<li><p><a href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a href="#heading-tools-well-be-using">Tools We'll Be Using</a></p>
</li>
<li><p><a href="#heading-the-problem-nodemailer-and-smtp-blocking">The Problem: Nodemailer and SMTP Blocking</a></p>
</li>
<li><p><a href="#heading-the-modern-trap-domain-verification">The "Modern" Trap: Domain Verification</a></p>
</li>
<li><p><a href="#heading-the-ultimate-solution-brevo-and-http-apis">The Ultimate Solution: Brevo and HTTP APIs</a></p>
</li>
<li><p><a href="#heading-backend-setup">Backend Setup</a></p>
</li>
<li><p><a href="#heading-brevo-configuration-setup">Brevo Configuration Setup</a></p>
</li>
<li><p><a href="#heading-creating-the-email-function">Creating the Email Function</a></p>
</li>
<li><p><a href="#heading-integrating-the-function-into-an-express-route">Integrating the Function into an Express Route</a></p>
</li>
<li><p><a href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>To get the absolute most out of this tutorial, it’s important to have some basic knowledge of the following:</p>
<ul>
<li><p><strong>JavaScript and Node.js:</strong> Having a good fundamental understanding of how JS works on the server side will make it easier to follow along with the project.</p>
</li>
<li><p><strong>REST APIs:</strong> You should have a basic understanding of how HTTP requests (like POST and GET) work using native <code>fetch()</code> in Node.js.</p>
</li>
<li><p><strong>Express.js:</strong> A little background on creating basic server routes will be helpful, as we'll build a real-world controller.</p>
</li>
<li><p>A basic understanding of what <a href="https://nodemailer.com/">Nodemailer</a> is and how cloud hosting platforms (like Render or Heroku) operate.</p>
</li>
</ul>
<h2 id="heading-tools-well-be-using">Tools We’ll Be Using</h2>
<p>In one of my recent projects, I created a complex authentication flow where users needed an OTP (One Time Password) sent to their email to complete registration. I set up Nodemailer, linked my Gmail, and tested it on <code>localhost</code>. Within seconds, the emails arrived perfectly.</p>
<p>But when I deployed my backend to Render, the entire signup flow broke. After doing some deep digging, I found out why it broke and how to fix it permanently. And now that I know how it works, I wanted to share it with you all.</p>
<h2 id="heading-the-problem-nodemailer-and-smtp-blocking">The Problem: Nodemailer and SMTP Blocking</h2>
<p>So what exactly is the issue?</p>
<p>Nodemailer is a very popular Node.js module that lets you send emails efficiently. Usually, developers use it to connect to services like Gmail or Mailtrap using <strong>SMTP</strong> (Simple Mail Transfer Protocol). When your code tries to send an email, Nodemailer opens a connection to the mail server using Port <code>587</code> (for STARTTLS) or Port <code>465</code> (for SSL).</p>
<p>But cloud providers like Render, Heroku, DigitalOcean, and AWS face a massive daily battle against automated spammers. Malicious users often spin up thousands of free-tier servers specifically to blast out millions of spam emails. If a cloud provider allows this, their entire network IP address block will get blacklisted by Gmail, Outlook, and Yahoo.</p>
<p>To protect their network reputation, cloud providers enacted a heavy-handed, silent rule: <strong>All outbound traffic on Ports 25, 465, and 587 is strictly blocked on free and entry-level tiers.</strong></p>
<p>This means your server is literally trapped behind a firewall. If you check your server logs, you won't see an "Invalid Password" error. Instead, you'll see a timeout error that looks like this:</p>
<pre><code class="language-plaintext">Error: connect ETIMEDOUT 142.250.102.108:587
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1494:16)
</code></pre>
<p>Your code isn't broken – it's just being blocked at the network level!</p>
<h3 id="heading-the-modern-trap-domain-verification">The "Modern" Trap: Domain Verification</h3>
<p>When developers hit this wall, they often try modern API-based email services like Resend or SendGrid. These are amazing tools, but they introduce a new problem for beginners: <strong>Strict Domain Authentication.</strong></p>
<p>To use Resend in production, you must own a custom domain (like <code>yourname.com</code>) and configure DNS records (SPF, DKIM, and DMARC). If you don't own a domain, Resend's sandbox mode strictly restricts you to sending emails <em>only</em> to yourself. You can't send emails to your live users.</p>
<p>For a developer just trying to launch a portfolio project, buying a domain just to send test emails is a huge bottleneck.</p>
<h3 id="heading-the-ultimate-solution-brevo-and-http-apis">The Ultimate Solution: Brevo and HTTP APIs</h3>
<p>We need a solution that meets two criteria:</p>
<ol>
<li><p>It must bypass the Port <code>587</code> firewall.</p>
</li>
<li><p>It must let us send emails to <em>anyone</em> without forcing us to buy a custom domain.</p>
</li>
</ol>
<p>This is where the architectural difference between SMTP and REST APIs comes to the rescue. While SMTP is a dedicated protocol for routing mail, a REST API operates over standard web traffic using <strong>HTTPS (Port 443)</strong>. Cloud providers <em>can't</em> block Port 443, because doing so would prevent your server from fetching data from databases or functioning as a web server entirely.</p>
<p>Enter <strong>Brevo</strong> (formerly Sendinblue). Brevo is a powerful email platform that allows you to send emails via a standard REST API. Best of all, their free tier (300 emails/day) allows Single Sender Verification. You just verify your standard Gmail address, and they let you send to anyone!</p>
<p>By sending a JSON payload via HTTPS to Brevo's API, your server routes the traffic out of the unrestricted Port <code>443</code>, bypassing the Render firewall completely.</p>
<p>Now that you know the theory behind the tools we’ll be using, let’s move on to writing the code.</p>
<h2 id="heading-backend-setup">Backend Setup</h2>
<p>First things first, you have to set up your environment. If you don't already have Node.js installed on your computer, head to their <a href="https://nodejs.org/en">website</a> to download and install it.</p>
<p>Start by running <code>npm init -y</code> in your terminal. This creates the <code>package.json</code> file which manages your project and stores all the dependencies.</p>
<p>Next, run <code>npm install express dotenv</code>.</p>
<p>You might be used to installing <code>nodemailer</code> for your email tasks. But because we are going to use the native Node.js <code>fetch()</code> API to talk to the Brevo API, you actually don't need to install <em>any</em> heavy email libraries at all! We want to keep our backend as lightweight as possible.</p>
<h3 id="heading-brevo-configuration-setup">Brevo Configuration Setup</h3>
<p>Before you write the email function, you first need to configure Brevo to get access to your API key.</p>
<ol>
<li><p>Go to <a href="https://www.brevo.com/">Brevo.com</a> and create a free account.</p>
</li>
<li><p>During setup, they will ask you to add a <strong>Sender Email</strong>. Make sure you input your standard Gmail address. They will send you an email with a link to verify you own this address.</p>
</li>
<li><p>Once verified and inside the dashboard, click on your profile name in the top right corner, and select <strong>SMTP &amp; API</strong> from the dropdown menu.</p>
</li>
<li><p>Go to the <strong>API Keys</strong> tab and click <strong>Generate a new API key</strong>. Give it a name like "MyWebApp".</p>
</li>
</ol>
<p>Copy this generated key and store it safely in a <code>.env</code> file at the root of your project:</p>
<pre><code class="language-env"># .env file
EMAIL_USER = yourverifiedemail@gmail.com
BREVO_API_KEY = xkeysib-your-generated-api-key-goes-here
</code></pre>
<h3 id="heading-creating-the-email-function">Creating the Email Function</h3>
<p>Now that you’ve gotten your API key and set up your environment variables, all that remains is to start putting your backend code together.</p>
<p>Create a file named <code>utils/email.js</code>.</p>
<p>First, start by ensuring you can load your <code>.env</code> file so you can easily access the credentials you generated:</p>
<pre><code class="language-javascript">require("dotenv").config();

// We'll define the function to accept dynamic options
const sendEmail = async (options) =&gt; {
  const brevoApiKey = process.env.BREVO_API_KEY;
  const senderEmail = process.env.EMAIL_USER;

  // Validate that the keys actually exist
  if (!brevoApiKey || !senderEmail) {
    throw new Error("Missing Brevo credentials in environment variables.");
  }
</code></pre>
<p>Next on the line, you’ll need to structure your payload. This is the JSON object that tells Brevo exactly who is sending the email, who is receiving it, and what the content is. Here’s how you can do that:</p>
<pre><code class="language-javascript">  const payload = {
    sender: {
      name: "My Awesome Web App",
      email: senderEmail, // Must match your verified Brevo email
    },
    to: [
      {
        email: options.email, // The dynamic email address of the user receiving the email
      },
    ],
    subject: options.subject,
    htmlContent: options.html,
  };
</code></pre>
<p>In the code above, the <code>payload</code> object securely packages up your information. We pass in <code>options.email</code>, <code>options.subject</code>, and <code>options.html</code> so that we can reuse this single function for welcome emails, password resets, and notifications.</p>
<p>Now, create the actual network request that sends your data to the Brevo backend. We'll use the <code>POST</code> method. When the data is sent, it must be stringified into a JSON format.</p>
<pre><code class="language-javascript">  try {
    const response = await fetch("https://api.brevo.com/v3/smtp/email", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "api-key": brevoApiKey,
      },
      body: JSON.stringify(payload),
    });

    const result = await response.json();

    if (!response.ok) {
      throw new Error(`Brevo API Error: ${JSON.stringify(result)}`);
    }

    console.log(`Email successfully sent to ${options.email} via Brevo HTTP API!`);
  } catch (error) {
    console.error("Error details:", error.message);
  }
};

module.exports = sendEmail;
</code></pre>
<p>In the code above, after the payload is submitted, if the message is sent successfully, a success log will be displayed in your terminal. But if the message wasn’t successful – maybe due to a typo in your API key – an error message will be thrown to help you debug exactly what went wrong.</p>
<h3 id="heading-integrating-the-function-into-an-express-route">Integrating the Function into an Express Route</h3>
<p>At this point, you've successfully built a robust email function. Let's see how you would actually use this in a real Express application.</p>
<p>Create an <code>index.js</code> file and set up a simple Express server route:</p>
<pre><code class="language-javascript">const express = require("express");
const sendEmail = require("./utils/email");
const app = express();

app.use(express.json()); // Middleware to parse JSON request bodies

app.post("/api/signup", async (req, res) =&gt; {
  const { username, email } = req.body;

  // 1. Save user to database (skipped for brevity)
  
  // 2. Generate a random OTP
  const otp = Math.floor(100000 + Math.random() * 900000);

  // 3. Send the email using our new Brevo function
  try {
    await sendEmail({
      email: email,
      subject: "Welcome! Here is your Verification Code",
      html: `
        &lt;div style="font-family: sans-serif; text-align: center;"&gt;
          &lt;h2&gt;Welcome to My Awesome Web App, ${username}!&lt;/h2&gt;
          &lt;p&gt;Please use the verification code below to complete your registration:&lt;/p&gt;
          &lt;h1 style="color: #2563eb; letter-spacing: 5px;"&gt;${otp}&lt;/h1&gt;
          &lt;p&gt;This code will expire in 10 minutes.&lt;/p&gt;
        &lt;/div&gt;
      `,
    });

    res.status(201).json({ message: "User created and email sent!" });
  } catch (error) {
    res.status(500).json({ error: "Failed to send email." });
  }
});

app.listen(8000, () =&gt; {
  console.log("Server running on port 8000");
});
</code></pre>
<p>And that is it! You can now hit this <code>/api/signup</code> endpoint from your React or Vue frontend, and it will instantly fire off a beautifully formatted email via Brevo's REST API.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>As developers, encountering a bug that works locally but fails in production is a rite of passage. But the "Email Delivery Failed" timeout error is special. It teaches you that software engineering isn't just about writing clean syntax – it's about understanding the underlying infrastructure, network layers, and the security context of the environment your code runs in.</p>
<p>By swapping a protocol (SMTP) for an architectural pattern (REST API over HTTPS), you didn't just fix a bug. You successfully engineered a secure, free, and robust bypass around a cloud-level firewall without relying on heavy third-party NPM modules like Nodemailer.</p>
<p>If you've made it this far, I hope I've successfully shown you the importance of understanding network layers and how you can use HTTP APIs to send email messages directly from your web applications safely.</p>
<p>Thank you for reading!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Telehealth App Using Stream Video and Chat SDK in React ]]>
                </title>
                <description>
                    <![CDATA[ Remember when the COVID-19 pandemic moved everything online – doctor’s visits included – and staying home became the safest option?  That moment kicked off a massive shift in how healthcare gets delivered.  Telehealth became more than a workaround. I... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-a-telehealth-app-using-stream-video-and-chat-sdk-in-react/</link>
                <guid isPermaLink="false">687ad06430967c1524c4663e</guid>
                
                    <category>
                        <![CDATA[ streams SDK ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Streams ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Tailwind CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ MERN Stack ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Mern Stack Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Okoro Emmanuel Nzube ]]>
                </dc:creator>
                <pubDate>Fri, 18 Jul 2025 22:53:24 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1752879185676/ab0574c8-d16b-41d0-8883-7df0f4bd0eb5.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Remember when the COVID-19 pandemic moved everything online – doctor’s visits included – and staying home became the safest option? </p>
<p>That moment kicked off a massive shift in how healthcare gets delivered. </p>
<p><a target="_blank" href="https://getstream.io/chat/solutions/healthcare/">Telehealth</a> became more than a workaround. It’s now a core part of modern care. As demand grows, developers are stepping up to build secure, real-time platforms that connect patients and providers from anywhere.</p>
<p>In this article, you’ll learn how to build a telehealth application with Stream’s <a target="_blank" href="https://getstream.io/video/sdk/react/">React Video</a> and <a target="_blank" href="https://getstream.io/chat/sdk/react/">Chat</a> SDKs. You’ll set up authentication, create video calls, enable messaging, and design a functional user interface that mimics real-world telehealth workflows.</p>
<p>Let’s dive in.</p>
<h2 id="heading-outline">Outline</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-introduction">Introduction</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-app-structure">App Structure</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-project-setup">Project Setup</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-backend-setup">Backend Setup</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-frontend-setup">Frontend Setup</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-stream-chat-and-video-integration">Stream Chat and Video Integration</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-chat-and-video-function-\(frontend\)">Chat and Video Function (Frontend)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-project-demo">Project Demo</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-Conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before you start this tutorial, make sure you have:</p>
<ul>
<li><p>A basic understanding of React.</p>
</li>
<li><p>Node.js and npm/yarn installed on your computer</p>
</li>
<li><p>A <a target="_blank" href="https://getstream.io/try-for-free/">free account with Stream</a></p>
</li>
<li><p>Familiarity with Stream SDKs</p>
</li>
<li><p>A basic understanding of Tailwind CSS for styling</p>
</li>
<li><p>Experience with VS Code and Postman (for testing APIs)</p>
</li>
</ul>
<h2 id="heading-app-structure"><strong>App Structure</strong></h2>
<p>Before diving into the code, it’s helpful to understand how the app is structured.</p>
<pre><code class="lang-markdown"><span class="hljs-section"># App Flow Structure</span>

<span class="hljs-bullet">-</span> Landing Page  
<span class="hljs-bullet">  -</span> Navigation  
<span class="hljs-bullet">    -</span> Home  
<span class="hljs-bullet">    -</span> About  
<span class="hljs-bullet">    -</span> Sign Up  
<span class="hljs-bullet">      -</span> Verify Account  
<span class="hljs-bullet">        -</span> Log In  
<span class="hljs-bullet">          -</span> Dashboard  
<span class="hljs-bullet">            -</span> Stream Chat  
<span class="hljs-bullet">            -</span> Stream Video  
<span class="hljs-bullet">            -</span> Log Out
</code></pre>
<h2 id="heading-project-setup"><strong>Project Setup</strong></h2>
<p>Before getting started, create two folders: “Frontend” to handle the client-side code and “Backend” for the server-side logic. This separation allows you to manage both parts of your application efficiently.</p>
<h3 id="heading-set-up-react-for-the-frontend"><strong>Set Up React for the Frontend</strong></h3>
<p>Once the folders are created, you can set up the React application in the Frontend folder.</p>
<p>First, navigate to the Frontend directory using the command <code>cd Frontend</code>.</p>
<p>Now you can initialize your React project. You’ll use Vite, a fast build tool for React applications.</p>
<p>To create your React project, run the following command:</p>
<p><code>npm create vite@latest [project name] -- --template react</code></p>
<p> Next, navigate to your new project folder, using the command:</p>
<p><code>cd [project name]</code></p>
<p>Once there, install the required dependencies by running:</p>
<p><code>npm install</code></p>
<p>This command installs both the <code>node_modules</code> folder (which contains all your project's packages) and the <code>package-lock.json</code> file (which records exact versions of installed packages).</p>
<p>Next, you’ll need to install Tailwind CSS for styling. Follow the <a target="_blank" href="https://v3.tailwindcss.com/docs/guides/vite">Tailwind Docs</a> for step-by-step instructions.</p>
<p>Then, it’s time to set up the website. Using React, you’ll create the home sign-in/log-in pages. Both will be nested together using <code>React-router-dom</code>.</p>
<p>Here’s what the <a target="_blank" href="https://github.com/Derekvibe/Telehealth_Frontend/tree/main/src/pages/Home">home page</a> looks like:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752705718347/ed5dd289-2998-41f7-8d10-352aa35fe614.gif" alt="Telehealth Home Page" class="image--center mx-auto" width="1415" height="666" loading="lazy"></p>
<p>Now, the user has a place to land whenever they visit the website.</p>
<p>Let’s set up the backend.</p>
<h2 id="heading-backend-setup"><strong>Backend Setup</strong></h2>
<h3 id="heading-installing-required-packages"><strong>Installing Required Packages</strong></h3>
<p>Before setting up your project's backend, it's important to define what your project needs to offer. This will help you install all the necessary packages in one go.</p>
<p>Start by moving into the backend folder using the command: <code>cd Backend</code></p>
<p>Inside the Backend directory, initialize your Node.js project using <code>npm install</code></p>
<p>This will create a <code>package.json</code> file, which stores metadata and dependencies for your project.</p>
<p>Next, install all the dependencies needed to build your backend. Run the following command:</p>
<p><code>npm i bcryptjs cookie-parser cors dotenv express jsonwebtoken mongoose nodemailer validator nodemon</code></p>
<p>Here’s a brief overview of what each package does:</p>
<ul>
<li><p>bcryptjs: Encrypts user passwords for secure storage.</p>
</li>
<li><p>Cookie-parser: Handles cookies in your application.</p>
</li>
<li><p>CORS: Middleware that enables cross-origin requests – essential for frontend-backend communication.</p>
</li>
<li><p>dotenv: Loads environment variables from a <code>.env</code> file into process.env.</p>
</li>
<li><p>Express: The core framework for building your server and API routes.</p>
</li>
<li><p>jsonwebtoken: Generates and verifies JWT tokens for authentication.</p>
</li>
<li><p>Mongoose: Connects your app to a MongoDB database.</p>
</li>
<li><p>nodemailer: Handles sending emails from your application.</p>
</li>
<li><p>Validator: Validates user inputs like email, strings, and so on.</p>
</li>
<li><p>nodemon: Automatically restarts your server when changes are made to files.</p>
</li>
</ul>
<p>Once your packages are installed, create two key files in the backend directory: <code>App.js</code>, which contains your app logic, middleware, and route handlers, and <code>server.js</code>, responsible for initializing and configuring your server.</p>
<p>Next, you have to update your <code>package.json</code> start script. Head to the <code>package.json</code> file in your backend directory and replace the default script:</p>
<pre><code class="lang-json"><span class="hljs-string">"scripts"</span>: {
    <span class="hljs-attr">"test"</span>: <span class="hljs-string">"echo\”Error: no test specified\" &amp;&amp; exit 1”
  }</span>
</code></pre>
<p>with this:</p>
<pre><code class="lang-json"><span class="hljs-string">"scripts"</span>: {
    <span class="hljs-attr">"start"</span>: <span class="hljs-string">"nodemon server.js"</span>
  }
</code></pre>
<p>This setup allows you to run your server using <code>nodemon</code>, automatically reloading it when changes are made. This helps boost productivity during development.</p>
<p>To check if your backend setup is correct, open the <code>server.js</code> file and add a test log: <code>console.log (“Any of your Log Message”)</code>. Then, head to your terminal in the backend directory, and run npm start. You should see the log message in the terminal, confirming that your backend is running.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752703046663/dc06ce5a-3b6c-4846-bd33-53c423a57235.png" alt="Backend Server Testing" class="image--center mx-auto" width="1120" height="986" loading="lazy"></p>
<h3 id="heading-appjs-setup"><code>App.js</code> <strong>Setup</strong></h3>
<p>In the <code>App.js</code> file, start by importing the packages you initially installed.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">"express"</span>);

<span class="hljs-keyword">const</span> cors = <span class="hljs-built_in">require</span>(<span class="hljs-string">"cors"</span>);

<span class="hljs-keyword">const</span> cookieParser = <span class="hljs-built_in">require</span>(<span class="hljs-string">"cookie-parser"</span>);

<span class="hljs-keyword">const</span> app = express();


app.use(

  cors({

<span class="hljs-attr">origin</span>: [

   <span class="hljs-string">"http://localhost:5173"</span>,

],

<span class="hljs-attr">credentials</span>: <span class="hljs-literal">true</span>,

  })

);

app.use(express.json({ <span class="hljs-attr">limit</span>: <span class="hljs-string">"10kb"</span> }));

app.use(cookieParser());

<span class="hljs-built_in">module</span>.exports = app;
</code></pre>
<p>Here’s what the code above does: </p>
<p>The require statements import <code>express</code>, <code>cors</code>, and <code>cookie-parser</code>, which are essential for creating your backend server, handling cross-origin requests, and parsing cookies.</p>
<p>The <code>const app = express();</code> command sets up a new instance of an Express application. </p>
<p><code>app.use(cors({ origin: ["</code><a target="_blank" href="http://localhost:5173"><code>http://localhost:5173</code></a><code>"], credentials: true }));</code> grants permission or allows requests from your frontend and enables cookie sharing between the frontend and backend of your application. This is important for authentication.</p>
<p>The <code>app.use(express.json({ limit: "10kb" }));</code> command is a middleware function that ensures the server can process incoming JSON payloads and protects against overly large requests, which could be used in DoS attacks. </p>
<p>The <code>app.use(cookieParser());</code> command makes cookies available via <code>req.cookies</code>.</p>
<p>Last, the <code>module.exports = app;</code> command allows the app to be imported in other files, especially in <code>server.js</code>, which is where the app will be started.</p>
<h3 id="heading-serverjs-setup"><code>Server.js</code> <strong>Setup</strong></h3>
<p>Once <code>App.js</code> is set up, the next step is to create and configure your server in a new file called <code>server.js</code>.</p>
<p>Before doing that, ensure you have a <strong>MongoDB database</strong> set up. If you don’t have one yet, you can <a target="_blank" href="https://youtu.be/pO6m0nmo1k0?si=Rqi_50fnsfQrM-ww">follow this video tutorial</a> to set up a MongoDB database.</p>
<p>After setting up MongoDB, you will receive a <code>username</code> and <code>password</code>. Copy the password, head to your backend directory, and create a <code>.env</code> file to store it.</p>
<p>After you have stored the password, head back to complete your database setup.</p>
<p>Next, click on the “Create Database User” button, then click on the <code>choose connection method</code> option. Since we are using Node.js for this project, choose the “Drivers” option. This gives you the database connection string (you should see it at No. 3).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752706253668/ad0cdbb4-453c-4291-ab4c-395d14ce297c.gif" alt="Database-String-Auth" class="image--center mx-auto" width="1280" height="671" loading="lazy"></p>
<p>Then head to your <code>.env</code> and paste it there, and add <code>auth</code> immediately after you have “.net/”.</p>
<p>Here’s what it looks like:</p>
<p><code>mongodb+srv://&lt;username&gt;:&lt;password&gt;@cluster0.qrrtmhs.mongodb.net/auth?retryWrites=true&amp;w=majority&amp;appName=Cluster0</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752767020758/aee4f54c-e562-4916-a8f5-b97590a671d1.png" alt="Backend config.env file" class="image--center mx-auto" width="1632" height="426" loading="lazy"></p>
<p>Lastly, whitelist your IP address. This ensures your backend can connect to MongoDB from your local machine or any environment during development.</p>
<p>To allow your application to connect to the database:</p>
<ul>
<li><p>Go to the "Network Access" section in the Security sidebar of your MongoDB dashboard.</p>
</li>
<li><p>Click on “ADD IP ADDRESS.”</p>
</li>
<li><p>Choose “Allow Access from Anywhere”, then click on Confirm.</p>
</li>
</ul>
<p>At this point, you can set up your <code>server.js</code></p>
<pre><code class="lang-javascript"><span class="hljs-comment">//server.js</span>
<span class="hljs-built_in">require</span>(<span class="hljs-string">"dotenv"</span>).config();
<span class="hljs-keyword">const</span> mongoose = <span class="hljs-built_in">require</span>(<span class="hljs-string">"mongoose"</span>);
<span class="hljs-keyword">const</span> dotenv = <span class="hljs-built_in">require</span>(<span class="hljs-string">"dotenv"</span>); <span class="hljs-comment">//to Manage our environment variable</span>

dotenv.config({ <span class="hljs-attr">path</span>: <span class="hljs-string">"./config.env"</span> });
<span class="hljs-comment">// console.log(process.env.NODE_ENV);</span>

<span class="hljs-keyword">const</span> app = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./app"</span>);

<span class="hljs-keyword">const</span> db = process.env.DB;
<span class="hljs-comment">//connect the application to database using MongoDB</span>

mongoose
  .connect(db)
  .then(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"DB connection Successful"</span>);
  })
  .catch(<span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(err);
  });

<span class="hljs-keyword">const</span> port = process.env.PORT || <span class="hljs-number">3000</span>;
<span class="hljs-comment">// console.log(process.env.PORT)</span>

app.listen(port, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`App running on port <span class="hljs-subst">${port}</span>`</span>);
});
</code></pre>
<p>The <code>server.js</code> file is responsible for handling all server-related functions and logic. From the code above, the <code>server.js</code> file loads the environment variables using <code>dotenv</code>, connects your backend to MongoDB using <code>mongoose</code>, and starts the Express server. It gets the database URL and port from the <code>config.env</code> file, connects to the database, then runs your application on the specified port (<code>8000</code>).</p>
<p>If the specified port is not found, it falls back to port <code>3000</code> and a confirmation message is printed to the console indicating that the server is up and running on the specified port.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752703203108/a94c724c-ad9c-4653-9081-894ac6e44dd6.png" alt="server-js Telehealth App" class="image--center mx-auto" width="991" height="800" loading="lazy"></p>
<h3 id="heading-connect-the-database-to-mongodb-compass">Connect the Database to MongoDB Compass</h3>
<p>First, download the MongoDB Compass app. (Go here to download and install: <a target="_blank" href="https://www.mongodb.com/try/download/compass">https://www.mongodb.com/try/download/compass</a>). The MongoDB Compass app makes it easy for us to manage our data.</p>
<p>Once the installation is complete, open the app and click on <code>Click to add new connection</code>. Go to your <code>.env</code> file, copy the connection string you initially got when setting up MongoDB, paste it in the URL section, and then click on “connect.” This setup helps you manage your data when you create and delete users.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752703344533/8dff0ff6-66e9-4359-a2c0-fe7a4bd5e4ba.png" alt="Mongo-DB-Compass" class="image--center mx-auto" width="1263" height="790" loading="lazy"></p>
<h3 id="heading-set-up-an-advanced-error-handling-method"><strong>Set up an Advanced Error Handling Method</strong></h3>
<p>You’ll now create an advanced error-handling mechanism. To do so, create a utils folder in your backend, a <code>catchAsync.js</code> file in the utils folder, and add this code:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//catchAsync.js</span>
<span class="hljs-built_in">module</span>.exports = <span class="hljs-function">(<span class="hljs-params">fn</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-function">(<span class="hljs-params">req, res, next</span>) =&gt;</span> {
    fn(req, res, next).catch(next);
  };
};
</code></pre>
<p>Next, create an <code>appError.js</code> file still in your utils folder. In the <code>appError.js</code> file, add the following command:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AppError</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Error</span> </span>{
  <span class="hljs-keyword">constructor</span>(message, statusCode) {
    <span class="hljs-built_in">super</span>(message);

    <span class="hljs-built_in">this</span>.statusCode = statusCode;
    <span class="hljs-built_in">this</span>.status = <span class="hljs-string">`<span class="hljs-subst">${statusCode}</span>`</span>.startsWith(<span class="hljs-string">"4"</span>) ? <span class="hljs-string">"fail"</span> : <span class="hljs-string">"error"</span>;
    <span class="hljs-built_in">this</span>.isOperational = <span class="hljs-literal">true</span>;

    <span class="hljs-built_in">Error</span>.captureStackTrace(<span class="hljs-built_in">this</span>, <span class="hljs-built_in">this</span>.constructor);
  }
}

<span class="hljs-built_in">module</span>.exports = AppError;
</code></pre>
<p>The code above is helpful in tracking and tracing errors. It also provides you with the URL and file location where your error might be occurring, which helps with cleaner error handling and debugging.</p>
<p>Next, let’s create a global error handler. Start by creating a new folder in the backend directory, and name it “controller”. In the controller folder, create your global error handling file. You can name it anything you like. In this example, it’s called <code>globalErrorHandler.js</code>.</p>
<p>Your <code>globalErrorHandler</code> file will define several functions that handle specific error types, such as database issues, validation failures, or even JWT problems and return a nicely formatted error response for users. For the <code>globalErrorHandler</code> to work properly, you have to create a controller function.</p>
<p>So, next, create an <code>errorController.js</code> file (still inside the controller folder). The <code>errorController.js</code> file responds to the user whenever an error is caught, sending the error in JSON format.</p>
<p><code>globalErrorHandler.js</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// globalErrorHandler.js</span>
<span class="hljs-keyword">const</span> AppError = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../utils/appError"</span>);

<span class="hljs-keyword">const</span> handleCastErrorDB = <span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> message = <span class="hljs-string">`Invalid <span class="hljs-subst">${err.path}</span>: <span class="hljs-subst">${err.value}</span>.`</span>;
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> AppError(message, <span class="hljs-number">400</span>);
};

<span class="hljs-keyword">const</span> handleDuplicateFieldsDB = <span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> value = err.keyValue ? <span class="hljs-built_in">JSON</span>.stringify(err.keyValue) : <span class="hljs-string">"duplicate field"</span>;
  <span class="hljs-keyword">const</span> message = <span class="hljs-string">`Duplicate field value: <span class="hljs-subst">${value}</span>. Please use another value!`</span>;
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> AppError(message, <span class="hljs-number">400</span>);
};

<span class="hljs-keyword">const</span> handleValidationErrorDB = <span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> errors = <span class="hljs-built_in">Object</span>.values(err.errors).map(<span class="hljs-function">(<span class="hljs-params">el</span>) =&gt;</span> el.message);
  <span class="hljs-keyword">const</span> message = <span class="hljs-string">`Invalid input: <span class="hljs-subst">${errors.join(<span class="hljs-string">". "</span>)}</span>`</span>;
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> AppError(message, <span class="hljs-number">400</span>);
};

<span class="hljs-keyword">const</span> handleJWTError = <span class="hljs-function">() =&gt;</span>
  <span class="hljs-keyword">new</span> AppError(<span class="hljs-string">"Invalid token. Please log in again!"</span>, <span class="hljs-number">401</span>);
<span class="hljs-keyword">const</span> handleJWTExpiredError = <span class="hljs-function">() =&gt;</span>
  <span class="hljs-keyword">new</span> AppError(<span class="hljs-string">"Your token has expired! Please log in again."</span>, <span class="hljs-number">401</span>);

<span class="hljs-built_in">module</span>.exports = {
  handleCastErrorDB,
  handleDuplicateFieldsDB,
  handleValidationErrorDB,
  handleJWTError,
  handleJWTExpiredError,
};
</code></pre>
<p>Here’s what the code above does:</p>
<p>The <code>const handleCastErrorDB = (err) =&gt;..</code> section handles MongoDB CastError which usually happens when an invalid ID is passed, and returns a <code>400 Bad Request</code> error response using your <code>AppError</code> class.</p>
<p>The <code>const handleDuplicateFieldsDB = (err) =&gt;...</code> checks and handles MongoDB duplicate key errors, such as trying to register an email or username that’s already taken and returns a <code>400 Bad Request</code> error.</p>
<p>The <code>const handleValidationErrorDB = (err) =&gt;...</code> handles Mongoose validation errors (like required fields missing or wrong data types). It gathers all the individual validation error messages and combines them into one.</p>
<p>The <code>const handleJWTError = () =&gt;</code> and <code>const handleJWTExpiredError = () =&gt;</code> handle errors which might occur as a result of invalid, tampered, or expired JWT tokens and return a <code>401 Unauthorized</code> error response.</p>
<p>The <code>module.exports = {……};</code> section exports all the individual error handlers so they can be used in the <code>errorController.js</code> file.</p>
<p><code>errorController.js</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//errorController.js</span>
<span class="hljs-keyword">const</span> errorHandlers = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./globalErrorHandler"</span>);

<span class="hljs-keyword">const</span> {
  handleCastErrorDB,
  handleDuplicateFieldsDB,
  handleValidationErrorDB,
  handleJWTError,
  handleJWTExpiredError,
} = errorHandlers;

<span class="hljs-built_in">module</span>.exports = <span class="hljs-function">(<span class="hljs-params">err, req, res, next</span>) =&gt;</span> {
  err.statusCode = err.statusCode || <span class="hljs-number">500</span>;
  err.status = err.status || <span class="hljs-string">"error"</span>;

  <span class="hljs-keyword">let</span> error = { ...err, <span class="hljs-attr">message</span>: err.message };

  <span class="hljs-keyword">if</span> (err.name === <span class="hljs-string">"CastError"</span>) error = handleCastErrorDB(err);
  <span class="hljs-keyword">if</span> (err.code === <span class="hljs-number">11000</span>) error = handleDuplicateFieldsDB(err);
  <span class="hljs-keyword">if</span> (err.name === <span class="hljs-string">"ValidationError"</span>) error = handleValidationErrorDB(err);
  <span class="hljs-keyword">if</span> (err.name === <span class="hljs-string">"JsonWebTokenError"</span>) error = handleJWTError();
  <span class="hljs-keyword">if</span> (err.name === <span class="hljs-string">"TokenExpiredError"</span>) error = handleJWTExpiredError();

  res.status(error.statusCode).json({
    <span class="hljs-attr">status</span>: error.status,
    <span class="hljs-attr">message</span>: error.message,
    ...(process.env.NODE_ENV === <span class="hljs-string">"production"</span> &amp;&amp; { error, <span class="hljs-attr">stack</span>: err.stack }),
  });
};
</code></pre>
<p>To ensure your error-handling function works properly, head to your <code>App.js</code> and add the command:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//import command</span>
<span class="hljs-keyword">const</span> globalErrorHandler = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./controller/errorController"</span>);
<span class="hljs-keyword">const</span> AppError = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./utils/appError"</span>);

<span class="hljs-comment">//Catch unknown routes</span>
app.all(<span class="hljs-string">"/{*any}"</span>, <span class="hljs-function">(<span class="hljs-params">req, res, next</span>) =&gt;</span> {
  next(<span class="hljs-keyword">new</span> AppError(<span class="hljs-string">`Can't find <span class="hljs-subst">${req.originalUrl}</span> on this server!`</span>, <span class="hljs-number">404</span>)); });

app.use(globalErrorHandler);
</code></pre>
<p>This ensures that all errors are properly handled and sends the error response to the user.</p>
<h3 id="heading-create-user-model"><strong>Create User Model</strong></h3>
<p>To build a user model, create a new folder in the backend directory and name it “model.” Inside the model folder, create a new file named <code>userModel.js</code>.</p>
<p>The <code>userModel.js</code> file is built essentially for user authentication and security. It provides a validation-rich schema for managing users using Mongoose, which maps how user data is structured in the MongoDB database. It includes validations, password hashing, and methods to compare user passwords securely.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//userModel.js</span>
<span class="hljs-keyword">const</span> mongoose = <span class="hljs-built_in">require</span>(<span class="hljs-string">"mongoose"</span>);
<span class="hljs-keyword">const</span> validator = <span class="hljs-built_in">require</span>(<span class="hljs-string">"validator"</span>);
<span class="hljs-keyword">const</span> bcrypt = <span class="hljs-built_in">require</span>(<span class="hljs-string">"bcryptjs"</span>);

<span class="hljs-keyword">const</span> userSchema = <span class="hljs-keyword">new</span> mongoose.Schema(
  {
    <span class="hljs-attr">username</span>: {<span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>, <span class="hljs-attr">required</span>: [<span class="hljs-literal">true</span>, <span class="hljs-string">"Please provide username"</span>], <span class="hljs-attr">trim</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">minlength</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">maxlength</span>: <span class="hljs-number">30</span>, <span class="hljs-attr">index</span>: <span class="hljs-literal">true</span>,},
    <span class="hljs-attr">email</span>: {<span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>, <span class="hljs-attr">required</span>: [<span class="hljs-literal">true</span>, <span class="hljs-string">"Please Provide an email"</span>], <span class="hljs-attr">unique</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">lowercase</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">validate</span>: [validator.isEmail, <span class="hljs-string">"Please provide a valid email"</span>],},
    <span class="hljs-attr">password</span>: {<span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>, <span class="hljs-attr">required</span>: [<span class="hljs-literal">true</span>, <span class="hljs-string">"Please provide a Password"</span>], <span class="hljs-attr">minlength</span>: <span class="hljs-number">8</span>, <span class="hljs-attr">select</span>: <span class="hljs-literal">false</span>,},
    <span class="hljs-attr">passwordConfirm</span>: {<span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>, <span class="hljs-attr">required</span>: [<span class="hljs-literal">true</span>, <span class="hljs-string">"Please confirm your Password"</span>],
     <span class="hljs-attr">validate</span>: {<span class="hljs-attr">validator</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">el</span>) </span>{<span class="hljs-keyword">return</span> el === <span class="hljs-built_in">this</span>.password;},
        <span class="hljs-attr">message</span>: <span class="hljs-string">"Passwords do not match"</span>,
      },
    },
    <span class="hljs-attr">isVerified</span>: {<span class="hljs-attr">type</span>: <span class="hljs-built_in">Boolean</span>, <span class="hljs-attr">default</span>: <span class="hljs-literal">false</span>,}, <span class="hljs-attr">otp</span>: <span class="hljs-built_in">String</span>,
    <span class="hljs-attr">otpExpires</span>: <span class="hljs-built_in">Date</span>,
     <span class="hljs-attr">resetPasswordOTP</span>: <span class="hljs-built_in">String</span>,
      <span class="hljs-attr">resetPasswordOTPExpires</span>: <span class="hljs-built_in">Date</span>,
    <span class="hljs-attr">createdAt</span>: {<span class="hljs-attr">type</span>: <span class="hljs-built_in">Date</span>, <span class="hljs-attr">default</span>: <span class="hljs-built_in">Date</span>.now,},}, { <span class="hljs-attr">timestamps</span>: <span class="hljs-literal">true</span> });

<span class="hljs-comment">// Hash password before saving</span>
userSchema.pre(<span class="hljs-string">"save"</span>, <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">next</span>) </span>{
  <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">this</span>.isModified(<span class="hljs-string">"password"</span>)) <span class="hljs-keyword">return</span> next();

  <span class="hljs-built_in">this</span>.password = <span class="hljs-keyword">await</span> bcrypt.hash(<span class="hljs-built_in">this</span>.password, <span class="hljs-number">12</span>);
  <span class="hljs-built_in">this</span>.passwordConfirm = <span class="hljs-literal">undefined</span>; <span class="hljs-comment">// Remove passwordConfirm before saving</span>
  next();
});

<span class="hljs-keyword">const</span> User = mongoose.model(<span class="hljs-string">"User"</span>, userSchema);
<span class="hljs-built_in">module</span>.exports = User;
</code></pre>
<h3 id="heading-auth-controller"><strong>Auth Controller</strong></h3>
<p>Now, you can create logic that regulates your user's authentication process. This authentication logic consists of the sign-up, sign-in (log-in), OTP, and so on. </p>
<p>To do so, first head to your controller folder and create a new file. Call it <code>authController.js</code> because it handles the authentication flow of your project.</p>
<p>After you’ve created the file, you’ll create your sign-up function.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//import</span>
<span class="hljs-keyword">const</span> User = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../model/userModel"</span>);
<span class="hljs-keyword">const</span> AppError = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../utils/appError"</span>);
<span class="hljs-keyword">const</span> catchAsync = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../utils/catchAsync"</span>);
<span class="hljs-keyword">const</span> generateOtp = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../utils/generateOtp"</span>);
<span class="hljs-keyword">const</span> jwt = <span class="hljs-built_in">require</span>(<span class="hljs-string">"jsonwebtoken"</span>);
<span class="hljs-keyword">const</span> sendEmail = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../utils/email"</span>)

<span class="hljs-built_in">exports</span>.signup = catchAsync(<span class="hljs-keyword">async</span> (req, res, next) =&gt; {
  <span class="hljs-keyword">const</span> { email, password, passwordConfirm, username } = req.body;

  <span class="hljs-keyword">const</span> existingUser = <span class="hljs-keyword">await</span> User.findOne({ email });

  <span class="hljs-keyword">if</span> (existingUser) <span class="hljs-keyword">return</span> next(<span class="hljs-keyword">new</span> AppError(<span class="hljs-string">"Email already registered"</span>, <span class="hljs-number">400</span>));

  <span class="hljs-keyword">const</span> otp = generateOtp();

  <span class="hljs-keyword">const</span> otpExpires = <span class="hljs-built_in">Date</span>.now() + <span class="hljs-number">24</span> <span class="hljs-number">60</span> <span class="hljs-number">60</span> * <span class="hljs-number">1000</span>; <span class="hljs-comment">//when thhe otp will expire (1 day)</span>

  <span class="hljs-keyword">const</span> newUser = <span class="hljs-keyword">await</span> User.create({
    username,
    email,
    password,
    passwordConfirm,
    otp,
    otpExpires,
  });

  <span class="hljs-comment">//configure email sending functionality</span>
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">await</span> sendEmail({
      <span class="hljs-attr">email</span>: newUser.email,
      <span class="hljs-attr">subject</span>: <span class="hljs-string">"OTP for email Verification"</span>,
      <span class="hljs-attr">html</span>: <span class="hljs-string">`&lt;h1&gt;Your OTP is : <span class="hljs-subst">${otp}</span>&lt;/h1&gt;`</span>,
    });

    createSendToken(newUser, <span class="hljs-number">200</span>, res, <span class="hljs-string">"Registration successful"</span>);
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Email send error:"</span>, error);
    <span class="hljs-keyword">await</span> User.findByIdAndDelete(newUser.id);
    <span class="hljs-keyword">return</span> next(
      <span class="hljs-keyword">new</span> AppError(<span class="hljs-string">"There is an error sending the email. Try again"</span>, <span class="hljs-number">500</span>)
    );
  }
});
</code></pre>
<p><code>const { email, password, passwordConfirm, username } = req.body;</code> extracts the necessary registration details from the incoming request: email, password, password confirmation, and username during user sign-up.</p>
<p><code>const existingUser = await User.findOne({ email });</code> checks the database to see if a user already exists with the given email. If yes, it sends an error response using your <code>AppError</code> utility.</p>
<p><code>const otp = generateOtp();</code> generates the OTP, and <code>const otpExpires =</code> <a target="_blank" href="http://date.now"><code>Date.now</code></a><code>()…..</code> is used to set the OTP to expire at a specified time or day.</p>
<p>With <code>const newUser = await User.create({…});</code>, the new user is saved in MongoDB with their credentials and the OTP info, with the password automatically hashed.</p>
<p><code>await sendEmail({…});</code> sends an email to the user. This email contains their sign-in OTP. If the email is sent successfully, <code>createSendToken(newUser, 200, res, "Registration successful");</code> (which is a utility function) generates a JWT token and sends it in the response with a success message.</p>
<p>If the email fails to send or something goes wrong, <code>await User.findByIdAndDelete(</code><a target="_blank" href="http://newuser.id"><code>newUser.id</code></a><code>);</code> deletes the user from the database to keep things clean, and an error message of <code>There is an error sending the email. Try again", 500</code> is returned.</p>
<h3 id="heading-generate-otp"><strong>Generate OTP</strong></h3>
<p>To ensure that your users' OTP is successfully sent to them, in the utils folder, create a new file and name it <code>generateOtp.js</code>. Then add the code:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.floor(<span class="hljs-number">1000</span> + <span class="hljs-built_in">Math</span>.random() * <span class="hljs-number">9000</span>).toString();
};
</code></pre>
<p>The code above is a function that generates a user's random 4-digit OTP and returns it as a string.</p>
<p>After completing the code above, go to your authController.js and ensure you import the <code>generateOtp.js</code> in the import section.</p>
<h3 id="heading-create-user-token"><strong>Create User Token</strong></h3>
<p>Next, the user sign-in token will be created, and it will be assigned to the user upon sign-in.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> signToken = <span class="hljs-function">(<span class="hljs-params">userId</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> jwt.sign({ <span class="hljs-attr">id</span>: userId }, process.env.JWT_SECRET, {
    <span class="hljs-attr">expiresIn</span>: process.env.JWT_EXPIRES_IN || <span class="hljs-string">"90d"</span>,
  });
};

<span class="hljs-comment">//function to create the token</span>
<span class="hljs-keyword">const</span> createSendToken = <span class="hljs-function">(<span class="hljs-params">user, statusCode, res, message</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> token = signToken(user._id);

  <span class="hljs-comment">//function to generate the cookie</span>
  <span class="hljs-keyword">const</span> cookieOptions = {
    <span class="hljs-attr">expires</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(
      <span class="hljs-built_in">Date</span>.now() + process.env.JWT_COOKIE_EXPIRES_IN <span class="hljs-number">24</span> <span class="hljs-number">60</span> <span class="hljs-number">60</span> <span class="hljs-number">1000</span>
    ),

    <span class="hljs-attr">httponly</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">secure</span>: process.env.NODE_ENV === <span class="hljs-string">"production"</span>, <span class="hljs-comment">//only secure in production</span>
    <span class="hljs-attr">sameSite</span>: process.env.NODE_ENV === <span class="hljs-string">"production"</span> ? <span class="hljs-string">"none"</span> : <span class="hljs-string">"Lax"</span>,
  };

  res.cookie(<span class="hljs-string">"token"</span>, token, cookieOptions);

  user.password = <span class="hljs-literal">undefined</span>;
  user.passwordConfirm = <span class="hljs-literal">undefined</span>;
  user.otp = <span class="hljs-literal">undefined</span>;
</code></pre>
<p>Before the code above can work perfectly, create a JWT in your <code>.env</code> file.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//.env</span>
JWT_SECRET = kaklsdolrnnhjfsnlsoijfbwhjsioennbandksd;
JWT_EXPIRES_IN = <span class="hljs-number">90</span>d
JWT_COOKIE_EXPIRES_IN = <span class="hljs-number">90</span>
</code></pre>
<p>The code above is how the <code>.env</code> file should look. Your <code>JWT_SECRET</code> can be anything, just as you can see in the code.</p>
<p>Note: The user token creation logic should run before the sign-in logic. So in that case, the <code>signToken</code> and <code>createSendToken</code> logic should be placed at the top before the <code>signup</code> logic.</p>
<h3 id="heading-send-email"><strong>Send Email</strong></h3>
<p>Next, you need to configure your email sending functionality so you can automatically send the user's OTP to their email whenever they sign in. To configure the email, head to the utils folder, create a new file, and give it a name. In this example, the name is <code>email.js</code>.</p>
<p>In <code>email.js,</code> we will send emails using the <code>nodemailer</code> package and Gmail as a provider.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//email.js</span>
<span class="hljs-keyword">const</span> nodemailer = <span class="hljs-built_in">require</span>(<span class="hljs-string">'nodemailer'</span>);

<span class="hljs-keyword">const</span> sendEmail = <span class="hljs-keyword">async</span> (options) =&gt; {
  <span class="hljs-keyword">const</span> transporter = nodemailer.createTransport({
    <span class="hljs-attr">service</span>: <span class="hljs-string">'Gmail'</span>,
    <span class="hljs-attr">auth</span>: {
      <span class="hljs-attr">user</span>: process.env.HOST_EMAIL,
      <span class="hljs-attr">pass</span>: process.env.EMAIL_PASS
    }
  })

  <span class="hljs-comment">//defining email option and structure</span>

  <span class="hljs-keyword">const</span> mailOptions = {
    <span class="hljs-attr">from</span>: <span class="hljs-string">`"{HOST Name}" &lt;{HOST Email} &gt;`</span>,
    <span class="hljs-attr">to</span>: options.email,
    <span class="hljs-attr">subject</span>: options.subject,
    <span class="hljs-attr">html</span>: options.html,
  };
  <span class="hljs-keyword">await</span> transporter.sendMail(mailOptions);
};

<span class="hljs-built_in">module</span>.exports = sendEmail;
</code></pre>
<p>From the code above, the <code>const nodemailer = require('nodemailer');</code> command imports the <code>nodemailer</code> package. This is a popular Node.js library for sending emails.</p>
<p>The <code>const transporter = nodemailer.createTransport({…..})</code> is an email transporter. Since we will be using the Gmail service provider, <code>service</code> will be assigned to <code>Gmail</code> and <code>auth</code> pulls your Gmail address and password from the <code>.env</code> file where it’s stored.</p>
<p>Note: The password is not your actual Gmail password but rather your Gmail app password. You can see how you can get your <a target="_blank" href="https://youtu.be/MkLX85XU5rU?si=yBIj4MJDLY7-k-c4">Gmail password here</a>.</p>
<p>Once you’ve successfully gotten your Gmail app password, store it in your <code>.env</code> file.</p>
<h3 id="heading-route-creation"><strong>Route Creation</strong></h3>
<p>At this point, you have finished setting up your project's signup function. Next, you need to test whether your signup works properly using Postman. But before that, let’s set up and define a route where the signup function will be executed.</p>
<p>To set up your route, create a new folder in your backend directory named "routes" and a file named <code>userRouter.js</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">"express"</span>);
<span class="hljs-keyword">const</span> {signup} = <span class="hljs-built_in">require</span>(“../controller/authController”);

<span class="hljs-keyword">const</span> router = express.Router();
router.post(<span class="hljs-string">"/signup"</span>, signup);

<span class="hljs-built_in">module</span>.exports = router;
</code></pre>
<p>Next, go to your <code>App.js</code> file and add the router to it.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> userRouter = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./routes/userRouters"</span>); <span class="hljs-comment">//Route import statement</span>
app.use(<span class="hljs-string">"/api/v1/users"</span>, userRouter) <span class="hljs-comment">//common route for all auth, i.e sign up, log in, forget password, etc.</span>
</code></pre>
<p>After setting up your routes, you can test your signup to see if it works. This is a post request, and the route URL will be <a target="_blank" href="http://localhost:8000/api/v1/users/signup%60"><code>http://localhost:8000/api/v1/users/signup</code></a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752704061383/380d8480-9997-4678-8ca7-0ed86ea24481.png" alt="New user Sign up Testing" class="image--center mx-auto" width="1280" height="716" loading="lazy"></p>
<p>The image above shows that the signup function works perfectly with a <code>statusCode</code> of <code>200</code> and an OTP code being sent to the user’s email.</p>
<p>Congratulations on reaching this point! You can check your MongoDB database to see if the user is displayed there.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752703565468/0f23f8ab-d17e-4555-8347-475bb6483b8a.png" alt="Mongo-DB-Compass-User-Display" class="image--center mx-auto" width="1280" height="495" loading="lazy"></p>
<p>From the image above, you can see that the user details are obtained and the password is in an encrypted form, which ensures the user credentials are safe.</p>
<h3 id="heading-create-a-verify-account-controller-function"><strong>Create a Verify Account Controller Function</strong></h3>
<p>In this section, you’ll create a Verify Account controller function. This function verifies a user’s account using the OTP code sent to their email address.</p>
<p>First, go to your <code>authController.js</code> file and add:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">exports</span>.verifyAccount = catchAsync(<span class="hljs-keyword">async</span> (req, res, next) =&gt; {
  <span class="hljs-keyword">const</span> { email, otp } = req.body;

  <span class="hljs-keyword">if</span> (!email || !otp) {
    <span class="hljs-keyword">return</span> next(<span class="hljs-keyword">new</span> AppError(<span class="hljs-string">"Email and OTP are required"</span>, <span class="hljs-number">400</span>));
  }

  <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> User.findOne({ email });

  <span class="hljs-keyword">if</span> (!user) {
    <span class="hljs-keyword">return</span> next(<span class="hljs-keyword">new</span> AppError(<span class="hljs-string">"No user found with this email"</span>, <span class="hljs-number">404</span>));
  }

  <span class="hljs-keyword">if</span> (user.otp !== otp) {
    <span class="hljs-keyword">return</span> next(<span class="hljs-keyword">new</span> AppError(<span class="hljs-string">"Invalid OTP"</span>, <span class="hljs-number">400</span>));
  }

  <span class="hljs-keyword">if</span> (<span class="hljs-built_in">Date</span>.now() &gt; user.otpExpires) {
    <span class="hljs-keyword">return</span> next(
      <span class="hljs-keyword">new</span> AppError(<span class="hljs-string">"OTP has expired. Please request a new OTP."</span>, <span class="hljs-number">400</span>)
    );
  }

  user.isVerified = <span class="hljs-literal">true</span>;
  user.otp = <span class="hljs-literal">undefined</span>;
  user.otpExpires = <span class="hljs-literal">undefined</span>;

  <span class="hljs-keyword">await</span> user.save({ <span class="hljs-attr">validateBeforeSave</span>: <span class="hljs-literal">false</span> });

  <span class="hljs-comment">// ✅ Optionally return a response without logging in</span>
  res.status(<span class="hljs-number">200</span>).json({
    <span class="hljs-attr">status</span>: <span class="hljs-string">"success"</span>,
    <span class="hljs-attr">message</span>: <span class="hljs-string">"Email has been verified"</span>,
  });
});
</code></pre>
<p>Next, create a middleware function to authenticate the currently logged-in user.</p>
<p>In your backend directory, create a new folder called <code>middlewares</code>. Inside the <code>middlewares</code> folder, create a file named <code>isAuthenticated.js</code>.</p>
<p>Add the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//isAuthenticated.js</span>
<span class="hljs-keyword">const</span> jwt = <span class="hljs-built_in">require</span>(<span class="hljs-string">"jsonwebtoken"</span>);
<span class="hljs-keyword">const</span> catchAsync = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../utils/catchAsync"</span>);
<span class="hljs-keyword">const</span> AppError = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../utils/appError"</span>);
<span class="hljs-keyword">const</span> User = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../model/userModel"</span>);

<span class="hljs-keyword">const</span> isAuthenticated = catchAsync(<span class="hljs-keyword">async</span> (req, res, next) =&gt; {
  <span class="hljs-keyword">let</span> token;

  <span class="hljs-comment">// 1. Retrieve token from cookies or Authorization header</span>
  <span class="hljs-keyword">if</span> (req.cookies?.token) {
    token = req.cookies.token;
  } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (req.headers.authorization?.startsWith(<span class="hljs-string">"Bearer"</span>)) {
    token = req.headers.authorization.split(<span class="hljs-string">" "</span>)[<span class="hljs-number">1</span>];
  }

  <span class="hljs-keyword">if</span> (!token) {
    <span class="hljs-keyword">return</span> next(
      <span class="hljs-keyword">new</span> AppError(
        <span class="hljs-string">"You are not logged in. Please log in to access this resource."</span>,
        <span class="hljs-number">401</span>
      )
    );
  }

  <span class="hljs-comment">// 2. Verify token</span>
  <span class="hljs-keyword">let</span> decoded;
  <span class="hljs-keyword">try</span> {
    decoded = jwt.verify(token, process.env.JWT_SECRET);
  } <span class="hljs-keyword">catch</span> (err) {
    <span class="hljs-keyword">return</span> next(
      <span class="hljs-keyword">new</span> AppError(<span class="hljs-string">"Invalid or expired token. Please log in again."</span>, <span class="hljs-number">401</span>)
    );
  }

<span class="hljs-comment">// 3. Confirm user still exists in database</span>
  <span class="hljs-keyword">const</span> currentUser = <span class="hljs-keyword">await</span> User.findById(decoded._id);
  <span class="hljs-keyword">if</span> (!currentUser) {
    <span class="hljs-keyword">return</span> next(
      <span class="hljs-keyword">new</span> AppError(<span class="hljs-string">"User linked to this token no longer exists."</span>, <span class="hljs-number">401</span>)
    );
  }

  <span class="hljs-comment">// 4. Attach user info to request</span>
  req.user = currentUser;
  req.user = {
    <span class="hljs-attr">id</span>: currentUser.id,
    <span class="hljs-attr">name</span>: currentUser.name,
  };

  next();
});

<span class="hljs-built_in">module</span>.exports = isAuthenticated;
<span class="hljs-string">``</span><span class="hljs-string">`
Now, go to your `</span>userRouter.js<span class="hljs-string">` file and add the route for the verify account function:
`</span><span class="hljs-string">``</span>
<span class="hljs-keyword">const</span> { verifyAccount} = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../controller/authController"</span>);
<span class="hljs-keyword">const</span> isAuthenticated = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../middlewares/isAuthenticated"</span>);
router.post(<span class="hljs-string">"/verify"</span>, isAuthenticated, verifyAccount);
</code></pre>
<p>Here is what these two sets of code are doing:</p>
<p>When a user sends a request to the <code>/verify</code> route, the <code>isAuthenticated</code> middleware runs first. It checks whether a valid token exists in the cookie or authorization header. If no token is found, it throws an error: <code>You are not logged in. Please log in to access this resource.</code></p>
<p>If a token is found, it verifies the token and checks if the associated user still exists. If not, another error is thrown: <code>"User linked to this token no longer exists."</code></p>
<p>If the user exists and the token is valid, their details are attached to the request (<code>req.user</code>). The request then proceeds to the <code>verifyAccount</code> controller, which handles OTP verification.</p>
<p>You can test this endpoint using Postman with a POST request to: <a target="_blank" href="http://localhost:8000/api/v1/users/verify%60"><code>http://localhost:8000/api/v1/users/verify</code></a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752703870392/a534d04f-7cb9-4f84-92e1-e9844cfa6921.png" alt="Verify-Account" class="image--center mx-auto" width="1280" height="723" loading="lazy"></p>
<p>The image above shows that the verify token function is working well, and a status code of <code>200</code> is displayed.</p>
<h3 id="heading-login-function"><strong>Login Function</strong></h3>
<p>If you’ve reached this point, you’ve successfully signed up and verified a user’s account. </p>
<p>Now it’s time to create the login function, which allows a verified user to access their account. Here’s how you can do that:</p>
<p>Go to your <code>authController.js</code> file and create your login function by adding the following:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">exports</span>.login = catchAsync(<span class="hljs-keyword">async</span> (req, res, next) =&gt; {
  <span class="hljs-keyword">const</span> { email, password } = req.body;

  <span class="hljs-comment">// 1. Validate email &amp; password presence</span>
  <span class="hljs-keyword">if</span> (!email || !password) {
    <span class="hljs-keyword">return</span> next(<span class="hljs-keyword">new</span> AppError(<span class="hljs-string">"Please provide email and password"</span>, <span class="hljs-number">400</span>));
  }

  <span class="hljs-comment">// 2. Check if user exists and include password</span>
  <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> User.findOne({ email }).select(<span class="hljs-string">"+password"</span>);
  <span class="hljs-keyword">if</span> (!user || !(<span class="hljs-keyword">await</span> user.correctPassword(password, user.password))) {
    <span class="hljs-keyword">return</span> next(<span class="hljs-keyword">new</span> AppError(<span class="hljs-string">"Incorrect email or password"</span>, <span class="hljs-number">401</span>));
  }

  <span class="hljs-comment">// 3. Create JWT token</span>
  <span class="hljs-keyword">const</span> token = signToken(user._id);

  <span class="hljs-comment">// 4. Configure cookie options</span>
  <span class="hljs-keyword">const</span> cookieOptions = {
    <span class="hljs-attr">expires</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(
      <span class="hljs-built_in">Date</span>.now() +
        (<span class="hljs-built_in">parseInt</span>(process.env.JWT_COOKIE_EXPIRES_IN, <span class="hljs-number">10</span>) || <span class="hljs-number">90</span>) <span class="hljs-number">24</span> <span class="hljs-number">60</span> <span class="hljs-number">60</span> <span class="hljs-number">1000</span>
    ),
    <span class="hljs-attr">httpOnly</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-comment">// secure: process.env.NODE_ENV === "production",</span>
    <span class="hljs-comment">// sameSite: process.env.NODE_ENV === "production" ?</span>
    <span class="hljs-comment">//  "None" : "Lax",</span>

    <span class="hljs-comment">//set to false during or for local HTTP and cross-origin</span>
    <span class="hljs-attr">secure</span>: <span class="hljs-literal">false</span>,
    <span class="hljs-attr">sameSite</span>: <span class="hljs-string">"Lax"</span>,
  };

  <span class="hljs-comment">// 5. Send cookie</span>
  res.cookie(<span class="hljs-string">"token"</span>, token, cookieOptions);

});
</code></pre>
<p><code>if (!email || !password) {…}</code> checks if the user actually provided both an email and a password. If not, it returns the error: <code>Please provide email and password", 400</code>.</p>
<p><code>const user = await User.findOne({ email }).select("+password");</code> searches the database for a user with the provided email and explicitly includes the password field, since it’s normally hidden by default in the schema.</p>
<p><code>if (!user || !(await user.correctPassword(…))) {…}</code> checks if the user exists and if the password entered matches the one stored in the database (after hashing comparison). If either is wrong, it throws: <code>Incorrect email or password</code>.</p>
<p>The line <code>signToken(user._id)</code> generates a JWT using the user's unique ID. The <code>cookieOptions</code> object configures how the cookie behaves – it sets the cookie to expire after a specific number of days defined in the <code>.env</code> file, marks it as <code>httpOnly</code> to prevent JavaScript access for security, sets <code>secure</code> to <code>false</code> since the app is currently in development, and uses <code>sameSite: "Lax"</code> to allow cross-origin requests during local testing. </p>
<p>Finally, <code>res.cookie(...)</code> sends the token as a cookie attached to the HTTP response, enabling the client to store the token for authentication purposes.</p>
<p>From the code above, you may have noticed that the password stored in the database is hashed for security reasons. This means it looks completely different from the user's password when logging in. So, even if a user types in the correct password, it won't match the stored hash directly through a simple comparison. </p>
<p>To fix this, you need to compare the entered password with the hashed one using the <code>bcryptjs</code> package.</p>
<p>Head over to your <code>userModel.js</code> file and create a method that handles password comparison. This method will take the plain text password provided by the user and compare it to the hashed password stored in the database.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//userModel.js</span>
<span class="hljs-comment">//create a method responsible for comparing the password stored in the database</span>

userSchema.methods.correctPassword = <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">password, userPassword</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> bcrypt.compare(password, userPassword);
};
</code></pre>
<p>This <code>correctPassword</code> method uses <code>bcrypt.compare()</code>, which internally hashes the plain password and checks if it matches the stored hashed version. This ensures that login validation works correctly and securely, even though the actual password is not stored in plain text.</p>
<p>Next, add the Login functionality to the <code>userRouter.js</code> file.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> {login} = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../controller/authController"</span>);
<span class="hljs-keyword">const</span> isAuthenticated = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../middlewares/isAuthenticated"</span>);

router.post(<span class="hljs-string">"/login"</span>, login);
</code></pre>
<p>You can test this endpoint using Postman with a <code>POST</code> request to: <a target="_blank" href="http://localhost:8000/api/v1/users/login%60"><code>http://localhost:8000/api/v1/users/login</code></a></p>
<h3 id="heading-logout-function"><strong>Logout Function</strong></h3>
<p>At this point, you can implement the logout function to end a user's session securely. To do this, navigate to your <code>authController.js</code> file and add the following function:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//creating a log out function</span>
<span class="hljs-built_in">exports</span>.logout = catchAsync(<span class="hljs-keyword">async</span> (req, res, next) =&gt; {
  res.cookie(<span class="hljs-string">"token"</span>, <span class="hljs-string">"loggedout"</span>, {
    <span class="hljs-attr">expires</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-number">0</span>),
    <span class="hljs-attr">httpOnly</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">secure</span>: process.env.NODE_ENV === <span class="hljs-string">"production"</span>,
  });

  res.status(<span class="hljs-number">200</span>).json({
    <span class="hljs-attr">status</span>: <span class="hljs-string">"success"</span>,
    <span class="hljs-attr">message</span>: <span class="hljs-string">"Logged out successfully"</span>,
  });
});
</code></pre>
<p>This function works by overwriting the authentication cookie named <code>token</code> with the value <code>"loggedout"</code> and setting its expiration time to the past using <code>new Date(0)</code>. This effectively invalidates the cookie and removes it from the browser. </p>
<p>The <code>httpOnly: true</code> flag ensures that the cookie cannot be accessed via JavaScript, which protects it from XSS attacks, while the <code>secure</code> flag ensures that the cookie is only sent over HTTPS in a production environment. Once the cookie is cleared, a success response is returned with the message "Logged out successfully" to confirm the action.</p>
<p>Next, add the <code>logout</code> functionality to your route:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> {logout} = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../controller/authController"</span>);
<span class="hljs-keyword">const</span> isAuthenticated = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../middlewares/isAuthenticated"</span>);

router.post(<span class="hljs-string">"/logout"</span>, logout);
</code></pre>
<p>Then, head to Postman to test your logout function and see if it works.</p>
<h2 id="heading-frontend-setup"><strong>Frontend Setup</strong></h2>
<p>Now that your backend is up and running, you can integrate it into your frontend application.</p>
<p>First, navigate to the frontend directory using the command <code>cd Frontend</code>.</p>
<p>Create a new folder in the <code>src</code> folder where your authentication-related files will live. Depending on your preference or app structure, you can name it something like <code>auth</code> or <code>pages</code>. Then, create a new file called <code>NewUser. js</code>. This file will handle user signup functionality.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">'axios'</span>;
<span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { Link, useNavigate } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;
<span class="hljs-keyword">import</span> { Loader } <span class="hljs-keyword">from</span> <span class="hljs-string">'lucide-react'</span>;
<span class="hljs-keyword">import</span> { useDispatch } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-redux'</span>;
<span class="hljs-keyword">import</span> { setAuthUser, setPendingEmail } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../../../store/authSlice'</span>;

<span class="hljs-keyword">const</span> API_URL = <span class="hljs-keyword">import</span>.meta.env.VITE_API_URL;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">NewUser</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> dispatch = useDispatch();
  <span class="hljs-keyword">const</span> navigate = useNavigate();

  <span class="hljs-keyword">const</span> [loading, setLoading] = useState(<span class="hljs-literal">false</span>);

  <span class="hljs-keyword">const</span> [formData, setFormData] = useState({
    <span class="hljs-attr">username</span>: <span class="hljs-string">''</span>,
    <span class="hljs-attr">email</span>: <span class="hljs-string">''</span>,
    <span class="hljs-attr">password</span>: <span class="hljs-string">''</span>,
    <span class="hljs-attr">passwordConfirm</span>: <span class="hljs-string">''</span>,
  });

  <span class="hljs-keyword">const</span> handleChange = <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> { name, value } = e.target;
    setFormData(<span class="hljs-function">(<span class="hljs-params">prev</span>) =&gt;</span> ({ ...prev, [name]: value }));
  };

  <span class="hljs-keyword">const</span> submitHandler = <span class="hljs-keyword">async</span> (e) =&gt; {
    e.preventDefault();
    setLoading(<span class="hljs-literal">true</span>);
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> axios.post(<span class="hljs-string">`<span class="hljs-subst">${API_URL}</span>/users/signup`</span>, formData, {
        <span class="hljs-attr">withCredentials</span>: <span class="hljs-literal">true</span>,
      });
      <span class="hljs-keyword">const</span> user = response.data.data.user;
      dispatch(setAuthUser(user));
      dispatch(setPendingEmail(formData.email)); <span class="hljs-comment">// Save email for OTP</span>
      navigate(<span class="hljs-string">'/verifyAcct'</span>); <span class="hljs-comment">// Navigate to OTP verification page</span>
    } <span class="hljs-keyword">catch</span> (error) {
      alert(error.response?.data?.message || <span class="hljs-string">'Signup failed'</span>);
    } <span class="hljs-keyword">finally</span> {
      setLoading(<span class="hljs-literal">false</span>);
    }
  };

  <span class="hljs-keyword">return</span> (
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
// visit the frontend Github repository to see the remaining code for the OTP Verification

https://github.com/Derekvibe/Telehealth_Frontend/blob/main/src/pages/Auth/Join/NewUser.jsx
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> NewUser;
</code></pre>
<p>The code above renders a signup form with fields for <code>username</code>, <code>email</code>, <code>password</code> and <code>passwordConfirm</code>. When the user submits the form, the frontend sends a <code>POST</code> request to the backend’s <code>/users/signup</code> endpoint using <code>Axios</code>. The <code>withCredentials: true</code> option ensures cookies like the <code>auth token</code> are properly set by the backend.</p>
<p>If the signup is successful, the user data is dispatched into Redux using <code>setAuthUser()</code>, and their email is saved with <code>setPendingEmail()</code> so it can be used during <code>OTP</code> verification. Then, the user is redirected to the <code>/verifyAcct</code> route, where they can enter their <code>OTP</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752704266192/0d1d5891-000a-48dc-a1d8-306a0103824a.png" alt="Frontend-Sign-Up" class="image--center mx-auto" width="815" height="675" loading="lazy"></p>
<h3 id="heading-otp-verification-page"><strong>OTP Verification Page</strong></h3>
<p>The OTP verification page is the next step in the user authentication process. Once a user signs up, they are redirected to enter the 4-digit OTP sent to their email. This verifies their account before allowing login access.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState, useRef, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { useSelector, useDispatch } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-redux'</span>;
<span class="hljs-keyword">import</span> { useNavigate, Link } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;
<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">'axios'</span>;
<span class="hljs-keyword">import</span> { clearPendingEmail } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../../../store/authSlice'</span>;

<span class="hljs-keyword">const</span> API_URL = <span class="hljs-keyword">import</span>.meta.env.VITE_API_URL || <span class="hljs-string">'http://localhost:5000/api'</span>; <span class="hljs-comment">// adjust as needed</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">VerifyAcct</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [code, setCode] = useState([<span class="hljs-string">''</span>, <span class="hljs-string">''</span>, <span class="hljs-string">''</span>, <span class="hljs-string">''</span>]);
  <span class="hljs-keyword">const</span> [loading, setLoading] = useState(<span class="hljs-literal">false</span>);
  <span class="hljs-keyword">const</span> [resendLoading, setResendLoading] = useState(<span class="hljs-literal">false</span>);
  <span class="hljs-keyword">const</span> [timer, setTimer] = useState(<span class="hljs-number">60</span>);

  <span class="hljs-keyword">const</span> inputsRef = useRef([]);
  <span class="hljs-keyword">const</span> dispatch = useDispatch();
  <span class="hljs-keyword">const</span> navigate = useNavigate();
  <span class="hljs-keyword">const</span> email = useSelector(<span class="hljs-function">(<span class="hljs-params">state</span>) =&gt;</span> state.auth.pendingEmail);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">let</span> interval;
    <span class="hljs-keyword">if</span> (timer &gt; <span class="hljs-number">0</span>) {
      interval = <span class="hljs-built_in">setInterval</span>(<span class="hljs-function">() =&gt;</span> setTimer(<span class="hljs-function">(<span class="hljs-params">prev</span>) =&gt;</span> prev - <span class="hljs-number">1</span>), <span class="hljs-number">1000</span>);
    }
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">clearInterval</span>(interval);
  }, [timer]);

  <span class="hljs-keyword">const</span> handleChange = <span class="hljs-function">(<span class="hljs-params">value, index</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (!<span class="hljs-regexp">/^\d*$/</span>.test(value)) <span class="hljs-keyword">return</span>;
    <span class="hljs-keyword">const</span> newCode = [...code];
<span class="hljs-comment">// visit the frontend Github repository to see the remaining code for the OTP Verification</span>
https:<span class="hljs-comment">//github.com/Derekvibe/Telehealth_Frontend/blob/main/src/pages/Auth/login/VerifyAcct.jsx</span>
}
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> VerifyAcct;
</code></pre>
<p>Here’s what the code does: </p>
<p>The OTP is stored as an array of 4 characters (<code>[‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘]</code>). Each box only accepts digits, and focus automatically moves to the next input as the user types in the digit. The focus returns to the previous input box if the user presses the backspace button on an empty box.</p>
<p>When the OTP has been added and the form is submitted, the 4-digit code is joined into a string and an <code>HTTP POST</code> request is made to the backend <code>/user/verify/</code> endpoint along with the stored email and OTP. If the verification is successful, the user is alerted and redirected to the login page, and if not, an error is shown.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752704448954/8ea46e32-c6d9-42e1-a016-f04b259eb0e7.png" alt="Frontend-OTP" class="image--center mx-auto" width="798" height="631" loading="lazy"></p>
<h3 id="heading-log-in"><strong>Log In</strong></h3>
<p>Now you can create the login interface for your application. First, create a <code>Login.jsx</code> file and input the code:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//Login.Jsx</span>

<span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { Link, useNavigate } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;
<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">'axios'</span>;

<span class="hljs-keyword">const</span> API_URL = <span class="hljs-keyword">import</span>.meta.env.VITE_API_URL || <span class="hljs-string">'https://telehealth-backend-2m1f.onrender.com/api/v1'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Join</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [formData, setFormData] = useState({ <span class="hljs-attr">email</span>: <span class="hljs-string">''</span>, <span class="hljs-attr">password</span>: <span class="hljs-string">''</span> });
  <span class="hljs-keyword">const</span> [loading, setLoading] = useState(<span class="hljs-literal">false</span>);
  <span class="hljs-keyword">const</span> [error, setError] = useState(<span class="hljs-string">''</span>);
  <span class="hljs-keyword">const</span> navigate = useNavigate();

  <span class="hljs-keyword">const</span> handleChange = <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
    setFormData({ ...formData, [e.target.name]: e.target.value });
  };

  <span class="hljs-keyword">const</span> handleLogin = <span class="hljs-keyword">async</span> (e) =&gt; {
    e.preventDefault();
    setLoading(<span class="hljs-literal">true</span>);
    setError(<span class="hljs-string">''</span>);

    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> axios.post(<span class="hljs-string">`<span class="hljs-subst">${API_URL}</span>/users/login`</span>, formData, {
        <span class="hljs-attr">withCredentials</span>: <span class="hljs-literal">true</span>,
      });

      <span class="hljs-keyword">if</span> (res.data.status === <span class="hljs-string">'success'</span>) {
        <span class="hljs-keyword">const</span> { token, user, streamToken } = res.data;

        <span class="hljs-comment">// Save to localStorage</span>
        <span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'authToken'</span>, token);
        <span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'user'</span>, <span class="hljs-built_in">JSON</span>.stringify(user));
        <span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'streamToken'</span>, streamToken);

        navigate(<span class="hljs-string">'/dashboard'</span>);
      }
    } <span class="hljs-keyword">catch</span> (err) {
      <span class="hljs-built_in">console</span>.error(err);
      setError(
        err.response?.data?.message || <span class="hljs-string">'Something went wrong. Please try again.'</span>
      );
    } <span class="hljs-keyword">finally</span> {
      setLoading(<span class="hljs-literal">false</span>);
    }
  };

  <span class="hljs-keyword">return</span> (
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
{// visit the frontend Github repository to see the remaining code for the OTP Verification
https://github.com/Derekvibe/Telehealth_Frontend/blob/main/src/pages/Auth/login/Login.jsx
 <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
);
}
</code></pre>
<p>The <code>Export default Join;</code> component allows a registered and verified user to log into your application using their email and password. It handles form submission, talks to the backend, and securely stores user data if login is successful. </p>
<p><code>handleChange()</code> updates the email or password field as the user types. </p>
<p><code>handleLogin()</code> is triggered when the login form is submitted. When the login button is triggered, it sends a <code>Post</code> request to <code>/users/login</code> with the form data, which includes <code>{withCredentials: true}</code> to enable cookie handling. </p>
<p>If login is successful, it extracts the JWT token, user data, and Stream Chat token from the response and stores them in the <code>localStorage</code> so the user stays logged in across sessions. Then it redirects the user to the dashboard page using <code>navigate(‘/dashboard’)</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752704515845/55c6e74a-a8bc-462a-b988-67b0e8df40ac.png" alt="Frontend-Login" class="image--center mx-auto" width="859" height="583" loading="lazy"></p>
<h3 id="heading-set-up-the-frontend-route"><strong>Set Up the Frontend Route</strong></h3>
<p>Just as you set up the backend route, you have to do the same for the frontend.</p>
<p>Head to <code>App.jsx</code>. Before adding the route, make sure you have installed the <code>react-router-dom</code> package. If not, run this command in the frontend terminal: </p>
<p><code>npm install react-router-dom</code></p>
<p>Then, add the command to your <code>App.jsx</code> file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { createBrowserRouter, RouterProvider } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;
<span class="hljs-keyword">import</span> HomeIndex <span class="hljs-keyword">from</span> <span class="hljs-string">'./pages/Home/HomeIndex'</span>;
<span class="hljs-keyword">import</span> Hero <span class="hljs-keyword">from</span> <span class="hljs-string">'./pages/Home/Hero'</span>;

<span class="hljs-comment">//Authentication Section</span>
<span class="hljs-keyword">import</span> NewUser <span class="hljs-keyword">from</span> <span class="hljs-string">'./pages/Auth/Join/NewUser'</span>;
<span class="hljs-keyword">import</span> Login <span class="hljs-keyword">from</span> <span class="hljs-string">'./pages/Auth/login/Login'</span>
<span class="hljs-keyword">import</span> VerifyAcct <span class="hljs-keyword">from</span> <span class="hljs-string">'./pages/Auth/login/VerifyAcct'</span>;

<span class="hljs-comment">// Dashboard</span>
<span class="hljs-keyword">import</span> Dashboard <span class="hljs-keyword">from</span> <span class="hljs-string">'./pages/Dashboard/Dashboard'</span>;
<span class="hljs-keyword">import</span> VideoStream <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/VideoStream'</span>;

<span class="hljs-keyword">const</span> router = createBrowserRouter([
  {
    <span class="hljs-attr">path</span>: <span class="hljs-string">'/'</span>,
    <span class="hljs-attr">element</span>: <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">HomeIndex</span> /&gt;</span></span>,
    children: [
      { <span class="hljs-attr">index</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">element</span>: <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Hero</span> /&gt;</span></span> }
    ],
  },

  {
    <span class="hljs-attr">path</span>: <span class="hljs-string">'signup'</span>,
    <span class="hljs-attr">element</span>: <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">NewUser</span> /&gt;</span></span>,
    children: [
      { <span class="hljs-attr">index</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">element</span>: <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">NewUser</span> /&gt;</span></span> }
    ],
  },

  {
    <span class="hljs-attr">path</span>: <span class="hljs-string">'login'</span>,
    <span class="hljs-attr">element</span>: <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Login</span> /&gt;</span></span>,
    children: [
      {<span class="hljs-attr">index</span>:<span class="hljs-literal">true</span>, <span class="hljs-attr">element</span>:<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Login</span> /&gt;</span></span>}
    ]
  },

]);
{<span class="hljs-comment">// visit the frontend Github repository to see the remaining code for the OTP Verification</span>
<span class="hljs-attr">https</span>:<span class="hljs-comment">//github.com/Derekvibe/Telehealth_Frontend/blob/main/src/App.jsx}</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'border border-red-700 w-full min-w-[100vw] min-h-[100vh]'</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">RouterProvider</span> <span class="hljs-attr">router</span>=<span class="hljs-string">{router}</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<h2 id="heading-stream-chat-and-video-integration"><strong>Stream Chat and Video Integration</strong></h2>
<p>Before proceeding to the dashboard, let’s integrate the Stream <a target="_blank" href="https://getstream.io/chat/">Chat</a> and <a target="_blank" href="https://getstream.io/video/">Video</a> functionality into the project.</p>
<p>First, <a target="_blank" href="https://getstream.io/try-for-free/">create a free Stream account</a>, start a new project in your dashboard, and get your <code>APP KEY</code> and <code>API_SECRET</code>.</p>
<pre><code class="lang-javascript">STREAM_API_KEY=your_app_key
STREAM_API_SECRET=your_api_secret
</code></pre>
<p>Watch the Stream <a target="_blank" href="https://youtu.be/kGKq4giL4ok?si=M_nkWAiq4IzGNYD_">Chat React Quick Start Guide</a> to see how you can set it up.</p>
<p>Next, store your Stream <code>APP KEY</code> and <code>API_SECRET</code> in your <code>.env</code>.</p>
<h3 id="heading-install-stream-packages-frontend"><strong>Install Stream Packages (Frontend)</strong></h3>
<p>Now, install the Stream Chat and Video packages in your terminal.</p>
<pre><code class="lang-javascript">npm install stream-chat stream-chat-react
npm install @stream-io/video-react-sdk
npm install @stream-io/stream-chat-css
</code></pre>
<h3 id="heading-stream-token-handler"><strong>Stream Token Handler</strong></h3>
<p>First, create a new file in your frontend Src directory and name it. In this example, it’s <code>StreamContext.jsx</code>. This file sets up a context to fetch and manage the Stream Chat token on login and includes logout functionality.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { createContext, useContext, useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;

<span class="hljs-keyword">const</span> API_URL = <span class="hljs-keyword">import</span>.meta.env.VITE_API_URL || <span class="hljs-string">'https://telehealth-backend-2m1f.onrender.com/api/v1'</span>;

<span class="hljs-comment">// 1. Create the context</span>
<span class="hljs-keyword">const</span> StreamContext = createContext();

<span class="hljs-comment">// 2. Provider component</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> StreamProvider = <span class="hljs-function">(<span class="hljs-params">{ children }</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> [user, setUser] = useState(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [token, setToken] = useState(<span class="hljs-literal">null</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> fetchToken = <span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> axios.get(<span class="hljs-string">`<span class="hljs-subst">${API_URL}</span>/stream/get-token`</span>, {
          <span class="hljs-attr">withCredentials</span>: <span class="hljs-literal">true</span>,
        });

        <span class="hljs-keyword">if</span> (res.data?.user &amp;&amp; res.data?.token) {
          setUser(res.data.user);
          setToken(res.data.token);
          <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Stream user/token:"</span>, res.data);
        } <span class="hljs-keyword">else</span> {
          <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Token or user missing in response:"</span>, res.data);
        }
      } <span class="hljs-keyword">catch</span> (error) {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error fetching Stream token:"</span>, error);
      }
    };

    fetchToken();
  }, []);

  <span class="hljs-comment">//Log out Functionality</span>
  <span class="hljs-keyword">const</span> logout = <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">await</span> axios.post(<span class="hljs-string">`<span class="hljs-subst">${API_URL}</span>/users/logout`</span>, {},
        {
          <span class="hljs-attr">withCredentials</span>: <span class="hljs-literal">true</span>
        });

      <span class="hljs-comment">// Clear localStorage</span>
      <span class="hljs-built_in">localStorage</span>.removeItem(<span class="hljs-string">'authToken'</span>);
      <span class="hljs-built_in">localStorage</span>.removeItem(<span class="hljs-string">'user'</span>);
      <span class="hljs-built_in">localStorage</span>.removeItem(<span class="hljs-string">'streamToken'</span>);

      <span class="hljs-comment">// Clear context</span>
      setUser(<span class="hljs-literal">null</span>);
      setToken(<span class="hljs-literal">null</span>);
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Logout failed"</span>, error);
    }
  };

  <span class="hljs-comment">// Expose Logout with capital L</span>
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">StreamContext.Provider</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">user</span>, <span class="hljs-attr">token</span>, <span class="hljs-attr">Logout:logout</span> }}&gt;</span>
      {children}
    <span class="hljs-tag">&lt;/<span class="hljs-name">StreamContext.Provider</span>&gt;</span></span>
  );
};

<span class="hljs-comment">// 3. Custom hook for easy access</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> useStream = <span class="hljs-function">() =&gt;</span> useContext(StreamContext);
</code></pre>
<p>The code above creates a StreamContext using React’s Context API. In the <code>useEffect</code> section, it makes a <code>GET</code> request to <code>/stream/get-token</code> to fetch the authenticated user and their Stream token. Then it stores them in <code>user</code> and <code>token</code> states. It also provides the user/token through the context so that any component that needs it can make use of it.</p>
<p>Finally, it adds a <code>Logout</code> method that hits the logout endpoint and clears all stored auth data from <code>localStorage</code>.</p>
<p>Next, open your <code>main.jsx</code> and wrap your entire application with the <code>StreamProvider</code> so all child components can access the Stream context.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// main.jsx</span>
<span class="hljs-keyword">import</span> { createRoot } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom/client'</span>;
<span class="hljs-keyword">import</span> { StrictMode } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> App <span class="hljs-keyword">from</span> <span class="hljs-string">'./App'</span>;
<span class="hljs-keyword">import</span> { StreamProvider } <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/StreamContext'</span>;

createRoot(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>)).render(
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">StrictMode</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">StreamProvider</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">StreamProvider</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">StrictMode</span>&gt;</span></span>
);
</code></pre>
<h3 id="heading-set-up-stream-api"><strong>Set Up Stream API</strong></h3>
<p>After successfully creating the streamContent, the next step is to set up the Stream API. This will be the endpoint from which the user ID and user Stream token can be generated and fetched during login.</p>
<p>To set it up, navigate to your backend directory by running <code>cd Backend</code> in your terminal. Then install the Stream package using the command:</p>
<pre><code class="lang-javascript">npm install getstream
npm install stream-chat stream-chat-react
</code></pre>
<p>Open your <code>.env</code> file and add your Stream <code>API KEY</code> and <code>API_SECRET</code>:</p>
<pre><code class="lang-javascript">STREAM_API_KEY=your_app_key
STREAM_API_SECRET=your_api_secret
</code></pre>
<p>Next, open your <code>authController.js</code> and create your Stream Chat logic:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//Initialize the Stream Client</span>
<span class="hljs-keyword">const</span> {StreamChat} = <span class="hljs-built_in">require</span>(<span class="hljs-string">"stream-chat"</span>);
<span class="hljs-keyword">const</span> streamClient = StreamChat.getInstance(
  process.env.STREAM_API_KEY,
  process.env.STREAM_API_SECRET
);

<span class="hljs-comment">// Modifies the `createSendToken to include `streamToken`</span>
<span class="hljs-keyword">const</span> createSendToken = <span class="hljs-function">(<span class="hljs-params">user, statusCode, res, message</span>) =&gt;</span> {
……
<span class="hljs-keyword">const</span> streamToken = streamClient.createToken(user._id.toString());

  <span class="hljs-comment">//structure of the cookie response when sent to the user</span>
  res.status(statusCode).json({
    <span class="hljs-attr">status</span>: <span class="hljs-string">"success"</span>,
    message,
    token,
    streamToken,
    <span class="hljs-attr">data</span>: {
      <span class="hljs-attr">user</span>: {
        <span class="hljs-attr">id</span>: user._id.toString(),
        <span class="hljs-attr">name</span>: user.username,
      },
    },
  });
};

<span class="hljs-comment">//login functionality</span>
<span class="hljs-built_in">exports</span>.login = catchAsync(<span class="hljs-keyword">async</span> (req, res, next) =&gt; {
 {…………………..}

<span class="hljs-comment">// Generate Stream token</span>
  <span class="hljs-keyword">await</span> streamClient.upsertUser({
    <span class="hljs-attr">id</span>: user._id.toString(),
    <span class="hljs-attr">name</span>: user.username,
  });
  <span class="hljs-keyword">const</span> streamToken = streamClient.createToken(user._id.toString());

user.password = <span class="hljs-literal">undefined</span>;

  res.status(<span class="hljs-number">200</span>).json({
    <span class="hljs-attr">status</span>: <span class="hljs-string">"success"</span>,
    <span class="hljs-attr">message</span>: <span class="hljs-string">"Login successful"</span>,
    token,
    <span class="hljs-attr">user</span>: {
      <span class="hljs-attr">id</span>: user._id.toString(),
      <span class="hljs-attr">name</span>: user.username,
    },
    streamToken,
  });
</code></pre>
<h3 id="heading-streamroutes-endpoint"><code>streamRoutes</code> <strong>Endpoint</strong></h3>
<p>Next, create an endpoint from which the Stream token can be called. To do this, go to your routes folder and create a new file called <code>streamRoutes.js</code>. In <code>streamRoutes.js</code>, add the command:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">"express"</span>);
<span class="hljs-keyword">const</span> { StreamChat } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"stream-chat"</span>);

<span class="hljs-keyword">const</span> protect = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../middlewares/protect"</span>);

<span class="hljs-keyword">const</span> router = express.Router();

<span class="hljs-keyword">const</span> apiKey = process.env.STREAM_API_KEY;
<span class="hljs-keyword">const</span> apiSecret = process.env.STREAM_API_SECRET;

<span class="hljs-keyword">if</span> (!apiKey || !apiSecret) {
  <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(
    <span class="hljs-string">"Missing Stream credentials. Check your environment variables."</span>
  );
}

<span class="hljs-keyword">const</span> streamClient = StreamChat.getInstance(apiKey, apiSecret);

router.get(<span class="hljs-string">"/get-token"</span>, protect, <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> { id, username } = req.user || {};
    <span class="hljs-built_in">console</span>.log(req.user.id, <span class="hljs-string">"User"</span>);
    <span class="hljs-comment">// TRY LOGGING THE ID AND NAME FROM YOUR REQUEST FIRST</span>

    <span class="hljs-keyword">if</span> (!id || !username) {
      <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"Invalid user data"</span> });
    }

    <span class="hljs-comment">// const userId = _id.toString();</span>
    <span class="hljs-keyword">const</span> user = { id, username };

    <span class="hljs-comment">// Ensure user exists in Stream backend</span>
    <span class="hljs-keyword">await</span> streamClient.upsertUser(user);

    <span class="hljs-comment">// Add user to my_general_chat channel</span>
    <span class="hljs-keyword">const</span> channel = streamClient.channel(<span class="hljs-string">"messaging"</span>, <span class="hljs-string">"my_general_chat"</span>);
    <span class="hljs-keyword">await</span> channel.addMembers([id]);


    <span class="hljs-comment">// Generate token</span>
    <span class="hljs-keyword">const</span> token = streamClient.createToken(id);
    res.status(<span class="hljs-number">200</span>).json({ token, user });
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Stream token generation error:"</span>, error);
    res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"Failed to generate Stream token"</span> });
  }
});

<span class="hljs-comment">/**
 * @route   POST /api/stream/token
 * @desc    Generate a Stream token for any userId from request body (no auth)
 * @access  Public
 */</span>
router.post(<span class="hljs-string">"/token"</span>, <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> { userId, name } = req.body;

    <span class="hljs-keyword">if</span> (!userId) {
      <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"userId is required"</span> });
    }

    <span class="hljs-keyword">const</span> userName = name || <span class="hljs-string">"Anonymous"</span>;
    <span class="hljs-keyword">const</span> user = { <span class="hljs-attr">id</span>: userId, <span class="hljs-attr">name</span>: userName };

    <span class="hljs-keyword">await</span> streamClient.upsertUser(user);

    <span class="hljs-comment">// Add user to my_general_chat channel</span>
    <span class="hljs-keyword">const</span> channel = streamClient.channel(<span class="hljs-string">"messaging"</span>, <span class="hljs-string">"my_general_chat"</span>);
    <span class="hljs-keyword">await</span> channel.addMembers([userId]);


    <span class="hljs-keyword">const</span> token = streamClient.createToken(userId);

    res.status(<span class="hljs-number">200</span>).json({
      token,
      <span class="hljs-attr">user</span>: {
        <span class="hljs-attr">id</span>: userId,
        <span class="hljs-attr">name</span>: name,
        <span class="hljs-attr">role</span>: <span class="hljs-string">"admin"</span>,
        <span class="hljs-attr">image</span>: <span class="hljs-string">`https://getstream.io/random_png/?name=<span class="hljs-subst">${name}</span>`</span>,
      },
    });
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Public token generation error:"</span>, error);
    res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"Failed to generate token"</span> });
  }
});

<span class="hljs-built_in">module</span>.exports = router;
</code></pre>
<h2 id="heading-user-logout-endpoint"><strong>User Logout Endpoint</strong></h2>
<p>Go to your <code>authController.js</code> and create a functionality that handles logging out the user:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">exports</span>.logout = catchAsync(<span class="hljs-keyword">async</span> (req, res, next) =&gt; {
  res.cookie(<span class="hljs-string">"token"</span>, <span class="hljs-string">"loggedout"</span>, {
    <span class="hljs-attr">expires</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-number">0</span>),
    <span class="hljs-attr">httpOnly</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">secure</span>: process.env.NODE_ENV === <span class="hljs-string">"production"</span>,
  });

  res.status(<span class="hljs-number">200</span>).json({
    <span class="hljs-attr">status</span>: <span class="hljs-string">"success"</span>,
    <span class="hljs-attr">message</span>: <span class="hljs-string">"Logged out successfully"</span>,
  });
});
</code></pre>
<p>Then register your logout route to your <code>userRouters.js</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">"express"</span>);
<span class="hljs-keyword">const</span> {logout}= <span class="hljs-built_in">require</span>(<span class="hljs-string">"../controller/authController"</span>);
<span class="hljs-keyword">const</span> isAuthenticated = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../middlewares/isAuthenticated"</span>);


router.post(<span class="hljs-string">"/logout"</span>, isAuthenticated, logout);

<span class="hljs-built_in">module</span>.exports = router;
</code></pre>
<h2 id="heading-chat-and-video-function-frontend">Chat and Video Function (Frontend)</h2>
<p>After setting up your backend Stream API, the last task is setting up chat and video in your frontend application.</p>
<h3 id="heading-dashboardjsx"><code>Dashboard.jsx</code></h3>
<p>Create a new file <code>Dashboard.jsx</code> in your frontend directory. This is where you will set up your Stream and video function.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;
<span class="hljs-keyword">import</span> {
  Chat,
  Channel,
  ChannelHeader,
  MessageInput,
  MessageList,
  Thread,
  Window,
  useCreateChatClient,
} <span class="hljs-keyword">from</span> <span class="hljs-string">"stream-chat-react"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"stream-chat-react/dist/css/v2/index.css"</span>;
<span class="hljs-keyword">import</span> { useStream } <span class="hljs-keyword">from</span> <span class="hljs-string">"../../components/StreamContext"</span>;
<span class="hljs-keyword">import</span> VideoStream <span class="hljs-keyword">from</span> <span class="hljs-string">"../../components/VideoStream"</span>;
<span class="hljs-keyword">import</span> { useNavigate } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-router-dom"</span>;



<span class="hljs-keyword">const</span> apiKey = <span class="hljs-keyword">import</span>.meta.env.VITE_STREAM_API_KEY;

<span class="hljs-keyword">const</span> API_URL = <span class="hljs-keyword">import</span>.meta.env.VITE_API_URL || <span class="hljs-string">'https://telehealth-backend-2m1f.onrender.com/api/v1'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [channel, setChannel] = useState(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [clientReady, setClientReady] = useState(<span class="hljs-literal">false</span>);
  <span class="hljs-keyword">const</span> navigate = useNavigate();

  <span class="hljs-comment">// const ChatComponent = () =&gt; {</span>
    <span class="hljs-keyword">const</span> { user, token, Logout } = useStream();

    <span class="hljs-comment">// Always call the hook</span>
    <span class="hljs-keyword">const</span> chatClient = useCreateChatClient({
      apiKey,
      <span class="hljs-attr">tokenOrProvider</span>: token,
      <span class="hljs-attr">userData</span>: user?.id ? { <span class="hljs-attr">id</span>: user.id } : <span class="hljs-literal">undefined</span>,
    });

  <span class="hljs-comment">// Debug: See when user/token is ready</span>
  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Stream user:"</span>, user);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Stream token:"</span>, token);
  }, [user, token]);

    <span class="hljs-comment">// Connect user to Stream</span>
    useEffect(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-keyword">const</span> connectUser = <span class="hljs-keyword">async</span> () =&gt; {
        <span class="hljs-keyword">if</span> (!chatClient || !user || !token || !user?.id) {
          <span class="hljs-built_in">console</span>.warn(<span class="hljs-string">"Missing chat setup data:"</span>, { chatClient, token, user });
          <span class="hljs-keyword">return</span>;
        }


        <span class="hljs-keyword">try</span> {
          <span class="hljs-keyword">await</span> chatClient.connectUser(
            {
              <span class="hljs-attr">id</span>: user.id,
              <span class="hljs-attr">name</span>: user.name || <span class="hljs-string">"Anonymous"</span>,
              <span class="hljs-attr">image</span>:
                user.image ||
                <span class="hljs-string">`https://getstream.io/random_png/?name=<span class="hljs-subst">${user.name || <span class="hljs-string">"user"</span>}</span>`</span>,
            },
            token
          );

          <span class="hljs-keyword">const</span> newChannel = chatClient.channel(<span class="hljs-string">"messaging"</span>, <span class="hljs-string">"my_general_chat"</span>, {
            <span class="hljs-attr">name</span>: <span class="hljs-string">"General Chat"</span>,
            <span class="hljs-attr">members</span>: [user.id],
          });

          <span class="hljs-keyword">await</span> newChannel.watch();
          setChannel(newChannel);
          setClientReady(<span class="hljs-literal">true</span>);
        } <span class="hljs-keyword">catch</span> (err) {
          <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error connecting user:"</span>, err);
        }
      };

      connectUser();
    }, [chatClient, user, token]);

    <span class="hljs-keyword">const</span> handleVideoCallClick = <span class="hljs-function">() =&gt;</span> {
      navigate(<span class="hljs-string">"/videoCall"</span>);
  };

  <span class="hljs-keyword">const</span> handleLogout = <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">await</span> Logout();
    navigate(<span class="hljs-string">"/login"</span>);
  }

  <span class="hljs-keyword">if</span> (!user || !token) {
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-red-600"</span>&gt;</span>User or token not ready.<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
  }

  <span class="hljs-keyword">if</span> (!clientReady || !channel) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Loading chat...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;


  <span class="hljs-keyword">return</span> (
{ checkout the github repo}
            &lt;ChannelHeader /&gt;
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">MessageList</span> /&gt;</span></span>
            <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">MessageInput</span> /&gt;</span></span>
          &lt;/Window&gt;
          <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Thread</span> /&gt;</span></span>
        &lt;/Channel&gt;
      &lt;/Chat&gt;


      &lt;/div&gt;

    );
  }

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<h3 id="heading-video-setup"><strong>Video Setup</strong></h3>
<p>You’ll now set up the video function for your frontend. To do so, create a new file <code>VideoStream.jsx</code> and add the command:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { StreamVideoClient } <span class="hljs-keyword">from</span> <span class="hljs-string">"@stream-io/video-client"</span>;
<span class="hljs-keyword">import</span> { StreamVideo, StreamCall } <span class="hljs-keyword">from</span> <span class="hljs-string">"@stream-io/video-react-sdk"</span>;
<span class="hljs-keyword">import</span> { useNavigate } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-router-dom"</span>;


<span class="hljs-keyword">import</span> { useStream } <span class="hljs-keyword">from</span> <span class="hljs-string">"./StreamContext"</span>;
<span class="hljs-keyword">import</span> { MyUILayout } <span class="hljs-keyword">from</span> <span class="hljs-string">"./MyUILayout"</span>;


<span class="hljs-keyword">const</span> apiKey = <span class="hljs-keyword">import</span>.meta.env.VITE_STREAM_API_KEY;

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

  <span class="hljs-keyword">const</span> [client, setClient] = useState(<span class="hljs-literal">null</span>);
    <span class="hljs-keyword">const</span> [call, setCall] = useState(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> { user, token } = useStream();
  <span class="hljs-keyword">const</span> navigate = useNavigate();

  useEffect(<span class="hljs-function">() =&gt;</span> {

    <span class="hljs-keyword">let</span> clientInstance;
    <span class="hljs-keyword">let</span> callInstance;


    <span class="hljs-keyword">const</span> setup = <span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">if</span> (!apiKey || !user || !token) <span class="hljs-keyword">return</span>;

      clientInstance = <span class="hljs-keyword">new</span> StreamVideoClient({ apiKey, user, token });

      callInstance = clientInstance.call(<span class="hljs-string">"default"</span>, user.id); <span class="hljs-comment">// Use user.id as callId</span>


      <span class="hljs-keyword">await</span> callInstance.join({ <span class="hljs-attr">create</span>: <span class="hljs-literal">true</span> });

      setClient(clientInstance);
      setCall(callInstance);
    };

    setup();

    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-keyword">if</span> (callInstance) callInstance.leave();
      <span class="hljs-keyword">if</span> (clientInstance) clientInstance.disconnectUser();

    };
  }, [user, token]);

  <span class="hljs-keyword">const</span> handleLeaveCall = <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">if</span> (call) <span class="hljs-keyword">await</span> call.leave();
    <span class="hljs-keyword">if</span> (client) <span class="hljs-keyword">await</span> client.disconnectUser();

    setCall(<span class="hljs-literal">null</span>);
    setClient(<span class="hljs-literal">null</span>);

    navigate(<span class="hljs-string">"/dashboard"</span>); <span class="hljs-comment">// or any other route</span>
  };

  <span class="hljs-keyword">if</span> (!apiKey) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Missing Stream API Key<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;

  <span class="hljs-keyword">if</span> (!client || !call)
    <span class="hljs-keyword">return</span> (
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex items-center justify-center h-screen text-xl font-semibold"</span>&gt;</span>
    Connecting to the video call...
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"relative h-screen w-full p-2 sm:p-4 bg-gray-50"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">StreamVideo</span> <span class="hljs-attr">client</span>=<span class="hljs-string">{client}</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">StreamCall</span> <span class="hljs-attr">call</span>=<span class="hljs-string">{call}</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">MyUILayout</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">StreamCall</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">StreamVideo</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">button</span>
        <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleLeaveCall}</span>
        <span class="hljs-attr">className</span>=<span class="hljs-string">"absolute top-2 right-2 sm:top-4 sm:right-4 bg-red-600 text-white text-sm sm:text-base px-3 sm:px-4 py-1.5 sm:py-2 rounded-lg shadow hover:bg-red-700 transition"</span>
      &gt;</span>
        Leave Call
      <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );
  }

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> VideoStream;
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-comment">//MYUILayout.jsx</span>
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> {
  useCall,
  useCallStateHooks,
  CallingState,
} <span class="hljs-keyword">from</span> <span class="hljs-string">'@stream-io/video-react-sdk'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyUILayout</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> call = useCall();
  <span class="hljs-keyword">const</span> { useCallCallingState, useParticipantCount } = useCallStateHooks();
  <span class="hljs-keyword">const</span> callingState = useCallCallingState();
  <span class="hljs-keyword">const</span> participantCount = useParticipantCount();

  <span class="hljs-keyword">if</span> (callingState !== CallingState.JOINED) {
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Joining call...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">padding:</span> '<span class="hljs-attr">1rem</span>', <span class="hljs-attr">fontSize:</span> '<span class="hljs-attr">1.2rem</span>' }}&gt;</span>
      ✅ Call "<span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>{call?.id}<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span>" has <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>{participantCount}<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span> participants.
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<h2 id="heading-project-demo">Project Demo</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752705861841/85b6d6b3-0f5e-402f-b8b5-8ab51d820403.gif" alt="Telehealth Final Project Demo" class="image--center mx-auto" width="1398" height="630" loading="lazy"></p>
<p>Congratulations! You have successfully integrated Stream’s chat and video function into your application.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>And that’s a wrap! </p>
<p>You’ve <a target="_blank" href="https://getstream.io/blog/telemedicine-app-development/">built a telehealth app</a> with secure video, real-time chat, and user authentication – all powered by Stream’s Chat and Video SDKs. </p>
<p>This foundation gives you the flexibility to expand further with features like appointment scheduling, patient history, or HIPPA-compliant file sharing. </p>
<p>You can find the <a target="_blank" href="https://github.com/Derekvibe/Telehealth_Backend">frontend</a> and <a target="_blank" href="https://github.com/Derekvibe/Telehealth_Frontend">backend</a> applications on GitHub. The frontend app is hosted using the Vercel hosting service, and the backend is hosted on Render.</p>
<p>Check out the <a target="_blank" href="https://telehealth-frontend.vercel.app/">repository of the application</a>.</p>
<p>Happy coding! 🚀</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Write Good API Documentation ]]>
                </title>
                <description>
                    <![CDATA[ Imagine purchasing a standing fan straight out of the box, all parts dismantled, and you have no manual or guide to put them together. Did you imagine that just now? Cool. Here is another scenario: imagine purchasing an LG product, such as a smart TV... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-write-good-api-docs/</link>
                <guid isPermaLink="false">68151f0be5850fcb8543375a</guid>
                
                    <category>
                        <![CDATA[ APIs ]]>
                    </category>
                
                    <category>
                        <![CDATA[ api documentation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ documentation ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Okoro Emmanuel Nzube ]]>
                </dc:creator>
                <pubDate>Fri, 02 May 2025 19:37:47 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746108055356/29f327c1-60a5-4d0c-baef-431c0e61c1b4.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Imagine purchasing a standing fan straight out of the box, all parts dismantled, and you have no manual or guide to put them together. Did you imagine that just now? Cool.</p>
<p>Here is another scenario: imagine purchasing an LG product, such as a smart TV without a guide on how to set it up and use the remote. Now you get the point.</p>
<p>The process of you trying to mount your fan or set up your smart TV will be a very frustrating and confusing one without any guidance. And most of the time, it’ll be hard to determine the full potential of the product you bought.</p>
<p>Now, keeping in mind the already painted scenarios, have you ever tried picking up a new programming language or using an unfamiliar API, only to find it confusing, and you felt completely overwhelmed at the beginning? Then you probably spent hours trying to piece things together, maybe via tutorials, but nothing seems to work perfectly due to the error messages you get…and you wonder if you’re doing the right thing.</p>
<p>But then you might have come across the product’s official documentation or maybe a properly written and well-structured guide (like this one you’re reading). Suddenly, everything clicks, you start writing code effortlessly or using the API with confidence. That’s it – the power of clear and concise documentation.</p>
<p>In this article, you will learn what an API is, how it works, what API documentation is all about, and how to create standard API documentation.</p>
<p>Let’s dive in.</p>
<h2 id="heading-outline">Outline</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-what-is-an-api">What is an API</a>?</p>
<ul>
<li><p><a class="post-section-overview" href="#heading-how-apis-work">How APIs Work</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-types-of-apis">Types of APIs</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-api-documentation">What is API Documentation</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-examples-of-api-documentation">Examples of API Documentation</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-benefits-of-clear-api-documentation">Benefits of Clear API Documentation</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-importance-of-a-clear-api-documentation">Importance of a Clear API Documentation</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-key-notes-of-api-documentation">Key Notes of API Documentation</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-key-component-of-an-api-documentation">Key Component of an API Documentation</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-best-practices-for-writing-concise-api-documentation">Best Practices for Writing Concise API Documentation</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<p>Before we continue, let’s deviate a bit to learn what APIs are all about, how they work, and the types of APIs that are out there.</p>
<h2 id="heading-what-is-an-api"><strong>What is an API?</strong></h2>
<p>You might have heard the term API before, and you’re wondering what it’s all about. API stands for Application Programming Interface. An API acts as an interface between two programs that allows them to communicate. It is a mediator between the client (browsers/mobile application) and the server (backend).</p>
<h3 id="heading-how-apis-work"><strong>How APIs Work</strong></h3>
<p>So now you know that an API acts as a bridge or middleman that allows two systems to communicate with each other. When working with APIs, you’ll come across two key terms: <strong>requests</strong> and <strong>responses.</strong> These two keywords are essential to understand because they form the core of how APIs work.</p>
<p>Think of requests and responses like what you use in a regular day-to-day conversation. It’s just like how you ask questions (request) and an answer is provided (response). Same thing happens with APIs, but in this case, its an interaction between software systems.</p>
<p>To explain better how an API works, let’s use a weather app or a stock market app. This should provide a clear view of what we are talking about.</p>
<p>When you open a weather app and want to check the current weather, the app doesn’t store the weather data itself. Instead, it sends a request through an API to the weather database server. When the request is sent, the API now interacts/communicates with the database server and retrieves the latest weather information, which is then sent back to the weather app as a response. Then this info is finally displayed to you.</p>
<p>This should be a smooth, fast, and continuous process and has to occur simultaneously for your app to run smoothly. This means that a request must be made first before a response can be received. You can’t get a response without making a request.</p>
<p>The same process occurs for the stock market app as well.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745908659843/7aaad1e5-a18d-43fc-a74c-a416b9e19ce2.png" alt="Image of How an API works" class="image--center mx-auto" width="3096" height="1548" loading="lazy"></p>
<h3 id="heading-types-of-apis"><strong>Types of APIs</strong></h3>
<p>APIs are categorised into two major types:</p>
<ul>
<li><p>By Use/Function</p>
</li>
<li><p>By Access</p>
</li>
</ul>
<h4 id="heading-types-of-apis-by-use"><strong>Types of APIs by Use</strong></h4>
<ul>
<li><p><strong>Web APIs</strong>: These are the most commonly used type of APIs and are also known as HTTP (Hypertext Transfer Protocol) APIs. This API enables communication over the internet with the use of HTTP. Examples of these APIs are REST APIs, GraphQL APIs, and so on.</p>
</li>
<li><p><strong>Library or Framework APIs</strong>: These are APIs provided by libraries or frameworks and are made use of by developers to build applications without having to build everything from scratch. Examples of this are React, JQuery, and so on.</p>
</li>
<li><p><strong>Operating System APIs</strong>: These are APIs built to allow systems/applications to communicate with operating systems. These APIs helps provide access to system-level resources, which is important for the application to function properly. Examples of these APIs are Android SDK, Windows API, and so on.</p>
</li>
<li><p><strong>Hardware APIs</strong>: These are APIs built to enable systems to communicate with the physical components of a hardware device. Examples of these APIs are Bluetooth APIs, Camera APIs, and so on.</p>
</li>
<li><p><strong>Database APIs</strong>: Just as the name states, they are APIs that allow applications to interact with the database. These APIs are essential and mostly used to store, retrieve, manage and update the database. Examples of these APIs are SQL-based APIs, NoSQL APIs, and so on.</p>
</li>
</ul>
<h4 id="heading-types-of-apis-by-access"><strong>Types of APIs by Access</strong></h4>
<ul>
<li><p>Open APIs: This can be seen as a public API and is also referred to as an external APIs. These are the types of APIs built and made available for anyone to use, therefore making them need little to no authorization and authentication. Based on the number of calls made to these APIs, some of them APIs are available for free while others are available at a specific cost (paid subscription).</p>
</li>
<li><p>Partner APIs: These are types of APIs built and made available for just businesses that collaborate together. When this type of APIs are built, strong authentication and authorization process are put into consideration so as to avoid it from being accessed by the public.</p>
</li>
<li><p>Internal APIs: The internal APIs can also be referred to as private APIs. These APIs are built and internally used by organization and are restricted from the public. These APIs are mostly used when there is communication between systems or Applications within the organization.</p>
</li>
<li><p>Composite APIs: This is a type of API built in a way that it combines multiple API requests into a bundle and allows users to get one single response from different servers. This type of APIs is most commonly used when Devs needs to fetch data from multiple servers or data sources.</p>
</li>
</ul>
<p>Now that we have broken down what APIs are, how they work, and their various types, let's move on to the main reason we’re here: learning about creating good API documentation.</p>
<h2 id="heading-what-is-api-documentation"><strong>What is API Documentation?</strong></h2>
<p>API documentation is also referred to as developer documentation. It is a well-written and organized guide or manual that explains how an API works. It’s designed to help developers (or even non-developers) understand what the API does, how to use it, and how to integrate it into their own projects.</p>
<p>By using API documentations, you can explore and take full advantage of everything an API has to offer. API documentation also aims at speeding up the development process and boosting the overall productivity of a product.</p>
<p>API documentation provides a detailed explanation of the complete functionality of the API, which can include:</p>
<ul>
<li><p>The most efficient way to use the API</p>
</li>
<li><p>How to integrate the API with your project.</p>
</li>
<li><p>The purpose of the API and the inputs to be passed for developers to make good use of it.</p>
</li>
</ul>
<h2 id="heading-examples-of-api-documentation"><strong>Examples of API Documentation</strong></h2>
<p>Here are some examples of API documentation to give you a better idea of what’s involved and what information these docs should provide.</p>
<h3 id="heading-stripe-api-docs"><strong>Stripe API Docs</strong></h3>
<p>This is an example of a Web/HTTP API. Stripe is a payment processing tool, and the <a target="_blank" href="https://docs.stripe.com/api">Stripe API documentation</a> provides a clean, interactive, and developer-friendly guide on how to make use of the API for payment integrations.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745908370335/eb50afc2-30b8-41ba-8c53-fd47b0f643a4.png" alt="Stripe API documentation Image" class="image--center mx-auto" width="1860" height="895" loading="lazy"></p>
<h3 id="heading-react-docs"><strong>React Docs</strong></h3>
<p>The <a target="_blank" href="https://react.dev/learn">React docs</a> are an example of a library or framework API. They provide a detailed guide to how you can use React in building your web project</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745908586648/b366b340-004b-4b88-8d6e-ab8eab8b04c1.png" alt="React API documentation image" class="image--center mx-auto" width="1899" height="873" loading="lazy"></p>
<h3 id="heading-android-sdk"><strong>Android SDK</strong></h3>
<p>This is an example of an Operating System API. The <a target="_blank" href="https://developer.android.com/reference">Android SDK Documentation</a> provides a detailed guide on how you can make use of the Android SDK API to build your Android app.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745908800051/c0707d78-6d29-4bf8-ace4-fa07d38e58bd.png" alt="Andriod SDK API documentation" class="image--center mx-auto" width="1891" height="924" loading="lazy"></p>
<h3 id="heading-web-bluetooth-api"><strong>Web Bluetooth API</strong></h3>
<p>This is an example of a hardware API. The <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API">Web Bluetooth API Docs</a> provide a detailed guide on how to make use of the API to connect and interact with Bluetooth low energy peripherals.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745909018248/70c028d5-5c70-4441-949d-a89b2ba9a183.png" alt="Web Bluetooth API Documentation" class="image--center mx-auto" width="1824" height="863" loading="lazy"></p>
<h3 id="heading-postgresql-api">PostgreSQL API</h3>
<p>This is an example of a Database API. The <a target="_blank" href="https://www.postgresql.org/docs/current/libpq-connect.html">PostgreSQL API Docs</a> provide developers with full details on what the API is all about, how they can effortlessly connect it with their application, and also the roadblocks they can encounter while using the API and how to overcome them.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745909167138/3004c153-8a7a-4814-b824-31fca6d11433.png" alt="PostgreSQL API documentation" class="image--center mx-auto" width="1853" height="921" loading="lazy"></p>
<h2 id="heading-benefits-of-clear-api-documentation"><strong>Benefits of Clear API Documentation</strong></h2>
<h3 id="heading-enhances-the-developer-experience"><strong>Enhances the Developer Experience</strong></h3>
<p>Great API documentation makes a developer’s life much easier. It clearly explains what the API does, how it works, and how to use it – all of which help developers get up to speed quickly.</p>
<p>Instead of wasting time figuring things out or getting stuck, they can focus on building. It reduces frustration, boosts productivity, and even makes it easier to collaborate with teammates.</p>
<h3 id="heading-reduces-the-learning-curve"><strong>Reduces the Learning Curve</strong></h3>
<p>Good API documentation helps reduce the learning curve for developers trying to use the API. This, in turn, leads to faster onboarding, saves time and money, and encourages higher adoption rates.</p>
<h3 id="heading-easy-to-maintain"><strong>Easy to Maintain</strong></h3>
<p>Good API documentation makes it easier to maintain both the API and any application the API is used in. Up-to-date docs help developers understand changes, fix bugs, and update features in their application with confidence.</p>
<h3 id="heading-provides-visibility-for-your-product"><strong>Provides Visibility for Your Product</strong></h3>
<p>Good API documentation increases the visibility of your product and encourages frequent use by making it easier for developers to understand and integrate it. It also promotes third-party integration, helping your product reach a wider audience.</p>
<h2 id="heading-key-components-of-api-documentation"><strong>Key Components of API Documentation</strong></h2>
<p>There are many components that make up a good API documentation. In this section, we will walk through a real-world example of properly prepared API documentation: the Spotify Web API.</p>
<h3 id="heading-overviewdescription-and-uses-of-the-api"><strong>Overview/Description and Uses of the API</strong></h3>
<p>This is the very first stage in writing good API documentation. This section explains to users what the API is all about and also has information about the type of resources it provides.</p>
<p>The overview section is usually short, perhaps 3-4 sentences, and it describes what the API is does, the available resources, its endpoints, and the methods attached to each endpoint. This helps bring you up to speed as to whether that particular API provides what you need to complete your project.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745909576601/ad916148-11df-4c8f-985e-8f9714173e04.png" alt="Overview Example of an API Doc's description section" class="image--center mx-auto" width="1457" height="835" loading="lazy"></p>
<p>As you can see, the Spotify API’s description explains how it helps you create applications that “can interact with Spotify’s streaming service, such as retrieving content metadata, creating and managing playlists, or controlling playback.”</p>
<h3 id="heading-endpoints"><strong>Endpoints</strong></h3>
<p>Endpoints are an important component in API documentation. Developers use them to communicate with other servers. They’re also used for data transfers. An Endpoint is referred to as the “touch point” in the communication channel between two servers.</p>
<p>When documenting an endpoint, it’s important to take note of the various components of the endpoints, as this increases the quality of your API documentation. The components of an endpoint include its <code>name</code>, <code>description</code>, <code>url</code>, <code>methods</code>, <code>parameters</code>, and so on.</p>
<p>For example, if you want to get the details of a user’s top artist, here’s how the endpoint looks:</p>
<pre><code class="lang-javascript">GET https:<span class="hljs-comment">//api.spotify.com/v1/me/top/artists</span>
</code></pre>
<p>Remember, we previously mentioned the key components that make up an API endpoint, such as the name, description, URL, and HTTP method. Let's take the Spotify endpoint URL above to see how these components are presented:</p>
<ul>
<li><p><strong>Name:</strong> Get User's Top Artists</p>
</li>
<li><p><strong>Description:</strong> Retrieves the current user's most listened-to artists.</p>
</li>
<li><p><strong>URL:</strong> <a target="_blank" href="https://api.spotify.com/v1/me/top/artists"><code>https://api.spotify.com/v1/me/top/artists</code></a></p>
</li>
<li><p><strong>Method:</strong> <code>GET</code></p>
</li>
</ul>
<p>This endpoint demonstrates how a well-documented API provides all the necessary details a developer needs to understand and use it effectively.</p>
<p>Response:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"rank"</span>: <span class="hljs-number">1</span>,
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Eminem"</span>,
 },

{
  <span class="hljs-attr">"rank"</span>: <span class="hljs-number">2</span>,
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"NF"</span>,
 },

{
  <span class="hljs-attr">"rank"</span>: <span class="hljs-number">3</span>,
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Adele"</span>,
 },
</code></pre>
<p>Now the code above indicates the response I should get from my initial request and it is displayed in a JSON format.</p>
<h3 id="heading-authorization-and-authentication"><strong>Authorization and Authentication:</strong></h3>
<p>Both authorization and authentication are important tools used for checking the access that’s been given to sensitive data.</p>
<p>APIs receive thousands of responses and handle huge amounts of data. Authentication and Authorization are ways to ensure that your API data and your users are safe and secure from hackers.</p>
<p>Note that authentication and authorization are two different concepts. Authentication is mainly all about verifying the identity of someone who wants to use your API. Authorization, on the other hand, describes the level of access that an already verified user has when interacting with the API.</p>
<p>There are three major types of API Authentication. Each type is used at different stages or levels, but in some scenarios, no authentication is used at all.</p>
<ul>
<li><p><strong>Basic Authentication:</strong> This is the type of API auth that is usually used for testing internal APIs. It’s not recommended for publicly used APIs because it’s not fully secure. This API sends a username and password with every API call made to the client.</p>
</li>
<li><p><strong>Key Authentication:</strong> In this type of auth, the client generates and sends a very long key. The API key is a long string that contains unique authorization tokens. This type of auth is more secure than the basic auth – but if the key is leaked, anyone can access the API until it’s revoked. Note: This type of Authentication is used for light applications.</p>
</li>
<li><p><strong>OAuth Authentication:</strong> OAuth is the most common and more secure token-based type of authentication. In this type of authentication, instead of sending a username and password, an authorization is first requested, which is approved by the user. After the user approves the request, a token is generated which can be used to make an API request. This method is secure, and the tokens generated have an expiration time as well.</p>
</li>
</ul>
<p>Let’s look at an example from the Spotify API.</p>
<p>Spotify uses <strong>OAuth 2.0</strong> for authentication and access control. To use most of Spotify’s Web API endpoints, you must first authenticate your application and obtain permission from the user:</p>
<pre><code class="lang-javascript">GET https:<span class="hljs-comment">//accounts.spotify.com/authorize</span>
</code></pre>
<p>Here are the key details of the Authorization endpoint:</p>
<ul>
<li><p><strong>Name:</strong> Authorization</p>
</li>
<li><p><strong>Description:</strong> Initiates the OAuth 2.0 flow to authorize users and allow your application to access Spotify data on their behalf.</p>
</li>
<li><p><strong>URL:</strong> <a target="_blank" href="https://accounts.spotify.com/authorize"><code>https://accounts.spotify.com/authorize</code></a></p>
</li>
<li><p><strong>Method:</strong> <code>GET</code></p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745909858569/5785d44b-642b-400c-b3b5-c12508faac43.png" alt="Sportify Authentication and Authorization Image" class="image--center mx-auto" width="1870" height="915" loading="lazy"></p>
<h3 id="heading-parameters-and-headers"><strong>Parameters and Headers:</strong></h3>
<p>Parameters are the variable part of a resource and comprise a name, value, and description. Some parameters are required and are used in making API calls, while some are just optional.</p>
<p>When writing an API documentation, you should list out all the parameters and descriptions alongside each parameter. It’s also a good idea to specify why such a parameter is needed and state if it is required or optional in the documentation.</p>
<p>Headers, on the other hand, are similar to parameters. They have key-value pairs and are used to send additional information (metadata) about a request to the server. If there are any headers used in your API, then it is important you include them when documenting the API.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746181055214/dbf02273-71ef-472e-94d1-7b49c78f9751.png" alt="Parameters and headers" class="image--center mx-auto" width="1428" height="615" loading="lazy"></p>
<p>As you can see in the image above, we have some Body Parameters and Header Parameters. For body parameters, there’s <code>grant_type</code> (which is required), <code>code</code> (also required), and <code>redirect_uri</code> (also required). You can also see that they have descriptions of the value listed.</p>
<p>For header parameters, we have <code>Authorization</code> (required) and <code>Content-Type</code> (also required), again with descriptions of their values.</p>
<h3 id="heading-error-handling-codes-and-troubleshooting-guidance"><strong>Error Handling Codes and Troubleshooting Guidance:</strong></h3>
<p>Errors are inevitable, they’ll always occur despite how careful you are. That’s why good API documentation should include guidance to help developers recover quickly when things go wrong.</p>
<p>Your documentation should provide a section that;</p>
<ul>
<li><p>Suggest possible fixes or troubleshooting tips for some specific errors.</p>
</li>
<li><p>Include sample error response codes and logs, which help in debugging.</p>
</li>
</ul>
<p>When it comes to API calls, two key components to understand are the <strong>request</strong> and the <strong>response</strong>. When an API call is made, a request is sent to the server, and a response is returned. This response includes a <strong>status code</strong> and, if applicable, an <strong>error code</strong> and both are essential for understanding what happened during the request.</p>
<p>For example, there are situations when you make an API call and the response you get is a code 404, which means that the request you made was not found. But when things go smoothly, you should see a code 200, which means your request was successful.</p>
<p>Here is what this section looks like:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"error"</span>: {
    <span class="hljs-attr">"status"</span>: <span class="hljs-number">404</span>,
    <span class="hljs-attr">"message"</span>: <span class="hljs-string">"Not Found"</span>
  }
}
</code></pre>
<p>By properly documenting these status and error codes with their explanations, developers can easily identify issues and take appropriate actions to solving it those issues.</p>
<p>Here are some common Response Code Statuses and what they mean:</p>
<h4 id="heading-response-code-status">Response Code Status:</h4>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Status Code</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td>200</td><td>OK</td></tr>
<tr>
<td>201</td><td>Created</td></tr>
<tr>
<td>202</td><td>Accepted</td></tr>
<tr>
<td>400</td><td>Bad Request</td></tr>
<tr>
<td>401</td><td>Unauthorized</td></tr>
<tr>
<td>403</td><td>Forbidden</td></tr>
<tr>
<td>404</td><td>Not Found</td></tr>
<tr>
<td>500</td><td>Internal Server Error</td></tr>
<tr>
<td>502</td><td>Bad Gateway</td></tr>
<tr>
<td>503</td><td>Service Unavailable</td></tr>
</tbody>
</table>
</div><p>The table above shows some of the most common code response statuses you’ll come across when using an API and its description.</p>
<h2 id="heading-best-practices-for-writing-concise-api-documentation"><strong>Best Practices for Writing Concise API Documentation</strong></h2>
<p>Here are some best practices that can help guide you while writing API documentation:</p>
<ol>
<li><p>You want to make sure users clearly understand what the API is, how they can use it, and the limits of use for the API.</p>
</li>
<li><p>Know your target audience and focus on what they need most to get started with the API docs.</p>
</li>
<li><p>Always stick to the essential information and use clear and consistent language.</p>
</li>
<li><p>Structure your documentation properly and make it standard.</p>
</li>
<li><p>Examples are important. Always use them in your documentation and make sure you clearly explain them.</p>
</li>
<li><p>Avoid repetition in your documentation.</p>
</li>
<li><p>Always document your error codes clearly. It’s recommended that you put them in tabular format.</p>
</li>
<li><p>Always provide a link to outsourced files in situations when more details are needed. This helps keep your documentation short and on point.</p>
</li>
<li><p>Review and regularly update the documentation.</p>
</li>
<li><p>Incorporate user feedback for continuous improvement.</p>
</li>
</ol>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>API documentation has become a critical component in today's technology landscape. Clear and concise documentation is not just helpful – it’s essential. It often determines whether an API succeeds in the tech ecosystem and whether developers can fully leverage its power.</p>
<p>This is a call to action for developers, organizations, and technical writers: prioritize high-quality, well-structured API documentation. The clarity of your documentation directly impacts the usability, adoption, and long-term success of your product in the industry.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create a Send Email Function using Nodemailer and OAuth2 ]]>
                </title>
                <description>
                    <![CDATA[ Being able to communicate by sending emails through web applications is important these days. It helps businesses stay connected with their potential customers. In this article, you’ll learn how to implement the Send Email function in your web app us... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/create-a-send-email-function-using-nodemailer-and-oauth2/</link>
                <guid isPermaLink="false">67e1ec8917e7e6a0f12cddf5</guid>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ nodemailer ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Chakra-ui ]]>
                    </category>
                
                    <category>
                        <![CDATA[ OAuth2 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Okoro Emmanuel Nzube ]]>
                </dc:creator>
                <pubDate>Mon, 24 Mar 2025 23:36:41 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1742859346889/dad1b775-f088-4c24-b252-3d85ec9e0bb7.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Being able to communicate by sending emails through web applications is important these days. It helps businesses stay connected with their potential customers.</p>
<p>In this article, you’ll learn how to implement the Send Email function in your web app using Nodemailer.</p>
<p>Let’s dive right in.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-tools-we%E2%80%99ll-be-using">Tools We’ll Be Using</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-frontend-setup">Frontend Setup</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-install-node.js">Install Node.js</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-contact-form-setup">Contact Form Setup</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-backend-setup">Backend Setup</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-backend-libraries-setup">Backend Libraries Setup</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-oauth2-configuration-setup">OAuth2 Configuration Setup</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-nodemailer-setup">Nodemailer Setup</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<p>To get the absolute most out of this project, it’s important to have some basic knowledge of the following:</p>
<ul>
<li><p>JavaScript: Having a good fundamental understanding of how JS works will make it easier to follow along with the project.</p>
</li>
<li><p>React.js and Chakra UI: You should have a good understanding of how <code>usestate</code> works and how you can apply it in a project. It’s also important that you’re familiar with Chakra Ui and know how to use it to style your web application.</p>
</li>
<li><p>A little background on <a target="_blank" href="https://www.nodemailer.com/about/">Nodemailer</a> would be helpful as well.</p>
</li>
</ul>
<h2 id="heading-tools-well-be-using"><strong>Tools We’ll Be Using</strong></h2>
<p>In one of my recent projects, I created a mailer function in Node.js using Nodemailer. This function ensured that users’ emails would be delivered efficiently. And now that I know how it works, I wanted to share it with you all.</p>
<h3 id="heading-nodemailer-and-smtp">Nodemailer and SMTP</h3>
<p>So what is Nodemailer?</p>
<p>Nodemailer is a popular Node.js module that lets you send emails efficiently using different methods such as SMTP (Simple Mail Transfer Protocol), OAuth2, and so on.</p>
<p>SMTP acts like a postal service – or rather, it’s a postal service that sorts your emails and routes your messages on different mail servers until they reach their final destination. This helps ensure that your messages reach the right inbox all the time.</p>
<p>But it’s important to note that SMTP only handles the <strong>sending of emails,</strong> meaning that it doesn’t handle retrieval of already sent emails. But protocols like IMAP (Internet Message Access Protocol) and POP3 (Post Office Protocol version 3) let you retrieve emails. We won’t be using these tools here, but I just wanted you to be aware of them in case you want to implement retrieval functionality in your own projects.</p>
<h3 id="heading-oauth2">OAuth2</h3>
<p>OAuth2, short for Open Authorization, simplifies the process of authentication and authorization. With OAuth2, users don’t have to go through the hassle of repeatedly signing in or logging in. Instead, web applications can securely access private user data from other websites—only with the user's permission.</p>
<p>But don’t worry, OAuth2 only grants requesting applications limited access, typically just enough to create a basic profile. Chances are, you’ve already used OAuth2 without even realizing what’s happening behind the scenes. Pretty cool, right?</p>
<p>Now that you know a bit more about the tools we’ll be using, let’s move on.</p>
<h2 id="heading-frontend-setup">Frontend Setup</h2>
<p>First things first, you have to set up your environment. When setting up my environment, I used React.js and Chakra UI (for my styling).</p>
<h3 id="heading-install-nodejs">Install Node.js</h3>
<p>Before starting this process, make that Node is installed on your computer. If it’s not, head to their <a target="_blank" href="https://nodejs.org/en">website</a> to download and install it from there.</p>
<p>You can also use your command line to install Node by running the command <code>nvm install –lts</code>.</p>
<p>Or you could use the newest method recommended on the Node.js website, which is simply to run <code>fnm</code>.</p>
<p>Here is how you can go about it: on your command line, run the following commands:</p>
<pre><code class="lang-javascript">winget install Schniz.fnm <span class="hljs-comment">// this command downloads and installs fnm into your operating system.</span>

fnm install <span class="hljs-number">22</span> <span class="hljs-comment">// this downloads and installs node.js.</span>

node -v <span class="hljs-comment">// this displays the version of node.js currently installed in your operating system.</span>

npm – v <span class="hljs-comment">// this verifies the version of npm currently installed.</span>
</code></pre>
<p>Next, let’s set up your frontend interface.</p>
<h3 id="heading-contact-form-setup">Contact Form Setup</h3>
<p>As I mentioned above, I’m using React for my front-end and Chakra UI for styling. I won’t be going over how to install React here, but if you need help with that for your project, <a target="_blank" href="https://www.freecodecamp.org/news/how-to-install-react-a-step-by-step-guide">check out my article on it</a>.</p>
<p>Next, make sure you have Chakra UI set up. You can do this by following the steps on the <a target="_blank" href="https://chakra-ui.com/docs/get-started/frameworks/vite">Chakra Ui official website</a>.</p>
<p>Note: The web application is a full web application, which consists of various pages like Home, Services, Pricing, Contact, and so on. But for the sake of this article, we’ll focus on only the contact page.</p>
<p>Here is what the contact page will look like:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742477133862/421baf80-c55a-443a-9e68-c2b2e2a9b1a2.png" alt="Frontend Design interface of the Contact Form" class="image--center mx-auto" width="1603" height="831" loading="lazy"></p>
<p>The first step in building this contact form is to create your form input. Here is how you can do that:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { Box, Button, Flex, Image, Input, Text, Textarea } <span class="hljs-keyword">from</span> <span class="hljs-string">'@chakra-ui/react'</span>;
 <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Flex</span>
      <span class="hljs-attr">flexDir</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">lg:</span> '<span class="hljs-attr">row</span>', <span class="hljs-attr">md:</span> '<span class="hljs-attr">row</span>', <span class="hljs-attr">sm:</span> '<span class="hljs-attr">column</span>', <span class="hljs-attr">base:</span> '<span class="hljs-attr">column</span>' }}
      <span class="hljs-attr">pt</span>=<span class="hljs-string">"10%"</span>
      <span class="hljs-attr">w</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">lg:</span> '<span class="hljs-attr">80</span>%' }}
      <span class="hljs-attr">gap</span>=<span class="hljs-string">{10}</span>
      <span class="hljs-attr">justify</span>=<span class="hljs-string">"center"</span>
      <span class="hljs-attr">align</span>=<span class="hljs-string">"center"</span>
      <span class="hljs-attr">m</span>=<span class="hljs-string">"auto"</span>
    &gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Box</span> <span class="hljs-attr">w</span>=<span class="hljs-string">"100%"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Image</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"Images/Contact_Bg.png"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Contact Background"</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">Box</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">Box</span> <span class="hljs-attr">w</span>=<span class="hljs-string">"80%"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Text</span>
          <span class="hljs-attr">as</span>=<span class="hljs-string">"h1"</span>
          <span class="hljs-attr">fontSize</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">base:</span> '<span class="hljs-attr">2xl</span>', <span class="hljs-attr">md:</span> '<span class="hljs-attr">3xl</span>', <span class="hljs-attr">sm:</span> '<span class="hljs-attr">3xl</span>' }}
          <span class="hljs-attr">fontWeight</span>=<span class="hljs-string">"bold"</span>
          <span class="hljs-attr">mb</span>=<span class="hljs-string">{3}</span>
        &gt;</span>
          Get In Touch
        <span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Text</span>
          <span class="hljs-attr">as</span>=<span class="hljs-string">"p"</span>
          <span class="hljs-attr">w</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">base:</span> '<span class="hljs-attr">100</span>%', <span class="hljs-attr">md:</span> '<span class="hljs-attr">80</span>%' }}
          <span class="hljs-attr">mt</span>=<span class="hljs-string">{5}</span>
          <span class="hljs-attr">fontSize</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">base:</span> '<span class="hljs-attr">sm</span>', <span class="hljs-attr">md:</span> '<span class="hljs-attr">md</span>', <span class="hljs-attr">lg:</span> '<span class="hljs-attr">lg</span>' }}
          <span class="hljs-attr">mb</span>=<span class="hljs-string">{6}</span>
        &gt;</span>
          Please use the form below to get in touch with us, and our team will
          get back to you as soon as possible. If you prefer to contact us by
          phone, you can find our contact details below.
        <span class="hljs-tag">&lt;/<span class="hljs-name">Text</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">Box</span> <span class="hljs-attr">w</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">base:</span> '<span class="hljs-attr">100</span>%', <span class="hljs-attr">md:</span> '<span class="hljs-attr">90</span>%' }}&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Input</span>
            <span class="hljs-attr">required</span>
            <span class="hljs-attr">value</span>=<span class="hljs-string">{name}</span>
            <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Name"</span>
            <span class="hljs-attr">mb</span>=<span class="hljs-string">{4}</span>
            <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Name"</span>
          /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Input</span>
            <span class="hljs-attr">required</span>
            <span class="hljs-attr">value</span>=<span class="hljs-string">{email}</span>
            <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Input your Email"</span>
            <span class="hljs-attr">mb</span>=<span class="hljs-string">{4}</span>
            <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Email"</span>
          /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Input</span>
            <span class="hljs-attr">required</span>
            <span class="hljs-attr">value</span>=<span class="hljs-string">{subject}</span>
            <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Subject"</span>
            <span class="hljs-attr">mb</span>=<span class="hljs-string">{4}</span>
            <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Subject"</span>
          /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Textarea</span>
            <span class="hljs-attr">value</span>=<span class="hljs-string">{message}</span>
            <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Message"</span>
            <span class="hljs-attr">mb</span>=<span class="hljs-string">{4}</span>
            <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Message"</span>
            <span class="hljs-attr">resize</span>=<span class="hljs-string">"none"</span>
          /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">Box</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">Button</span>
          <span class="hljs-attr">mb</span>=<span class="hljs-string">{4}</span>
          <span class="hljs-attr">isLoading</span>=<span class="hljs-string">{isLoading}</span>
          <span class="hljs-attr">isDisabled</span>=<span class="hljs-string">{isLoading}</span>
          <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleSubmit}</span>
          <span class="hljs-attr">colorScheme</span>=<span class="hljs-string">"teal"</span>
        &gt;</span>
          Send
        <span class="hljs-tag">&lt;/<span class="hljs-name">Button</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">Box</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Flex</span>&gt;</span></span>
  );
}
</code></pre>
<p>In the code above, we’re importing the various UI components from the Charkra UI library which we’ll use for building the form input.</p>
<p>Now that we’ve created the form inputs, let’s focus on the logical aspect: making the form input functional. Here’s how you can do this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
</code></pre>
<p>You import the <code>useState</code> hook (which is a React hook) which lets you effectively declare/add states and manage states in a functional component.</p>
<p>The <code>useState</code> hook declaring states and managing states might sound a bit off to you – but I have an article that’ll help you understand how the <code>useState</code> hook functions: <a target="_blank" href="https://www.freecodecamp.org/news/how-to-use-the-usestate-and-useeffect-hooks-in-your-project">Here you go</a>.</p>
<p>Next, you’ll need to declare your state variables. Here’s how you can do that:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> [name, setName] = useState(<span class="hljs-string">''</span>);
<span class="hljs-keyword">const</span> [email, setEmail] = useState(<span class="hljs-string">''</span>);
<span class="hljs-keyword">const</span> [subject, setSubject] = useState(<span class="hljs-string">''</span>);
<span class="hljs-keyword">const</span> [message, setMessage] = useState(<span class="hljs-string">''</span>);
<span class="hljs-keyword">const</span> [isLoading, setIsLoading] = useState(<span class="hljs-literal">false</span>);
<span class="hljs-keyword">const</span> [error, setError] = useState(<span class="hljs-string">''</span>);
</code></pre>
<p>In the code above, the state variable includes the likes of <code>name</code>, <code>email</code>, <code>subject</code>, <code>message</code>, and so on which we’re using to store user inputs from the contact form. Then we’re using <code>setName</code>, <code>setEmail</code>, <code>setSubject</code>, <code>setMessage</code> and so on to manage and update the state in case the initial value changes at some point later.</p>
<p>Next, create a function to handle the form submission:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> handleSubmit = <span class="hljs-keyword">async</span> (e) =&gt; {
  e.preventDefault();
  setIsLoading(<span class="hljs-literal">true</span>);
  setError(<span class="hljs-string">''</span>);
</code></pre>
<p>Here, <code>e.preventDefault()</code> helps prevent the page from reloading when the form is submitted. <code>SetIsLoading(true)</code> shows that the form submission is in progress. And <code>setError(‘ ‘)</code> clears any previous error messages that might have occurred during submission.</p>
<p>Next, create a form validation function to validate the input forms and seek out any errors before the form is finally submitted.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">if</span> (!name || !email || !subject || !message) {
  setError(<span class="hljs-string">'All fields are required.'</span>);
  setIsLoading(<span class="hljs-literal">false</span>);
  <span class="hljs-keyword">return</span>;
}

<span class="hljs-keyword">if</span> (!<span class="hljs-regexp">/\S+@\S+\.\S+/</span>.test(email)) {
  setError(<span class="hljs-string">'Invalid email format.'</span>);
  setIsLoading(<span class="hljs-literal">false</span>);
  <span class="hljs-keyword">return</span>;
}
</code></pre>
<p>Before the form is finally submitted, the code above first checks if all the input fields are filled out. If any field is found empty, it displays an error and immediately the form submission is stopped. The same goes for the email. Emails are arranged and typed out in a specific syntax, and if the email field doesn’t follow that syntax, an error is displayed as well.</p>
<p>Next, create an object which stores the information given by the user when they fill out the form. This information will be sent to the backend.</p>
<pre><code class="lang-javascript">Const formData = {name, email, subject, message };
</code></pre>
<p>Now, create a function that sends your data to the backend:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">try</span> {
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">" YOUR API LINK GOES HERE"</span>, {
    <span class="hljs-attr">method</span>: <span class="hljs-string">'POST'</span>,
    <span class="hljs-attr">headers</span>: { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span> },
    <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify(formData),
  });

  <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> response.json();
</code></pre>
<p>The <code>fetch</code> response sends the data to the backend API. It uses the <code>post</code> method. When the data is sent to the backend, it’s sent out as a <code>JSON</code> file. Then the data inside the <code>JSON</code> file are all converted into a string.</p>
<p>This is what it looks like when sent:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742477266973/7c1a1da7-c7f7-40bc-89f2-a26cb1f444e4.png" alt="7c1a1da7-c7f7-40bc-89f2-a26cb1f444e4" class="image--center mx-auto" width="389" height="149" loading="lazy"></p>
<p>At this point, let’s work on the response handling from the API as well as error handling:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">if</span> (response.ok) {
      alert(result.message || <span class="hljs-string">'Email sent successfully!'</span>);
      setName(<span class="hljs-string">''</span>);
      setEmail(<span class="hljs-string">''</span>);
      setSubject(<span class="hljs-string">''</span>);
      setMessage(<span class="hljs-string">''</span>);
    } <span class="hljs-keyword">else</span> {
      setError(result.error || <span class="hljs-string">'Failed to send email.'</span>);
    }
  } <span class="hljs-keyword">catch</span> (error) {
    setError(<span class="hljs-string">'An unexpected error occurred. Please try again later.'</span>);
  } <span class="hljs-keyword">finally</span> {
    setIsLoading(<span class="hljs-literal">false</span>);
  }
</code></pre>
<p>In the code above, after the user types in their information correctly and submits it, if the message is sent successfully, an alert will be displayed with the message <code>Email sent Successfully</code>. But if the message wasn’t successful – maybe due to how the user typed in their information or due to a failed request – an alert will be displayed as well an error message <code>Failed to send email.</code>.</p>
<p>For handling server errors that might occur due to network issues or due to the API being down, an error message will be displayed <code>An unexpected error occurred. Please try again later.</code>.</p>
<p>At this point, we have successfully built out the frontend aspect of the form. So now we can fully dive into the backend. Let’s get on with it.</p>
<h2 id="heading-backend-setup">Backend Setup</h2>
<p>For the backend, we’ll use <code>Node.js</code>, <code>Dotenv</code>, <code>CORS</code>, <code>Nodemailer</code>, and <code>oAuth2</code>.</p>
<h3 id="heading-backend-libraries-setup">Backend Libraries Setup</h3>
<p>Let’s start by setting up your Node.js server. To do this, you’ll want to create a file inside your backend folder with the name <code>send-email.js</code>. Then in your backend folder, you’ll create a package.json file and install all the dependencies you’ll need.</p>
<p>Start by running <code>npm init -y</code> in your terminal. This creates the Package.json file which manages your project and stores all the dependencies.</p>
<p>Next, let’s go ahead and install the libraries you’ll be using:</p>
<ul>
<li><p><code>Nodemailer</code> enables email sending, as you now know.</p>
</li>
<li><p><code>dotenv</code> loads an environment where you’ll store your <code>.env</code> file.</p>
</li>
<li><p><code>cors</code> allows requests between the frontend and the backend.</p>
</li>
<li><p><code>googleapis</code> provides OAuth2 authentication support for sending emails securely.</p>
</li>
</ul>
<p>You can install these one by one by running the commands <code>npm install nodemailer</code>, <code>npm install dotenv</code>, <code>npm install cors</code>, and <code>npm install googleapis</code>. Or you can install them all at once with:</p>
<pre><code class="lang-bash">npm install nodemailer dotenv cors googleapis
</code></pre>
<p>Note that <code>cors</code> plays an important role in ensuring effective communication between your frontend server and the backend. <a target="_blank" href="https://www.freecodecamp.org/news/access-control-allow-origin-header-explained">You can learn more about CORS here</a>.</p>
<h3 id="heading-oauth2-configuration-setup">OAuth2 Configuration Setup</h3>
<p>Now before you finish setting up the send email function, you first need to configure <code>OAuth2</code> to get access to the tokens and keys you’re using, such as <code>CLIENT_ID</code>, <code>CLIENT_SECRET</code>, <code>REFRESH_TOKEN</code>, and so on.</p>
<p>To set up OAuth2, <a target="_blank" href="https://console.cloud.google.com/projectselector2/home">go here</a> to visit your Google Cloud dashboard. Once it opens, it should look like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742477897924/e6879a15-6835-42e8-a869-8e49b725101a.png" alt="Google Cloud Dashboard" class="image--center mx-auto" width="1914" height="572" loading="lazy"></p>
<p>On the screen, click on “create project” and it’ll take you to a place where you can create your project. It should look like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742477974830/bd51345f-0af8-4ad0-a912-0a59db8e3fee.png" alt="Google Cloud Project Creation" class="image--center mx-auto" width="1067" height="703" loading="lazy"></p>
<p>After you create your project, it’ll take you to your dashboard with your project name displayed at the top right left corner of the screen. This shows that you have successfully created your project. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742478101790/7fa5e621-69c2-4144-ae9c-a3bd9b59a038.png" alt="Google Cloud Dashboard after Project has been created" class="image--center mx-auto" width="1258" height="927" loading="lazy"></p>
<p>After creating the account, click the toggle button at the top left-hand corner of your screen. When it opens, click on the APIs &amp; Services button. A dropdown should then be displayed. Then click on the OAuth consent screen. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742478459190/1af14c8f-7cff-4efa-804c-88ba19f0c47c.png" alt="Google Cloud API and Services Process" class="image--center mx-auto" width="861" height="655" loading="lazy"></p>
<p>After that, it should direct you to a new page where you can then configure your project.</p>
<p>The configuration process has four steps, which we’ll go through now.</p>
<h4 id="heading-step-1-add-app-information">Step 1: Add app information</h4>
<p>First, you’ll need to add your app’s information, which includes your app name and user support email. For the app name, go ahead and add your project name there. For the support email, add your email address and click on the ‘Next’ button. It should look like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742478695772/587bef4a-e1e1-4ae8-94e0-f620f4b81c79.png" alt="Project configuration step 1" class="image--center mx-auto" width="767" height="388" loading="lazy"></p>
<h4 id="heading-step-2-set-up-the-audience-section">Step 2: Set up the audience section</h4>
<p>Next, you’ll need to set up the Audience section. In this section, choose the ‘External’ options, which means that others (not only those within the organization) can send messages with the web application. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742478724025/59dde0dd-e1f7-445c-9155-64926f71d746.png" alt="Project configuration step 2" class="image--center mx-auto" width="720" height="468" loading="lazy"></p>
<h4 id="heading-step-3-add-contact-information">Step 3: Add contact information</h4>
<p>Now you’ll come to the contact information section, where you’ll need to add your email address.</p>
<h4 id="heading-step-4-agree-to-google-api-services">Step 4: Agree to Google API Services</h4>
<p>Finally, you’ll need to agree to the Google API Services. After that, you can finish the configuration of your project by clicking on the ‘create’ button.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742478750231/742f0104-0631-4442-8a69-1266b433a1d1.png" alt="Project configuration step 3" class="image--center mx-auto" width="685" height="264" loading="lazy"></p>
<p>After you’ve completely configured your project, it’ll take you to a page where you can create your client ID. To create it, click on the ‘Create Oauth Client’ button on the screen.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742478869578/b12e0437-ef27-4127-80fb-d8e36a2714c1.png" alt="Create OAuth Client Section" class="image--center mx-auto" width="1592" height="461" loading="lazy"></p>
<p>This takes you to a place where you’ll add the information about your project. For the “project type/Application type”, choose Web application, and then scroll down and click on the Create button.</p>
<p>After that, your <code>Client ID</code> and <code>Client Secret</code> token should finally be generated. Here is what it looks like:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742479023599/004465be-cce9-4b20-aa32-5a4f676f4d03.png" alt="Client ID and Client Secret generation Successful" class="image--center mx-auto" width="642" height="712" loading="lazy"></p>
<p>Next, head to the <a target="_blank" href="https://developers.google.com/oauthplayground/">OAuth Playground</a> where you’ll complete the final setup. Once there, click on the gear button at the top right of the screen. There, just add your <code>client ID</code> and <code>Client Secret</code> which you generated before.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742479184829/7885b38b-de54-46fb-9c0d-a0739110dd98.png" alt="Refresh token generation process step 1 " class="image--center mx-auto" width="582" height="770" loading="lazy"></p>
<p>Then on the left, scroll down to ‘Gmail API v1’, click on it, and select the first dropdown option which was ‘<a target="_blank" href="https://mail.google.com/’">https://mail.google.com/’</a>. Then click on ‘Authorize APIs’.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742479467364/2f04e0ac-3514-4bc4-b16f-cf163770a5c5.png" alt="Refresh token generation process step 2" class="image--center mx-auto" width="762" height="821" loading="lazy"></p>
<p>This’ll take you to a sign-in with Google page, where you can choose your email account and continue.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742479538105/c3470cfa-5867-40a2-a2bc-122334efa752.png" alt="Refresh token generation process step 3" class="image--center mx-auto" width="1381" height="742" loading="lazy"></p>
<p>Then you’ll be redirected back to the OAuth Playground dashboard. At this point, your Authorization code has been generated for you, but what you really need is the <code>Refresh token</code>. So to get it, click on <code>Exchange authorization code for tokens</code>. After that your <code>refresh token</code> should be generated.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742479669946/76b6b4a3-1929-4354-abb2-a7f514e04c20.png" alt="Refresh token generation process Completion stage" class="image--center mx-auto" width="619" height="695" loading="lazy"></p>
<p>At this point, your OAuth2 configuration is done! Now what’s left is to store all the tokens you generated in an <code>.env</code> file you’ve created. You’ll also need to set up your send email function using <code>NodeMailer</code>.</p>
<h3 id="heading-nodemailer-setup"><code>Nodemailer</code> Setup</h3>
<p>Now, that you’ve gotten all the tokens you need to create your mailer function, all that remains is to start putting your backend code together.</p>
<p>First, start by loading your <code>.env</code> file into <code>process.env</code> so you can easily access all the tokens you generated. Also, import the libraries you initially installed.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">require</span>(<span class="hljs-string">"dotenv"</span>).config();
<span class="hljs-keyword">const</span> nodemailer = <span class="hljs-built_in">require</span>(<span class="hljs-string">"nodemailer"</span>);
<span class="hljs-keyword">const</span> cors = <span class="hljs-built_in">require</span>(<span class="hljs-string">"cors"</span>);
<span class="hljs-keyword">const</span> { google } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"googleapis"</span>);
</code></pre>
<p>Next on the line, you’ll need to set up OAuth2. Here, the <code>client ID</code>, and <code>client Secret</code> which you initially generated will be used to authenticate the application and securely request and create access tokens. These will be used for seamlessly sending emails through Google APIs.</p>
<p>You’ll also need to configure the refresh token which lets the application obtain new access tokens automatically without requiring user interaction.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> oAuth2Client = <span class="hljs-keyword">new</span> google.auth.OAuth2(
  process.env.CLIENT_ID,
  process.env.CLIENT_SECRET,
  process.env.REDIRECT_URI
);

<span class="hljs-comment">//setting up refresh token.</span>
oAuth2Client.setCredentials({
  <span class="hljs-attr">refresh_token</span>: process.env.OAUTH_REFRESH_TOKEN,
});
</code></pre>
<p>Since we want the frontend to interact properly with the backend, you’ll want to configure a <code>CORS Middleware</code>. This allows requests from any origin (`*`) as well as allowing POST requests from that origin. Here is how you can do that:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> corsMiddleware = cors({ <span class="hljs-attr">origin</span>: <span class="hljs-string">"*"</span>, <span class="hljs-attr">methods</span>: [<span class="hljs-string">"POST"</span>] });
</code></pre>
<p>Next, create a function to handle <code>CORS</code> and the Request Method. This function applies the <code>CORS</code> middleware to the request in such a way that if the request method is <code>OPTIONS</code>, it responds with a <code>200 status (“preflight OK”)</code>. This means that your request has been approved/allowed by the server because it met the server’s set rules. If the request method is not <code>POST</code>, a response of <code>405 status (“Method not allowed”)</code> will be displayed, showing that your request does not meet the server’s set rule.</p>
<p>Here’s how it’s done:</p>
<pre><code class="lang-javascript">corsMiddleware(req, res, <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">if</span> (req.method === <span class="hljs-string">"OPTIONS"</span>) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).send(<span class="hljs-string">"Preflight OK"</span>);
  }

  <span class="hljs-keyword">if</span> (req.method !== <span class="hljs-string">"POST"</span>) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">405</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"Method not allowed"</span> });
  }
</code></pre>
<p>Next, create a function that extracts and validates the input request. This request contains the senders <code>name</code>, <code>email</code>, <code>subject</code>, and <code>message</code>. This function ensures that all the input fields must be filled out and the email must also be written properly. If not, it responds with a <code>400 status</code> error.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> { name, email, subject, message } = req.body;

<span class="hljs-comment">// Validate input</span>
<span class="hljs-keyword">if</span> (!name || !email || !subject || !message) {
  <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"All fields are required."</span> });
}

<span class="hljs-keyword">if</span> (!<span class="hljs-regexp">/^[^\s@]+@[^\s@]+\.[^\s@]+$/</span>.test(email)) {
  <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"Invalid email address."</span> });
}
</code></pre>
<p>Up next, you’ll create a function that helps retrieve new access tokens. You’ll also create a Nodemailer transporter function. This transporter was configured to use Gmail’s SMTP service with OAuth2 authentication.</p>
<p>This means whenever a user sends an email, the transporter function first verifies if the Gmail’s SMTP service is ready. If it is, the mail will be verified first with OAuth2, and if the authentication check is successful, the mail will be delivered successfully.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//Function to retrieve new access token</span>
<span class="hljs-keyword">const</span> accessToken = <span class="hljs-keyword">await</span> oAuth2Client.getAccessToken();
<span class="hljs-keyword">if</span> (!accessToken || !accessToken.token) {
  <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Failed to retrieve access token."</span>);
}
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Access token retrieved successfully."</span>);

<span class="hljs-comment">/// Creating the Nodemailer Transporter function</span>
<span class="hljs-keyword">const</span> transporter = nodemailer.createTransport({
  <span class="hljs-attr">service</span>: <span class="hljs-string">"gmail"</span>,
  <span class="hljs-attr">auth</span>: {
    <span class="hljs-attr">type</span>: <span class="hljs-string">"OAuth2"</span>,
    <span class="hljs-attr">user</span>: process.env.EMAIL_HOST,
    <span class="hljs-attr">clientId</span>: process.env.CLIENT_ID,
    <span class="hljs-attr">clientSecret</span>: process.env.CLIENT_SECRET,
    <span class="hljs-attr">refreshToken</span>: process.env.OAUTH_REFRESH_TOKEN,
    <span class="hljs-attr">accessToken</span>: accessToken.token,
  },
  <span class="hljs-attr">debug</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">logger</span>: <span class="hljs-literal">true</span>,
});

<span class="hljs-comment">///The function verifying if SMTP server is ready</span>
<span class="hljs-keyword">await</span> transporter.verify();
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"SMTP server is ready to send emails."</span>);
</code></pre>
<p>Lastly, you’ll want to structure your mail in the format it should be displayed in the mailbox of the receiver. You’ll also create an error handling function which displays whenever a mail is sent successfully or whenever an error occurs.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> mailOptions = {
        <span class="hljs-attr">from</span>: <span class="hljs-string">`"<span class="hljs-subst">${name}</span>" &lt;<span class="hljs-subst">${email}</span>&gt;`</span>,
        <span class="hljs-attr">to</span>: process.env.EMAIL_RECEIVE,
        <span class="hljs-attr">replyTo</span>: email,
        subject,
        <span class="hljs-attr">html</span>: <span class="hljs-string">`
          &lt;h1&gt;Name: <span class="hljs-subst">${name}</span>&lt;/h1&gt;
          &lt;p&gt;Email: <span class="hljs-subst">${email}</span>&lt;/p&gt;
          &lt;p&gt;Subject: <span class="hljs-subst">${subject}</span>&lt;/p&gt;
          &lt;p&gt;Message: <span class="hljs-subst">${message}</span>&lt;/p&gt;
          &lt;p&gt;&lt;i&gt;Message from Exesenergy Website&lt;/i&gt;&lt;/p&gt;
        `</span>,
      };
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Mail options:"</span>, mailOptions);

      <span class="hljs-comment">// Send email</span>
      <span class="hljs-keyword">await</span> transporter.sendMail(mailOptions);
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Email sent successfully."</span>);

      <span class="hljs-keyword">return</span> res
        .status(<span class="hljs-number">200</span>)
        .json({ <span class="hljs-attr">status</span>: <span class="hljs-string">"success"</span>, <span class="hljs-attr">message</span>: <span class="hljs-string">"Email sent successfully."</span> });
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error details:"</span>, error);
      <span class="hljs-keyword">return</span> res
        .status(<span class="hljs-number">500</span>)
        .json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"Internal Server Error"</span>, <span class="hljs-attr">details</span>: error.message });
    }
</code></pre>
<p>At this point, you have successfully set up both your frontend and backend applications. Now you may want to host them. I decided to host both applications using Vercel and link their URLs together.</p>
<p>Here is the source code to access both the <a target="_blank" href="https://github.com/Derekvibe/ExesEnergyFrontend">frontend</a> and the <a target="_blank" href="https://github.com/Derekvibe/ExesEnergyBackend/blob/main/api/send-email.js">backend</a>.</p>
<p>Here is the final result:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742476641876/69f5123a-570f-4e1a-bbed-6278b54fed7a.gif" alt="Video Representation of How the Send mail function works" class="image--center mx-auto" width="1493" height="820" loading="lazy"></p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>Nodemailer is a popular Node.js module that enables its users to send emails efficiently using different methods like SMTP and OAuth2.</p>
<p>If you've made it this far, I hope I've successfully shown you the importance of Nodemailer and how you can use it to send email messages directly from your website.</p>
<p>Thank you for reading!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Next.js vs React – Differences and How to Choose the Right One for Your Project ]]>
                </title>
                <description>
                    <![CDATA[ As a developer, there are many tools, languages, frameworks and open-source packages you have to learn in order to make your job easier and straightforward (though the journey isn’t a straightforward one but you will get there). Some of these tools, ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/nextjs-vs-react-differences/</link>
                <guid isPermaLink="false">6750b8d54a1773ff14ce07cd</guid>
                
                    <category>
                        <![CDATA[ Next.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Okoro Emmanuel Nzube ]]>
                </dc:creator>
                <pubDate>Wed, 04 Dec 2024 20:17:25 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1733260801154/22f3a036-3b7f-4e38-946e-93ec432164b1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>As a developer, there are many tools, languages, frameworks and open-source packages you have to learn in order to make your job easier and straightforward (though the journey isn’t a straightforward one but you will get there).</p>
<p>Some of these tools, languages, or frameworks are used daily by community members and can undergo fundamental changes in how they are implemented or written over time.</p>
<p>In this article, we will explore two popular JavaScript technologies, Next.js and React.js, by comparing their key differences, examining their strengths, and offering insights to help developers choose the best option for their projects.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-table-of-contents">Table of Contents</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-understanding-react">Understanding React</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-client-side-rendering">Client-side Rendering</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-use-cases-for-react-in-web-development">Use Cases for React in Web Development</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-exploring-nextjs">Exploring Next.js</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-server-side-rendering">Server-side Rendering</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-use-cases-for-nextjs-in-web-development">Use Cases for Next.js in web development</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-key-difference-between-nextjs-and-react">Key Difference Between Next.js and React</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-rendering-methods-client-side-vs-server-side">Rendering Methods: client-side vs. server-side</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-performance-considerations">Performance Considerations</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-seo-implications">SEO Implications</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-scalability-and-project-complexity">Scalability and Project Complexity</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-when-to-use-react-or-nextjs">When to Use React or Next.js</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-when-to-use-react">When to use React</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-when-to-use-nextjs">When to Use Next.js</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-understanding-react">Understanding React</h2>
<p>We often confuse ourselves as to whether React is a JavaScript framework or not, but here is the answer to that question. React is not a JavaScript framework, it is a JavaScript library. Now, these two terminologies are often interchanged or misused, but I will explain them shortly.</p>
<p>A library is a collection of already-written code that can be reused or called upon when building your own project.</p>
<p><strong>Example:</strong> Imagine a library where you go to study. The books are already available on the shelves – you simply pick the one you need and start reading. Similarly, in programming, a library provides ready-made tools that you can use in your project without starting from scratch.</p>
<p>On the other hand, a framework is like a ready-made structure that helps you build your project. It gives you a solid foundation to work with, so you don't have to start from scratch or write repetitive code. Instead, you focus on adding your own features and logic, while the framework takes care of running things at the right time and in the right way.</p>
<p><strong>Example:</strong> Think of a framework like a house under construction where the walls, foundation, and roof are already built. All you need to do is decide how to design the interior—like choosing the furniture, paint, and decorations. The framework handles the heavy lifting, like ensuring the house stands strong, while you focus on making it your own. Similarly, in programming, the framework provides the structure, and you add your custom logic to complete the project.</p>
<p>With that out of the way, let’s move on.</p>
<p>React is one of the most popular JavaScript libraries used by developers to build fast, interactive, and reliable user interfaces. It is a declarative library that helps developers create component-based web applications. Facebook developed this library in 2011 and it has been trending since then.</p>
<p>Usually, when writing JavaScript code, we create a file with the extension <code>js</code>. For example: <code>App.js</code>, <code>script.js</code>, and so on. In React we create a file with the extension <code>jsx</code>. That is: <code>index.jsx</code>, <code>Home.jsx</code>, and so on. The <code>jsx</code> is a React extension that allows you to write a JavaScript code resembling HTML. The syntax, when executed, is passed through preprocessors/transpilers which transforms the HTML-looking code into a standard JavaScript code.</p>
<p>At the heart of all React applications are components. Components are chunks of user interfaces (UI) which are built independently and can be reused in different parts of your project. Different components can be built separately and later brought together to form a complex user interface (UI).</p>
<p><strong>Note:</strong> Every React application has at least one component, commonly referred to as the root component. This component represents the entire application. Within the root component, there are often other components, known as child components, that help structure and manage different parts of the application.</p>
<p>Here is a structural representation of root and child components.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732758941272/17c6b471-b2a7-40ae-83f8-4e215a50c853.png" alt="structural representation of root and child components" class="image--center mx-auto" width="939" height="753" loading="lazy"></p>
<p>From the image above, you can clearly understand what components are all about. <code>App</code> is the root component, and inside the root component, we have the child components: <code>Navbar</code>, <code>Profile</code>, <code>Blog</code> and <code>Footer</code>. The child components can be reused on other pages of the project without having to rewrite the code again.</p>
<h3 id="heading-client-side-rendering">Client-side Rendering</h3>
<p>Client-side rendering (CSR) is a common technique, especially in libraries like React and frameworks like Vue.js, Angular, and so on. Here, the browser downloads and processes JavaScript files to dynamically render content directly on the user's device. With CSR, web pages are generated dynamically, and any updates or changes to the code are applied without requiring a full page reload. Only the specific parts that have changed are updated, ensuring a seamless and efficient user experience.</p>
<p>Therefore, in CSR, the logic and structure of the web page is handled by the client (browser) and a fully rendered page is displayed.</p>
<p>To help you understand CSR, <a target="_blank" href="https://www.freecodecamp.org/news/rendering-patterns/#heading-single-page-applications-spas-with-client-side-rendering-csr">I have added an article here</a>.</p>
<h3 id="heading-use-cases-for-react-in-web-development"><strong>Use Cases for React in Web Development</strong></h3>
<p>Ever since React became a go-to choice for many developers, its flexibility has made it suitable for a wide range of use cases in web development. Here are a few cases:</p>
<ul>
<li><p><strong>Single Page Applications (SPAs):</strong> When we talk about SPAs, we don’t really mean that your web application has only one page, it can go on to having multiple pages. In SPAs, your web application files (HTML, CSS, JS) are generated once on your web page and when subsequent updates are made on the file, your page won’t have to fully reload. This approach helps ensure a faster transition, reduces load on the server and enhance overall user experience.</p>
</li>
<li><p><strong>Interactive User Interfaces:</strong> React is suitable for building interactive user interfaces which, from time to time, undergo dynamic updates based on the actions of the users. Examples are online forms, dashboards, websites (E-commerce websites), and so on.</p>
</li>
<li><p><strong>Cross-Platform Applications:</strong> Having React knowledge comes in handy when building mobile applications, simplifying the connection between web applications and mobile applications. Tools like React Native helps you achieve this process.</p>
</li>
</ul>
<h2 id="heading-exploring-nextjs"><strong>Exploring Next.js</strong></h2>
<p>Next.js is a popular React-based framework used in building web applications with the use of React components. Next.js provides additional structure, features, and optimization for your web application.</p>
<p>Unlike React, Next.js supports server-side rendering (SSR), so requests are processed and generated from the server and then displayed on the browser (client).</p>
<h3 id="heading-server-side-rendering"><strong>Server-side Rendering</strong></h3>
<p>Server-side rendering (SSR) is a technique in web development where a server generates the HTML for a web page on the server and sends it to the browser (client). In other words, the server handles the structures and logic of the page and displays a fully rendered page on the screen.</p>
<p>In server-side rendering, a request is first sent to the server from the browser (client), then the server begins to process the request and when it's done processing the request, it executes the request by generating and displaying an HTML file with the content on the browser (client side). When a change is made or a new page is requested, a new request is sent again to the server and it is processed all over again – a fresh, fully rendered HTML file will be generated and displayed on the browser (client).</p>
<p>For a better understanding of CSR and SSR, I have added a <a target="_blank" href="https://youtu.be/-JXUaydU1J0?si=U3PrqicrIJoLYOM9">YouTube video here</a>.</p>
<h3 id="heading-use-cases-for-nextjs-in-web-development">Use Cases for Next.js in web development</h3>
<ul>
<li><p><strong>Single Page Application (SPAs):</strong> Next.js can be used in the creation of single page applications, similar to React.</p>
</li>
<li><p><strong>SEO-Friendly:</strong> Next.js helps create SEO-friendly websites by rendering an HTML file on the server and delivering it to the browser. This improves search engine visibility, increasing the chances of your website appearing at the top of search results.</p>
</li>
<li><p><strong>Multi-User Platforms:</strong> Due to Next.js ability to handle dynamic routing, API handling, and so on, it’s easy to create applications that serve various purposes.</p>
</li>
</ul>
<h2 id="heading-key-difference-between-nextjs-and-react">Key Difference Between Next.js and React</h2>
<h3 id="heading-rendering-methods-client-side-vs-server-side">Rendering Methods: client-side vs. server-side</h3>
<p>When we talk about the rendering method in React, React relies mainly on rendering with the client-side rendering (CSR) method. Therefore both the logic and the structure of the web page will be handled by the browser (client). Though this method is commonly used, it has some downside effects like slower initial page load.</p>
<p>Next.js, on the other hand, supports both SSR and CSR because it was built on top of React. Web pages are rendered on the server and both logic and structure of the page are all handled by the server. This enables a faster loading of the web page and also improves the SEO.</p>
<h3 id="heading-performance-considerations">Performance Considerations</h3>
<p>In terms of performance considerations, Next.js is often preferred because it offers multiple rendering options, including server-side rendering (SSR), static site generation (SSG), Incremental Static Regeneration (ISR), and client-side rendering (CSR). In contrast, React primarily provides a single rendering approach: client-side rendering.</p>
<h3 id="heading-seo-implications">SEO Implications</h3>
<p>React is less SEO-friendly because search engines may struggle to index content that requires JavaScript execution to render.</p>
<p>On the other hand, Next.js is more SEO-friendly than React because it renders content on the server, providing fully-rendered HTML to search engines for easier indexing.</p>
<h3 id="heading-scalability-and-project-complexity">Scalability and Project Complexity</h3>
<p>In terms of scalability and project complexity, Next.js is generally better than React. Next.js provides built-in features that enhance the scalability of your project. These include:</p>
<ul>
<li><p>Server-side rendering (SSR) and static site generation (SSG) for better performance and SEO.</p>
</li>
<li><p>A built-in API routes feature for creating serverless functions seamlessly.</p>
</li>
<li><p>A file-based routing system that simplifies the organization of larger projects.</p>
</li>
</ul>
<p>In contrast, with React, you are responsible for setting up and maintaining the structure for scalability. For larger projects, this often requires adding additional tools such as:</p>
<ul>
<li><p>State management libraries (for example, Redux, Recoil, and so on).</p>
</li>
<li><p>Routing libraries (for example, React Router).</p>
</li>
</ul>
<p>These tools are necessary to enhance React's scalability and address project complexity, but they also increase the overhead and effort needed to set up and manage the application.</p>
<p>In summary, here is a tabular break down;</p>
<table><tbody><tr><td><p><strong>Factors</strong></p></td><td><p><strong>React</strong></p></td><td><p><strong>Next.js</strong></p></td></tr><tr><td><p>Scalability</p></td><td><p>It is possible but to increase scalability, it requires additional tools and a custom setup</p></td><td><p>It is scalable and already has built-in tools that increase the scalability.</p></td></tr><tr><td><p>Performance</p></td><td><p>It provides only one rendering option which is client-side rendering (CSR)</p></td><td><p>It offers multiple rendering options, including SSR, SSG, ISR, and CSR.</p></td></tr><tr><td><p>SEO</p></td><td><p>It is less SEO-friendly because search engines may struggle to index content that requires JavaScript execution to render.</p></td><td><p>It is more SEO-friendly than React because it renders content on the server, providing fully-rendered HTML to search engines for easier indexing.</p></td></tr><tr><td><p>Use Case</p></td><td><p>Mostly used in smaller or unique projects</p></td><td><p>Mostly used in large-scale projects and enhances performance and SEO</p></td></tr></tbody></table>

<h2 id="heading-when-to-use-react-or-nextjs">When to Use React or Next.js</h2>
<p>Choosing the right tool for your project solely depends on the complexity of the solution of the project you are building. While React and Next.js are closely related, each has its strengths and optimal use cases.</p>
<h3 id="heading-when-to-use-react">When to use React</h3>
<p>Here are some cases when it is best to use React for your project:</p>
<ul>
<li><p>When building highly interactive applications.</p>
</li>
<li><p>When your project requires manual handling of routing, state management or/and API integration.</p>
</li>
<li><p>When your project requires client-side rendering (CSR)</p>
</li>
</ul>
<h3 id="heading-when-to-use-nextjs">When to Use Next.js</h3>
<p>Here are some cases where it’s best to use Next.js:</p>
<ul>
<li><p>When your project requires a better SEO.</p>
</li>
<li><p>When your project requires server side rendering.</p>
</li>
<li><p>When your project requires you to build APIs along your frontend code.</p>
</li>
<li><p>When building content-driven websites like blogs or e-commerce sites. Due to its use of server-side rendering, it aids in improving the load times of contents on the page.</p>
</li>
<li><p>Next.js is best used when you want to optimize images in your project.</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>At this point I believe you have a clear understanding of React and Next.js, the concepts of server-side and client-side rendering, the use cases for both React and Next.js, and the key differences between them.</p>
<p>Thank you for taking the time to read this. I hope you found it helpful.</p>
<p>Happy coding.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Deploy Your Project On Vercel With A Custom Domain ]]>
                </title>
                <description>
                    <![CDATA[ Have you ever built a project but found it difficult to make it live on the internet? Well, worry no more because this article will help you do that. In this article, I will introduce you to one of the fastest and easiest deployment platforms for bri... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-deploy-your-project-on-vercel/</link>
                <guid isPermaLink="false">671bf3148df28644ca9012f9</guid>
                
                    <category>
                        <![CDATA[ deployment ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Okoro Emmanuel Nzube ]]>
                </dc:creator>
                <pubDate>Fri, 25 Oct 2024 19:35:48 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1729806244084/f4aca70a-801e-4577-8073-e078323db51a.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Have you ever built a project but found it difficult to make it live on the internet? Well, worry no more because this article will help you do that.</p>
<p>In this article, I will introduce you to one of the fastest and easiest deployment platforms for bringing your code/project to the web.</p>
<p>I will also show you how you can deploy a web application with your custom domain and why it’s important to do so.</p>
<p>Let's dive right in.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-overview-of-vercel">Overview of Vercel</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-are-domains">What are Domains?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-set-up-a-vercel-account">How to Set Up a Vercel Account</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-configure-a-custom-domain">How to Configure a Custom Domain</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-overview-of-vercel"><strong>Overview of Vercel</strong></h2>
<p>Vercel is a cloud hosting platform that provides tools that enable developers to build, deploy and scale their web applications. One important fact about this platform is that it is quick, easy to navigate/use, and it is very efficient.</p>
<p>Vercel supports and deploys many frameworks with minimal configuration, especially frameworks built with JavaScript. Here is a list of frameworks that can be deployed to Vercel: Angular, Astro, Brunch, React, Dojo, Gatsby.js, Next.js, Nuxt.js, Vite, Vue.js, Vuepress, and so on.</p>
<p>You may not know all these frameworks at this point, but it's important to know that Vercel supports these frameworks and many more.</p>
<p>See <a target="_blank" href="https://vercel.com/docs/frameworks/more-frameworks">Vercel documentation</a> to view more.</p>
<h2 id="heading-what-are-domains"><strong>What are Domains?</strong></h2>
<p>Domains are ‘unique identifiers’ used to locate or find a specific website on the internet. For example, <a target="_blank" href="http://freecodeCamp.org">freecodeCamp.org</a>. Whenever you see a domain name, you should have an idea of the website it belongs to.</p>
<p>It is important to note that a domain name can be created with a combination of letters (A-z), numbers (0-9), and dash characters.</p>
<h3 id="heading-importance-of-having-a-domain-name"><strong>Importance of Having a Domain Name</strong></h3>
<p>Here are some reasons why you should have a domain name:</p>
<ul>
<li><p><strong>Easy to find and locate you:</strong> Having a domain name makes the work of finding your business easy and also increases the possibility of making more sales from your web page. If you have a physical store, not everyone may want to visit it.</p>
</li>
<li><p><strong>For Professionalism and Credibility:</strong> Imagine having a business but no website or domain. This will make you look unprofessional to customers because they may not take you seriously.</p>
</li>
<li><p><strong>Increase your Online Presence:</strong> With a domain name, your online presence or your brand’s online presence is increased, which makes you more visible.</p>
</li>
</ul>
<p>Now let's talk about setting up a Vercel account. This process is actually simple and easy to follow.</p>
<h2 id="heading-how-to-set-up-a-vercel-account"><strong>How to Set Up a Vercel Account</strong></h2>
<p>The first step is to visit <a target="_blank" href="https://vercel.com/">Vercel</a>.</p>
<p>On the Vercel home page, click on the sign-up button, located at the top right corner of the home page.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729808253459/5946836c-3de9-4d27-bb5a-dd992446bd9c.png" alt="Vercel Home page" class="image--center mx-auto" width="1806" height="711" loading="lazy"></p>
<p>Choose your "Plan Type" and then input your name. Then click on Continue to proceed.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729807310680/e4872073-f8de-4e74-9555-281cf96efa01.png" alt="Vercel setup process " class="image--center mx-auto" width="839" height="739" loading="lazy"></p>
<p>Next, connect the account where you will be importing your project from. You’ll be provided with three options: GitHub, GitLab, or BitBucket.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729807383749/7bab422e-87cd-4b9a-b254-25af80f9a73b.png" alt="Linking your Github or GitLab or Bitbucket to Vercel" class="image--center mx-auto" width="708" height="595" loading="lazy"></p>
<p>In my case, I clicked “Continue with GitHub”.</p>
<p><strong>Note</strong>: If you don’t have a GitHub account, you can read see how to create one <a target="_blank" href="https://www.freecodecamp.org/news/git-and-github-the-basics/">here</a>.</p>
<p>Once you have linked your GitHub account with Vercel, the interface should look like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729807623924/c44c31f2-e77a-4538-9a86-c80d06680779.png" alt="Vercel setup complete interface" class="image--center mx-auto" width="1605" height="702" loading="lazy"></p>
<p>At this point, you’re done setting up your Vercel account. The next step is to deploy your project.</p>
<p>From the image description above, you can see an “import” button. Go to the particular project you want to deploy and click on the import button. In my case, I named my project repository “practice-purpose”.</p>
<p>Once you click the import button, it should lead you to the next page where you can input your project name and finally deploy it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729807744450/3eaf81e5-f53c-45bb-9890-166516ff17c4.png" alt="Deployment setup interface" class="image--center mx-auto" width="849" height="801" loading="lazy"></p>
<p>Wait for a few minutes for the deployment to be complete. After that, your interface should look like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729807863920/fcfdfaa7-a42e-451a-b539-74dc151eca69.png" alt="After Deployment Interface" class="image--center mx-auto" width="1458" height="808" loading="lazy"></p>
<p>Congratulations! At this point, you have deployed your first project.</p>
<h2 id="heading-how-to-configure-a-custom-domain"><strong>How to Configure a Custom Domain</strong></h2>
<p>Before you continue with the process of configuring a custom domain, you must have gotten your domain ready. If not, I have added a quick video that will guide you.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/JRRXTR7PUug" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>For this article, I will be making use of Namecheap, because that is where I got the domain I am using. Feel free to use any domain provider of your choice.</p>
<p>At this point, your domain name should be available. If that is so, let’s continue.</p>
<p>In your deployment page on Vercel, click on “Domain” in the navigation bar, input your custom domain name (the one you bought) in the space provided and click on “Add”.</p>
<p>When you click on the “Add” button, a prompt should pops up – don’t change anything, use the recommended option and click on the ‘Add’ button.</p>
<p>For the next step, click on the “Nameservers” option, then click on “Enable vercel DNS”.</p>
<p>Lastly, copy the DNS and head to the website where you purchased your domain.</p>
<p>Here are detailed images that show the above steps.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729808085843/7061315b-ca1e-4201-bd00-6d3b02bfa456.gif" alt="Custom Domain Setup on Vercel" class="image--center mx-auto" width="1468" height="771" loading="lazy"></p>
<p>At this point, all you have to do is link your custom domain with Vercel, using the DNS you just copied from Vercel.</p>
<p>Here is how you can go do that (I’ll use the Namecheap process to explain it):</p>
<p>Go to the website where you purchased your domain and log in to your dashboard.</p>
<p>Head to the domain list option and click on it. This should display a list of domains you have purchased with that account.</p>
<p>Next, head to the domain name you used for your Vercel project and click on the “manage” option. This should open a page where details of the domain is displayed.</p>
<p>Find where you have “nameservers” and choose the “custom DNS” option. Lastly, paste each of the DNS you copied from Vercel into the spaces provided and click on save.</p>
<p>After this, you should get a prompt stating that the custom domain will be live in the next 48 hours. In most cases, it doesn’t take up to a day for it to be active.</p>
<p>Here is a detailed image that shows the above steps.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729808142674/7d533d7d-0ea9-4cf8-bd19-183283ffa150.gif" alt="Custom Domain Setup on Namecheap" class="image--center mx-auto" width="1890" height="981" loading="lazy"></p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>In this article, you learned about the Vercel platform, what a domain name means and its importance.</p>
<p>You also learned how to set up your Vercel account, deploy your project, and add a custom domain.</p>
<p>If you’ve read up to this point, I want to say a very big congratulations, and I hope you got the value out of this article.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Git Stash to Efficiently Manage Your Code ]]>
                </title>
                <description>
                    <![CDATA[ Sometimes when you’re coding, you need to leave a particular task incomplete to focus on another task – but you don't want to lose your progress. So what do you do? Fortunately, git stash comes to the rescue. In this article, you’ll learn all about t... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-git-stash-to-manage-code/</link>
                <guid isPermaLink="false">67092ab15a02c36736216d67</guid>
                
                    <category>
                        <![CDATA[ gitpop ]]>
                    </category>
                
                    <category>
                        <![CDATA[ gitapply ]]>
                    </category>
                
                    <category>
                        <![CDATA[ git stash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ code management ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Okoro Emmanuel Nzube ]]>
                </dc:creator>
                <pubDate>Fri, 11 Oct 2024 13:40:01 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1728563160215/147e5b8d-960d-4a90-ad2f-6d71337ac0ce.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Sometimes when you’re coding, you need to leave a particular task incomplete to focus on another task – but you don't want to lose your progress. So what do you do? Fortunately, <code>git stash</code> comes to the rescue.</p>
<p>In this article, you’ll learn all about the <a target="_blank" href="https://git-scm.com/docs/git-stash">git stash</a> command and why it’s important to stash your code. By the end of this article, you will have firsthand knowledge of how to use the <code>git stash</code> command in your projects.</p>
<h3 id="heading-heres-what-well-cover">Here’s what we’ll cover:</h3>
<ol>
<li><p><a class="post-section-overview" href="#heading-why-do-we-stash">Why do we stash?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-pros-and-cons-of-using-git-stash">Pros and cons of using git stash</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-a-stash-in-git-step-by-step-guide">How to create a stash in Git (step-by-step guide)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-other-git-stash-commands-like-list-apply-and-pop">Other git stash commands like list, apply, and pop</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-handle-multiple-stashes-in-your-project">How to handle multiple stashes in your project</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-real-use-cases-for-git-stash">Real use cases for git stash</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-why-do-we-stash">Why Do We Stash?</h2>
<p><a target="_blank" href="https://git-scm.com/book/en/v2/Getting-Started-What-is-Git%3F">Git</a> has provided us with the stash command, which makes our lives easier. The <code>git stash</code> command helps you save a draft of your current task, temporarily giving you time to attend to your new task without losing your progress on the previous task.</p>
<p>There are so many reasons why stashing is important. Here are some of them:</p>
<ul>
<li><p><strong>Resolving Conflicts within a Project</strong>: In a collaboration setting, you, as a developer, get to work with other developers on a particular project. A merge conflict might occur, which might require you to pause your current task to handle the conflict. You can easily stash your current task and focus fully on resolving the merge conflict without having to worry about losing your progress.</p>
</li>
<li><p><strong>Clean Working Environment</strong>: You might want to start up a new task or want to pull a repository into your working environment. With stashing, you can clear your current working environment temporarily, making your work environment clean and ready to perform another task.</p>
</li>
<li><p><strong>Switching branches</strong>: <code>Git stash</code> is very useful in this situation. You might be in the middle of something and it's not ready to be committed, but at that moment, you need to switch branches. With <code>git stash</code>, you can easily move to another branch and perform your other tasks.</p>
</li>
</ul>
<h2 id="heading-pros-and-cons-of-stashing">Pros and Cons of Stashing</h2>
<p>Here are some of the pros (advantages) of using stash:</p>
<ul>
<li><p>It’s easy to use and understand</p>
</li>
<li><p>It helps you save a draft of your current task and focus on another task.</p>
</li>
<li><p>It comes in handy when trying to resolve conflicts like merge conflicts, <code>git fork</code>, and so on when working with other collaborators in a project.</p>
</li>
<li><p>You can reapply your draft file not only on the branch you stashed it from but also on other branches.</p>
</li>
</ul>
<p>As the saying goes "Anything that has an advantage also has a disadvantage". Here are some of the cons (disadvantages) of using stash:</p>
<ul>
<li><p>Stashing can lead to a merge conflict: A merge conflict can occur when reapplying your stashed draft to a branch which already has similar content to the draft, and you’ll need to resolve this manually.</p>
</li>
<li><p>Cluster and Confusion: In a situation where you are working on a huge project with multiple sub-tasks, applying the stash command at various points might lead to a cluster of saved drafts. This can lead to confusion on the particular saved draft you would want to continue working on.</p>
</li>
</ul>
<p>Now that we have seen some of the pros and cons of using <code>git stash</code>, let’s look at how <code>git stash</code> works and how to apply it to our project.</p>
<h2 id="heading-how-git-stash-works">How Git Stash Works</h2>
<p>As we just discussed, <code>git stash</code> helps you save a draft of your current uncommitted changes. Now let's see how this happens using the analogy below.</p>
<p>When you run the <code>git stash</code> command, it puts your tracked file in a box and then removes/hides that box, making the environment/branch clean and free to use for another task. When you apply the stash command to the current branch you are working on, it saves a draft of all tracked files in that branch and reverts that branch to a clean slate.</p>
<p>To explain better, here’s an example:</p>
<p><img src="https://hackmd.io/_uploads/S1x5zSPhR.gif" alt="Image of How Git Stash Works" width="600" height="400" loading="lazy"></p>
<p>From the image above, we created a new project and already initialized <code>git</code> in it. We are currently on the "main" branch which is the default branch.</p>
<p>If we modify a file in the <code>main</code> branch and apply the <code>git stash</code> command, the modified file will be saved as a draft and your working environment will be reverted to the last commit you made (making it look like there was no modification in the first place).</p>
<p>Note: By default, you can only apply the stash command to tracked files in <code>git</code>.</p>
<h3 id="heading-how-to-create-a-stash">How to Create a Stash</h3>
<p>Here is how you can go about creating a stash in your project.</p>
<p>Create a file you want to work on, maybe an <code>index.html</code> file or a <code>style.css</code> file. Initialize <code>git</code> in your project by running the command <code>git init</code>. Add the file to the Git tracking stage by running <code>git add .</code> Then at this point, if you make any modifications and would like to come back later to complete it, you can run:</p>
<pre><code class="lang-bash">git stash
</code></pre>
<p>Here is a visual representation of the above process:</p>
<p><img src="https://hackmd.io/_uploads/HJg8cHDh0.gif" alt="Visual Representation of How to Create a stash" width="600" height="400" loading="lazy"></p>
<p>There are other stash commands you should know in order to control your stashed project. They include <a target="_blank" href="https://git-scm.com/docs/git-stash#Documentation/git-stash.txt-listltlog-optionsgt">List</a>, <a target="_blank" href="https://git-scm.com/docs/git-stash#Documentation/git-stash.txt-pop--index-q--quietltstashgt">Pop</a>, <a target="_blank" href="https://git-scm.com/docs/git-stash#Documentation/git-stash.txt-clear">Clear</a>, <a target="_blank" href="https://git-scm.com/docs/git-stash#Documentation/git-stash.txt-apply--index-q--quietltstashgt">Apply</a>, <a target="_blank" href="https://git-scm.com/docs/git-stash#Documentation/git-stash.txt-show-u--include-untracked--only-untrackedltdiff-optionsgtltstashgt">Show</a>, and a few others.</p>
<ul>
<li><p><strong>List</strong>: The list command is mainly used to display the number of stashes made in a particular project. Just like an array, the stashed draft is numbered from 0 upwards. To use this command, run <code>git stash list</code>. Note: The stash command is arranged in such a way that when a change is stashed, it takes up the first position i.e."stash@{0}" while the other changes are pushed down.</p>
</li>
<li><p><strong>Pop</strong>: This command is used to retrieve an already stashed draft back into your project. When you apply the pop command, it automatically retrieves the latest stashed draft back into your working project and removes it from the stash list. Run the following command to pop a stash: <code>git stash pop</code>.</p>
</li>
<li><p><strong>Clear</strong>: When applied, this command is used to remove/delete all the stash entries. It is important to note that, when you use the clear command, you can recover the cleared stash again. You can use it by running this command: <code>git stash clear</code>.</p>
</li>
<li><p><strong>Apply</strong>: This command works just like the pop command, but the only difference is that the stashed draft is not removed from the list after it has been retrieved. This means that when you use the apply command, it retrieves the latest stashed draft back into your project but doesn't remove it from the stash list. Run the following to use the apply command: <code>git stash apply</code>.</p>
</li>
<li><p><strong>Show</strong>: This command is important because it helps show you the changes you made in the stashed draft. Use the following command to show a stash: <code>git stash show</code>.</p>
</li>
</ul>
<h2 id="heading-how-to-handle-multiple-stashes-in-your-project">How to Handle Multiple Stashes in Your Project</h2>
<p>Knowing how to handle multiple stashes in your project is important, as there may be times when you have more than 3-4 stashed drafts in your project.</p>
<p>Here is how to handle multiple stashes:</p>
<h3 id="heading-step-one-customize-each-stash-with-a-specific-message">Step One: Customize each stash with a specific message</h3>
<p>This step is very important if you would like to avoid being confused in situations where you have multiple stashes.</p>
<p><img src="https://hackmd.io/_uploads/BkVtICNIA.png" alt="Multiple stashes with the Same messages" width="600" height="400" loading="lazy"></p>
<p>From the image above, we have a total of four stashes (that is, "stash@{0}" to "stash@{3)") and each stash bears the same message of "first commit". This might be confusing when we might want to pop or apply one of these stashes later in the future.</p>
<p>To sort this issue, all we have to do is assign a specific stash message to the next stash. We can do this by running the following command:</p>
<pre><code class="lang-bash">git stash save <span class="hljs-string">"New message/name goes here"</span>
</code></pre>
<p>Here is how it looks:</p>
<p><img src="https://hackmd.io/_uploads/HJH3IRNLA.png" alt="Multiple stashes with the different messages" width="600" height="400" loading="lazy"></p>
<p>From the image above, you can clearly see the difference between the two latest stashes (that is, "stash@{0}" and "stash@{1}") and the others. The first two stashes have their own specific message, which makes it very easy to differentiate them from the rest.</p>
<h3 id="heading-step-two-retrieve-a-specific-stash-instead-of-the-latest-stash">Step Two: Retrieve a specific stash instead of the latest stash</h3>
<p>There are situations when you might want to retrieve a specific stashed draft rather than the latest stashed draft you just made. You can do this by using either:</p>
<pre><code class="lang-bash">git stash pop stash@{n}
</code></pre>
<p>or</p>
<pre><code class="lang-bash">git stash apply stash@{n}
</code></pre>
<p>Where <code>n</code> indicates the stash ID you want to retrieve. This also works when you want to delete or clear a specific stashed draft.</p>
<h3 id="heading-step-three-preview-your-stashed-draft-before-you-retrieve-it">Step Three: Preview your stashed draft before you retrieve it.</h3>
<p>Before you restore a stashed draft, it is important to preview it to ensure that it's the exact draft you want to restore. The <code>show</code> command helps you review the changes in the draft before restoring it. To do this, run the following command:</p>
<pre><code class="lang-bash">git stash show stash@{n}
</code></pre>
<h2 id="heading-real-use-cases-for-git-stash">Real Use Cases for <code>git stash</code></h2>
<p>Here are some real-life case scenarios of when the git stash command is important.</p>
<ul>
<li><p><strong>During Debugging</strong>: This happens a lot when you are in a collaboration setting. Let's say you are working with extra two developers on a project and one of them happens to encounter an error that needs your urgent attention. Using the <code>git stash</code> command is ideal in this situation.</p>
</li>
<li><p><strong>When you are not ready to Commit</strong>: This occurs often. There are situations where you are not ready to commit your changes to the repository. Stashing those changes is the best next step.</p>
</li>
<li><p><strong>Returning the directory to its original state</strong>: Returning the directory to its original state simply means cleaning out all changes made to the directory and making it look as if nothing was done to it. The <code>git stash</code> command helps you achieve this.</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The <code>git stash</code> command effortlessly helps you manage your project properly whether you are working alone or you’re in a collaboration setting.</p>
<p>This tool is vital to every developer who wants to flow freely and effortlessly while working on a project.</p>
<p>At this point, I believe you know what <code>git stash</code> is all about, why it is important and how to make use of it in your project.</p>
<p>Thank you for reading.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ React Hooks – How to Use the useState & useEffect Hooks in Your Project ]]>
                </title>
                <description>
                    <![CDATA[ Hooks allow function components to have access to state and other React features, such as lifecycle methods. These Hook features were introduced to React version 16.8. One of the interesting things about the Hook features is that they let you use Rea... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-the-usestate-and-useeffect-hooks-in-your-project/</link>
                <guid isPermaLink="false">66d45e0c47a8245f78752a26</guid>
                
                    <category>
                        <![CDATA[ hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ react hooks ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Okoro Emmanuel Nzube ]]>
                </dc:creator>
                <pubDate>Fri, 08 Mar 2024 15:37:42 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/03/React-JS-Hooks.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Hooks allow function components to have access to state and other React features, such as lifecycle methods. These Hook features were introduced to React version 16.8.</p>
<p>One of the interesting things about the Hook features is that they let you use React without classes. This, in turn, helps simplify your codebase and helps you write cleaner and more intuitive code.</p>
<p>In this article, you will learn how to make use of the common Hooks in your project.</p>
<h2 id="heading-react-hooks-benefits">React Hooks Benefits</h2>
<p>Let's go over some of the reasons why you might want to use Hooks in your project:</p>
<ul>
<li><p><strong>Easy to use and understand:</strong> With Hooks, you can write more straightforward code. These Hook commands can only be written inside a functional component.</p>
</li>
<li><p><strong>Reusable code:</strong> Hooks allow you to reuse a particular logic used in one component across multiple other components.</p>
</li>
<li><p><strong>Better optimization performance:</strong> Hooks offer a more efficient approach to utilizing React functionalities like state and lifecycle functions, resulting in improved performance as compared to class components in some situations.</p>
</li>
</ul>
<h2 id="heading-different-types-of-react-hooks">Different Types of React Hooks</h2>
<p>The React Hook features are of different types, ranging from the <code>useState</code>, <code>useEffect</code>, <code>useRef</code>, <code>useReducer</code>, and so on.</p>
<h2 id="heading-react-hook-rules">React Hook Rules</h2>
<p>There are a few important rules when it comes to the React Hook features that should be strictly followed. Let's go over them in the following sections.</p>
<h3 id="heading-hooks-should-be-called-inside-a-react-function">Hooks should be called inside a React function</h3>
<p>Hooks should not be used inside a class component – they can and should only be called inside the React function.</p>
<p>This first rule essentially specifies that a Hook component should not be found in a class component, but in a functional component.</p>
<p>Here is the wrong way of implementing the Hook feature:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> React, {useState} <span class="hljs-keyword">from</span> react;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">App</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span> </span>{
 <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);

  render() {
    <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello, I am a Class Component!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>And here is the correct way of implementing the Hook feature:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [userName, setUsername] = useState(<span class="hljs-string">''</span>);

  };

  <span class="hljs-keyword">return</span> ( Your JSX code goes <span class="hljs-keyword">in</span> here.....);
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>The code example above shows a proper way of using a Hook feature.</p>
<p>If you use a Hook feature in a class component, just like in the first example, your code will raise an error. Therefore, you can only implement a Hook inside a function component.</p>
<h3 id="heading-hooks-can-only-be-called-at-the-top-level-of-a-component">Hooks can only be called at the top level of a component</h3>
<p>You can only implement/call a React Hook at the top level of a component before any other code.</p>
<p>Using the code from the previous section as an example, you can see that immediately after <code>function App ()</code>.</p>
<p>The next thing that comes is the Hook command – in that example we used the <code>useState</code> Hook. That is what the second rule is all about.</p>
<h3 id="heading-hooks-cannot-be-used-in-a-conditional-statement">Hooks cannot be used in a conditional statement</h3>
<p>We have different types of conditional statements/rendering ranging from <code>if</code>, <code>else</code>, and so on.</p>
<p>The above rule means that conditionals cannot be applied directly to Hooks. This is the case because Hooks are called in the same order on every render of a functional component.</p>
<p>You can conditionally run Hooks within a functional component, but for this to work, this condition must be determined by top-level logic and should not be nested within any other blocks or components.</p>
<p>The reason for this is because Hooks need to be invoked at the highest level of the component, rather than under conditions, loops, or nested functions.</p>
<p>Here is an example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ConditionalEffectComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [isMounted, setIsMounted] = useState(<span class="hljs-literal">false</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (isMounted) {
      <span class="hljs-comment">// Perform some effect when the component is mounted</span>
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Component mounted'</span>);
    }
  }, [isMounted]); <span class="hljs-comment">// Dependency array ensures effect runs when isMounted changes</span>

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setIsMounted(!isMounted)}&gt;
        {isMounted ? 'Unmount' : 'Mount'}
      <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> ConditionalEffectComponent;
</code></pre>
<p>From the example above, the <code>useEffect</code> hook is executed conditionally dependent on the value of the <code>isMounted</code> state variable.</p>
<p>Clicking the button causes the value of <code>isMounted</code> to alternate, either activating or deactivating the effect depending on the updated value.</p>
<p>This is deemed appropriate because the Hook is invoked at the highest level of the component and its condition is determined by the overarching logic within the component.</p>
<h2 id="heading-how-to-use-the-usestate-hook">How to Use the useState Hook</h2>
<p>The React <code>useState</code> Hook enables you to have state variables in functional components.</p>
<p>To make use of the state Hook, you must first import it into your project by using the <code>import</code> command.</p>
<p>The way <code>useState</code> works is that it gives us two variables. The first variable is known as the value of the state, and the second variable is a function used to update the state.</p>
<p>Here is an example of how to go about this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> <span class="hljs-string">'./App.css'</span>
<span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

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

    <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>); 

<span class="hljs-keyword">return</span> ( 
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>You clicked {count} times<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setCount(count + 1)}&gt; Click me
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    ); 
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>From the code example above, you can see that the state Hook was used in a functional component and not a class component.</p>
<p><code>count</code> and <code>setCount</code> are the two variables of the state Hook, where <code>count</code> is the current value of the state and <code>setCount</code> is used to update the value of the state. Therefore, whenever the button is clicked, <code>setCount</code> will update the value of the count.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/R1.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>How useState Hook works</em></p>
<h2 id="heading-how-to-use-the-useeffect-hook">How to Use the useEffect Hook</h2>
<p>The <code>useEffect</code> hook in React is like a handy tool for functional components. It helps manage tasks that aren't directly related to showing stuff on the screen, like fetching data from the internet, retrieving data from API endpoints, or setting up timers. It can be used to update components even after they've been shown, making your app more dynamic.</p>
<p>Here's a basic example of how <code>useEffect</code> is used to fetch data from an API endpoint:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [data, setData] = useState(<span class="hljs-literal">null</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> fetchData = <span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'https://api.example.com/data'</span>);
        <span class="hljs-keyword">const</span> jsonData = <span class="hljs-keyword">await</span> response.json();
        setData(jsonData);
      } <span class="hljs-keyword">catch</span> (error) {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error fetching data:'</span>, error);
      }
    };

    fetchData(); <span class="hljs-comment">// Call the fetchData function when the component mounts or updates</span>

    <span class="hljs-comment">// Cleanup function (optional) to handle unsubscriptions or resource cleanup</span>
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-comment">// Cleanup logic here, if needed</span>
    };
  }, []); <span class="hljs-comment">// Empty dependency array means the effect runs only once after the initial render</span>

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      {/* Render the fetched data */}
      {data &amp;&amp; (
        <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
          {data.map(item =&gt; (
            <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{item.id}</span>&gt;</span>{item.name}<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
          ))}
        <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
      )}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> MyComponent;
</code></pre>
<p>In the code example above, <code>MyComponent</code> is a functional component which utilizes React hooks, specifically <code>useState</code> and <code>useEffect</code>, to handle state management and execute side effects. The <code>useState</code> hook is used to initialize a state variable called <code>data</code>. This variable will store the data retrieved from an API endpoint.</p>
<p>The <code>useEffect</code> hook is used to request data from the API endpoint once the component initially renders. Within the <code>useEffect</code>, an asynchronous function <code>fetchData</code> is defined to fetch JSON data from the specified API endpoint using the fetch API.</p>
<p>If the data fetching is successful, the returned JSON data is saved in the data state variable using the <code>setData</code> function supplied by the <code>useState</code> hook.</p>
<p>The <code>useEffect</code> hook also optionally returns a cleaning function, which is currently empty but can be used for any necessary cleanup logic.</p>
<p>In the component's JSX, the fetched data is conditionally rendered. If the data is not null, a list <code>&lt;ul&gt;</code> is produced using items extracted from the data array using map.</p>
<p>Finally, the <code>MyComponent</code> function is exported as the default export from the module, allowing it to be imported and utilized in other sections.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>As a developer, React Hooks are a very useful and powerful tool for functional components that make your work easy.</p>
<p>I believe that at this point you now know what a React Hook is and how to use the most popular ones.</p>
<p>Thanks for reading, and happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Install React – A Step-by-Step Guide ]]>
                </title>
                <description>
                    <![CDATA[ React is an open-source JavaScript library that helps you build dynamic user interfaces (UIs). You can use it to build components that represent logically reusable parts of the UI. Because React is open source, anyone can access its source code, insp... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-install-react-a-step-by-step-guide/</link>
                <guid isPermaLink="false">66d45e043dce891ac3a967ce</guid>
                
                    <category>
                        <![CDATA[ beginners guide ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Okoro Emmanuel Nzube ]]>
                </dc:creator>
                <pubDate>Mon, 05 Feb 2024 12:43:22 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/02/solid-navy-blue-concrete-textured-wall.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>React is an open-source JavaScript library that helps you build dynamic user interfaces (UIs). You can use it to build components that represent logically reusable parts of the UI.</p>
<p>Because React is open source, anyone can access its source code, inspect it, modify it, and enhance it for their personal needs or app development requirements.</p>
<p>In this tutorial, you'll learn how to install React into your project.</p>
<h2 id="heading-how-to-install-react">How to Install React</h2>
<p>Now that you know what React is and why it's useful, you'll learn how to make use of this library in your project.</p>
<h3 id="heading-step-1-install-nodejs">Step 1: Install Node.js</h3>
<p>Before you start the React installation process, you must have Node.js installed on your computer. If you do not know what Node.js is all about, you can read more <a target="_blank" href="https://www.freecodecamp.org/news/what-is-node-js/">here</a>.</p>
<p>You have to install Node first because React.js is a JavaScript library, and Node.js is a JavaScript runtime environment that allows you to run JavaScript on the server side. So when you're writing React, you include JavaScript functions in your React project, and then Node.js helps run this JavaScript code on the web page.</p>
<p>Node.js has various versions. The recommended version is the latest stable version, as it contains major and significant changes. These changes includes bug fixes and security updates, compatibility with your project dependencies, and so on.</p>
<p>To install Node, navigate to the <a target="_blank" href="https://nodejs.org/en/">Node.js website</a>. On their webpage, you have the option to download either the recommended version or the current version, as seen in the image below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/Node.js.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Node.js web page interface</em></p>
<p>After you have downloaded the version of your choice, install it on your computer.</p>
<p>Once installation is complete, open your command prompt to confirm that Node has been successfully installed. Type in <code>node -v</code> in your command prompt, then click the enter button. This command should display the current version of Node installed on your computer.</p>
<p>Here is what it looks like:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/node-version-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Node version displayed in the command prompt</em></p>
<p>If your Node version is displayed like the above, congratulations! You have successfully installed Node.js on your computer.</p>
<h3 id="heading-step-2-install-react">Step 2: Install React</h3>
<p>Now you can go ahead and install React into your project. Let's go through the steps together.</p>
<p>First, we'll look at the "traditional" way of installing React, using create-react-app (CRA), so you're aware of that process. Then we'll see how to install it using the modern Vite build tool.</p>
<h4 id="heading-using-cra">Using CRA</h4>
<p>Still in your command prompt window, navigate to the directory that you want to use in creating your React project. To do this, type <code>cd [directory name]</code> then click enter.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/Screenshot-1_30_2024-9_53_23-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><code>cd documents</code> command to go to <code>documents</code> directory</p>
<p>As you can see in the image above, I am navigating to the <code>documents</code> directory, which is where I would like to create my React project.</p>
<p>In the <code>documents</code> directory (or wherever you're creating your project), create a folder that you will be using to create your React app. Type <code>mkdir [folder name]</code>then navigate to the newly created directory using <code>cd [newly created folder name]</code>.</p>
<p>In the newly created folder directory, type in <code>npx create-react-app [project name of your choice]</code>, and then wait until your React project is completely created. The final section should have the text in the image below displayed:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/React-project-2-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>React complete installation in the terminal</em></p>
<p>Lastly, open the React project in your code editor by typing in <code>code .</code> . Your code editor (if you are making use of VS code) should look like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/Welcome---reactproject---Visual-Studio-Code-1_30_2024-8_39_40-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>React Complete Installation Display Using CRA</em></p>
<p>In the above image, let's go over some of the elements you'll see there.</p>
<ul>
<li><p>The <code>node module</code> folder is a storage folder that holds your React package along with other packages that might be installed as you work on your React project. The <code>node module</code> helps configure the design system of your React project.</p>
</li>
<li><p>The <code>src</code> folder stores in all the files and components used in your react application ranging from the <code>App.js</code>, <code>index.js</code>, <code>App.css</code> just as seen in the image above.</p>
</li>
<li><p>The <code>package-lock.json</code> file locks the versions of dependencies your React project uses, and this helps in managing dependencies in your React project.</p>
</li>
</ul>
<p>Recently, create-react-app has become deprecated and the React team doesn't recommend using it anymore. Other modern tools provide a faster front-end development experience, and and you can use them to create React apps without stress. Such tools include Vite, Snowpack, Gatsby, Next.js, Percel, and so on.</p>
<p>In this section, you will learn how to use the Vite tool to install React into your project.</p>
<h4 id="heading-using-vite">Using Vite</h4>
<p>Vite is a very fast and customizable modern tool that aims to provide a linear development experience for modern web projects. You can use it to create your React apps in a fast and reliable way. It also has the same features as create-react-app (CRA).</p>
<p>Just as we did when installing React using CRA, the first step is to make sure you have Node installed on your computer. After that, navigate to the directory you want to use and create a new folder (with any name of your choice).</p>
<p>Open the newly created folder in your code editor (VS code).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/Vite_React---Visual-Studio-Code-2_2_2024-8_10_22-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Vite_React</em></p>
<p>The image above is what yours should look like. In my case, I named the folder I created <code>Vite_React</code>.</p>
<p>The next step is to open the terminal (located in between Run and Help), as seen in the image above.</p>
<p>Once in the terminal, run <code>npm create vite@latest [your project name]</code>. In my case the project named I used is <code>new-react-vite</code>. The above command should look like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/Vite_React---Visual-Studio-Code-2_2_2024-8_30_00-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Select Framework (React)</em></p>
<p>At this point, you are asked to select what framework you want to install, so since you are working on React, use your arrow keys to navigate to where we have React, then click on Enter.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/Vite_React---Visual-Studio-Code-2_2_2024-8_36_40-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Select language (Javascript)</em></p>
<p>From the image above, the next step is to select what language you want for your project. You can choose any language of your choice, but for the sake of this tutorial, I chose JavaScript.</p>
<p>The next step is to navigate to the project directory where you created the React project. To do this, type <code>cd [directory name]</code>. Yours should look like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/Vite_React---Visual-Studio-Code-2_2_2024-8_44_16-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>React Complete Installation Using Vite</em></p>
<p>Once you have done this, you should see that your React files has been created and displayed on the screen like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/Vite_React---Visual-Studio-Code-2_2_2024-8_49_58-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>React Installation Display</em></p>
<p>Last but not least, install the Node module folder by typing <code>npm install</code> in the terminal. This takes a little time to complete, but when installation is done, you should see the <code>node_module</code> folder at the top, like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/Vite_React---Visual-Studio-Code-2_2_2024-9_02_48-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Node Modules folder</em></p>
<p>Lastly, type <code>npm run dev</code> to run your project and display on the web page. If you followed the installation steps correctly, you should see your local host:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/vite.config.js---Vite_React---Visual-Studio-Code-2_2_2024-9_11_55-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Local host</em></p>
<p>Hold your control button and click on your local host. This takes you to the web page. At this point, if your web page is displayed like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/Vite---React---Google-Chrome-2_2_2024-9_16_47-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Final React Display on the web page</em></p>
<p>Congratulations on installing React on your project!</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The React library is a powerful open-source JavaScript tool you can use to create dynamic and appealing applications. It is actually a fun framework to get your hands on, so I recommend trying it out.</p>
<p>I believe at this point you can fully install React into your project with the modern tool (like Vite). If you've done it, congratulations again!</p>
<p>Happy Coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Basic Git Commands – How to Use Git in a Real Project ]]>
                </title>
                <description>
                    <![CDATA[ In my previous tutorial we talked about what version control is, how Git and GitHub work, and how to setup an account with GitHub. Today we will be looking at how to use some basic Git commands in a real project. I created a simple project that we'll... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-basic-git-and-github-commands/</link>
                <guid isPermaLink="false">66d45e08f855545810e9341d</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ version control ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Okoro Emmanuel Nzube ]]>
                </dc:creator>
                <pubDate>Wed, 20 Jul 2022 16:39:48 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/07/git-and-github.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In my <a target="_blank" href="https://www.freecodecamp.org/news/git-and-github-the-basics/">previous tutorial</a> we talked about what version control is, how Git and GitHub work, and how to setup an account with GitHub.</p>
<p>Today we will be looking at how to use some basic Git commands in a real project.</p>
<p>I created a simple project that we'll be using in this tutorial.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/Document---Google-Chrome-7_18_2022-6_54_37-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Project interface</em></p>
<p>By going through this tutorial, you'll learn how to:</p>
<ul>
<li><p>Create a repository in GitHub</p>
</li>
<li><p>Initialize Git in your project</p>
</li>
<li><p>Add and commit your project</p>
</li>
<li><p>Push your project to GitHub</p>
</li>
<li><p>Add and remove a file from a repository</p>
</li>
</ul>
<h2 id="heading-how-to-create-a-repository-in-github">How to Create a Repository in Github</h2>
<p>I built the sample project above using HTML and CSS. To initialize Git to the project, I will have to create a new repository in my GitHub account.</p>
<p>I can do this by logging into my account, then clicking on the <code>new</code> button located at the top right of the screen. When it opens, I will input my repository name, the description, then choose if I want my project to be accessed publicly or privately. Then I'll click on "Create repository."</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/Create-a-New-Repository---Google-Chrome-7_18_2022-7_43_32-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-initialize-git">How to Initialize Git</h2>
<p>We can't make use of Git in our project if we do not initialize/start it first with the <code>git init</code> command.</p>
<p>So after creating the repository in GitHub, I'll open the project in my VS Code editor, go to my terminal, and then use the <code>git init</code> command to initialize/start.</p>
<p>When you run this command in your terminal, you will notice some changes in color in your project. You will also see a <code>U</code> symbol which means your files are untracked.</p>
<p>Also, when you open the folder where your project is stored/located, you will see another folder named <code>.git</code> which was automatically created when you ran the <code>git init</code> command.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/git-add.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>git add</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/bandicam-2022-07-18-02-40-08-007.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>.git folder</em></p>
<h2 id="heading-how-to-add-and-commit-your-project">How to Add and Commit your Project</h2>
<h3 id="heading-how-to-use-the-git-add-command">How to use the <code>git add</code> command</h3>
<p>Adding the project to the staging area helps Git track your project and see changes you have made to it.</p>
<p>To add your project to the staging area, run the <code>git add .</code> command. When you run this command, you will see that the <code>U</code> symbol automatically changes to <code>A</code>. This means that your files have been added to the staging area and are now being tracked by Git, waiting to be committed.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/git-add-1.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>git add</em></p>
<h3 id="heading-how-to-use-the-git-commit-command">How to use the <code>git commit</code> command</h3>
<p>By running the <code>git commit</code> command, you are saving this particular stage and t he changes to your project permanently in the Git repository. And although you might make few changes to the project in the future and commit them as well, this particular commit you made now will still be saved in the Git repository and can be accessed anytime.</p>
<p>So after your project has been added to the staging area, the next thing you'll want to do is commit it by using the <code>git commit –m “first commit”</code> command.</p>
<p>When you run this command, you should notice that the <code>A</code> symbol in the project in no longer there, and the project looks as you'd expect once again.</p>
<h2 id="heading-how-to-push-your-project-to-github">How to Push your Project to GitHub</h2>
<p>Pushing your project to Github helps prevent your project from getting corrupted/lost in the local storage. It also lets you access the GitHub repository freely from anyplace, with any computer (not necessarily your personal computer).</p>
<p>To be able to push your project to the GitHub repository, you will have to add the remote repository you created in GitHub initially.</p>
<p>To do this, you will use the <code>git remote add origin (repository name)</code> command. In my case my repository name is <a target="_blank" href="https://github.com/Derekvibe/FoodResturant.git"><code>https://github.com/Derekvibe/FoodResturant.git</code></a>. Writing it in the terminal should look like this:</p>
<p><code>git remote add origin [https://github.com/Derekvibe/FoodResturant.git](https://github.com/Derekvibe/FoodResturant.git)</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/bandicam-2022-07-19-20-32-00-790.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If you're are not sure of the current branch you're working on, use the <code>git branch</code> command. If it displays the branch as <code>master</code>, we will change it to the <code>main</code> branch by running the <code>git branch –M main</code> command.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/git-branch.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>(my git branch)</em></p>
<p>In my case I had already configured my default branch to be <code>branch main</code> when I installed Git on my computer by running the <code>git config –global init.default branch main</code> command. So I don’t need to run the <code>git branch –M main</code> command again.</p>
<p>Finally, after adding the remote repository where you want to upload the project and changing the branch to <code>main</code>, you'll want to push your project to GitHub.</p>
<p>To achieve this, run the <code>git push –u origin main</code> command and wait for it to load completely.</p>
<p>When this is done, go to the Git repository you created in GitHub and refresh the page. You will see that all your projects in the local repository have been uploaded to the GitHub repository.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/git-push-image.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>From this point forward, after making changes to the project, you just have to add the changes to the staging area by running the <code>git add .</code> command. Then you can commit it using <code>git commit –m “(commit name)”</code> and push it to the Git repository by using the <code>git push –u origin main</code>.</p>
<h2 id="heading-how-to-add-and-remove-a-file-from-a-repository">How to Add and Remove a File from a Repository</h2>
<p>At this point I will be showing you how to add and remove a new file to a GitHub repository.</p>
<h3 id="heading-how-to-add-a-new-file-to-an-existing-repository">How to add a new file to an existing repository</h3>
<p>Just to recap: I added a new file to my project with the name <code>newfile.txt</code>. I added it to the staging area by running <code>git add newfile.txt</code>, then committed it using <code>git commit –m “new commit”</code> and pushed it to GitHub just like we did when we wanted to upload the entire project to GitHub.</p>
<p>When I refreshed my GitHub page, I should see the new file which I created being displayed.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/bandicam-2022-07-18-07-14-54-352-1.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-how-to-remove-a-file-from-an-existing-repository">How to remove a file from an existing repository</h3>
<p>If I want to delete/remove the file I just created from my project in GitHub, I can do this by running the <code>git rm newfile.txt</code> command in the terminal.</p>
<p>When I run this command in my terminal, I will add the changes to the staging area using the <code>git add .</code>, and then commit and push the changes to the GitHub repository.</p>
<p>When I refresh my GitHub page, the file will be removed from my GitHub repository. Also, when I go to my local storage, the file should be deleted from there as well.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/bandicam-2022-07-18-07-02-35-474.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/bandicam-2022-07-18-07-10-12-196.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this tutorial, you learned how to use the basic Git commands to manage your projects.</p>
<p><a target="_blank" href="https://github.com/Derekvibe/FoodResturant">Click here</a> to access my GitHub repository for this project so you can try it out on your own.</p>
<p>Hope this tutorial was helpful to you.</p>
<p><strong>Have fun coding!</strong></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Git and GitHub – Version Control Basics for Beginners ]]>
                </title>
                <description>
                    <![CDATA[ A Version Control System is a tool you use to track, make, and manage changes to your software code. It's also called source control. A version control system helps developers store every change they make to a file at different stages so they and the... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/git-and-github-the-basics/</link>
                <guid isPermaLink="false">66d45e00868774922c884fdc</guid>
                
                    <category>
                        <![CDATA[ beginner ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ version control ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Okoro Emmanuel Nzube ]]>
                </dc:creator>
                <pubDate>Tue, 12 Jul 2022 16:55:20 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/07/git-github.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>A Version Control System is a tool you use to track, make, and manage changes to your software code. It's also called source control.</p>
<p>A version control system helps developers store every change they make to a file at different stages so they and their teammates can retrieve those changes at a later time.</p>
<p>There are three types of version control systems, which are:</p>
<ul>
<li><p>Local Version Control Systems</p>
</li>
<li><p>Centralized Version Control Systems</p>
</li>
<li><p>Distributed Version Control Systems.</p>
</li>
</ul>
<h2 id="heading-what-is-a-local-version-control-system-lvcs">What is a Local Version Control System (LVCS)?</h2>
<p>This is a type of version control system that is very common and simple to use. But this method is quite prone to errors and attacks because the files are being stored in your local system.</p>
<p>This means that you might lose the system file or accidentally forget the directory/folder of the file you are working (and then write in another directory).</p>
<h2 id="heading-what-is-a-centralized-version-control-system-cvcs">What is a Centralized Version Control System (CVCS)?</h2>
<p>In this type of version control, a server act as a repository that stores each version of the code. The CVCS helps different developers collaborate together.</p>
<p>Despite the helpful collaboration and communication between developers, if a server goes down for few seconds or gets corrupted, there's the chance you'll lose your work. Unfortunately, this is a very big problem with the CVCS.</p>
<p>In CVCS, only a few developers can work together on a project.</p>
<h2 id="heading-what-is-a-distributed-version-control-system-dvcs">What is a Distributed Version Control System (DVCS)?</h2>
<p>This is the latest and most commonly used type of version control system these days.</p>
<p>In a DVCS all developers have a full back up (clone) of all the data in the server. This means that whenever the server is down or faulty, you can still work on your project and you can copy or back up your repositories to the server to restore them.</p>
<p>When you're using a DVCS, many developers can work together on a project. One popular DVCS is Git, which we'll talk about more now.</p>
<h2 id="heading-what-is-git">What is Git?</h2>
<p>Git is a free open source distributed version control system you can use to track changes in your files. You can work on all types of projects in Git, from small to large.</p>
<p>With Git, you can add changes to your code and then commit them (or save them) when you're ready. This means you can also go back to changes you made before.</p>
<p>Git works hand in hand with GitHub – so what is GitHub?</p>
<h2 id="heading-what-is-github">What is GitHub?</h2>
<p>GitHub is a web interface where you store your Git repositories and track and manage your changes effectively. It gives access to the code to various developers working on the same project. You can make your own changes to a project at the same time as other developers are making theirs.</p>
<p>If you accidentally mess up some code in your project while making changes, you can easily go back to the previous stage where the mess has not occurred yet.</p>
<h2 id="heading-why-use-github">Why use GitHub</h2>
<p>There are so many reasons you should learn and use GitHub. Let's look at a few of them now.</p>
<h3 id="heading-effective-project-management">Effective Project Management</h3>
<p>GitHub is a place where your Git repositories are stored. GitHub makes it easy for developers working on the same project but in different locations to be on the same page.</p>
<p>With GitHub, you can easily track and manage the changes you have made and check on the progress you've made in your project.</p>
<h3 id="heading-easy-collaboration-and-cooperation">Easy Collaboration and Cooperation</h3>
<p>With GitHub, developers from all over the world can work together on a project without having any problems.</p>
<p>Teams are able to stay on the same page while working on a project together and can easily organize and manage the project effectively.</p>
<h3 id="heading-open-source">Open Source</h3>
<p>GitHub is a free and open source system. This means that developers can easily access different types of code/projects which they can use in learning and developing their skills.</p>
<h3 id="heading-versatility">Versatility</h3>
<p>This attribute of GitHub is very important. GitHub is not a web interface for only developers. It can be used by designers, writers, and anyone who wants to keep track of the history of their projects.</p>
<h2 id="heading-how-to-setup-git">How to Setup Git</h2>
<p>To start using Git, you'll need to download it to your computer if you haven't already. You can do this by going to their official <a target="_blank" href="https://git-scm.com/">website</a>.</p>
<p>When Git opens, scroll down a bit and you should see a download button. Go ahead and click on it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/bandicam-2022-07-05-20-23-44-196-1.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Download button on the Git website</em></p>
<p>Choose your operating system whether it's Windows, MacOS, Linux/Unix. In my case, I will be choosing the Windows option because I am using a Windows computer:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/bandicam-2022-07-05-20-24-33-919.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Choose your operating see you system</em></p>
<p>Click on the first link at the very top of the page to download the latest version of Git.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/bandicam-2022-07-05-20-25-06-107.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Download the latest version of Git by clicking the first link</em></p>
<p>When the download is complete, then go ahead and install Git to your computer. You'll need to go to the location where the file has been downloaded and install it.</p>
<p>After the installation, you'll want to make sure that Git is successfully installed on your system. Open your command prompt or Git bash (whichever one you choose to use) and run the command:</p>
<p><code>git --version</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/bandicam-2022-07-05-20-48-13-907.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If Git was successfully installed on your computer, it should display the current version of Git below the command you just ran. If the current version is being displayed, congratulations!</p>
<h2 id="heading-how-to-configure-git">How to Configure Git</h2>
<p>Now that we have installed Git on our computer, we have to configure it. We do this so that any time we are working in a team on a project, we can easily identify the commits we have made in the repository.</p>
<p>To configure Git, we need to specify the name, email address, and branch by using the <code>git config --global</code> command. For example:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/MINGW64__c_Users_me-7_7_2022-2_38_36-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>From the image above, we used <code>git config --global user.name</code> to configure the username. In my case I used my name <code>“Derek Emmanuel”</code>. The same applies for the <code>git config --global user.email</code>.</p>
<p>Git comes with a default branch of master, so I changed it to be called the main branch by using the <code>git config --global init.default branch main</code> command.</p>
<p>Now you're ready to start using Git.</p>
<h2 id="heading-how-to-setup-a-github-account">How to Setup a GitHub Account</h2>
<p>To set up a GitHub account, visit their <a target="_blank" href="https://github.com/">official website</a>. Click on the sign up button in the upper right corner:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/bandicam-2022-07-05-20-27-35-732.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>When the sign up form opens up, enter your email, create a password, enter your username, and then verify your account before clicking on the create account button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/07/bandicam-2022-07-05-20-35-26-646.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Create your GitHub account</em></p>
<h2 id="heading-commonly-used-git-commands">Commonly Used Git Commands</h2>
<p>There are some basic Git commands that every developer should know how to use:</p>
<ul>
<li><p><code>git config</code></p>
</li>
<li><p><code>git init</code></p>
</li>
<li><p><code>git add</code></p>
</li>
<li><p><code>git commit</code></p>
</li>
<li><p><code>git clone</code></p>
</li>
<li><p><code>git push</code></p>
</li>
<li><p><code>git rm</code></p>
</li>
<li><p><code>git branch</code></p>
</li>
</ul>
<p>Let's go through each of these briefly so you know how to use them.</p>
<h3 id="heading-how-to-use-the-git-config-command">How to Use the <code>git config</code> Command</h3>
<p>You use this command to set the username, email, and branch of a user so as to identify who made a commit when working on a project. This command is used when you have downloaded git into your computer and you want to customize it for your use.</p>
<p>For example:</p>
<p><code>git config --global user.name “ [username]”</code></p>
<p><code>git config --global user.email [email address]</code></p>
<h3 id="heading-how-to-use-the-git-init-command">How to Use the <code>git init</code> Command</h3>
<p>You use the <code>git init</code> command to start Git in your project. This git command is used when you are working on a project and would like to initialize git to the project in order to keep track of the changes made in the project.</p>
<p>For example:</p>
<p><code>git init</code></p>
<p>When you run this command, you should see a folder named <code>.git</code> being created automatically in the current folder you are working on.</p>
<h3 id="heading-how-to-use-the-git-add-command">How to Use the <code>git add</code> Command</h3>
<p>This command adds your file to the staging area. The staging area is the area where files we make changes to are added and where they wait for the next commit.</p>
<p>To add a file to the staging area, you use the <code>git add</code> command. It adds all the files in the folder to the staging area.</p>
<p><code>git add (file name)</code> adds the name of the particular file you want to commit in the staging area.</p>
<p>Use this command when you have made changes to a file and want to commit them to your project.</p>
<h3 id="heading-how-to-use-the-git-commit-command">How to Use the <code>git commit</code> Command</h3>
<p>This commits any file you added with the <code>git add</code> command as well as every file in the staging area.</p>
<p>For example:</p>
<p><code>git commit –m “first commit”</code></p>
<p>This command saves a file permanently to the Git repository. You use it whenever a file has been added to the staging area using the <code>git add</code> command.</p>
<h3 id="heading-how-to-use-the-git-clone-command">How to Use the <code>git clone</code> Command</h3>
<p>You use the <code>git clone</code> command to copy an existing repository in another location to the current location where you want it to be.</p>
<p>For example:</p>
<p><code>git clone (repository name)</code></p>
<p>You use this command when you want to duplicate a Git repository from GitHub into your local storage.</p>
<h3 id="heading-how-to-use-the-git-push-command">How to Use the <code>git push</code> Command</h3>
<p>You use this command to upload/push files from the local repository/storage to another storage, like a remote storage such as GitHub.</p>
<p>For example:</p>
<p><code>git push (remote storage name)</code></p>
<p>You only use this command when you're satisfied with the changes and commits you've made on a project and finally want to upload/push it to the Git repository in GitHub.</p>
<h3 id="heading-how-to-use-the-git-rm-command">How to Use the <code>git rm</code> Command</h3>
<p>You use this Git command to remove a file from a working repository. For example:</p>
<p><code>git rm (filename)</code></p>
<p>You use this command only when you wish to get rid of an unwanted changes/files from the Git repository.</p>
<h3 id="heading-how-to-use-the-git-branch-command">How to Use the <code>git branch</code> Command</h3>
<p>You use this command to check the current branch you are working on, either <code>main</code> or <code>master</code>. For example:</p>
<p><code>git branch</code></p>
<p>This command helps you know the current branch you are working on.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this tutorial you learned what version control systems are all about. You also learned how to install and setup Git on your computer and setup a GitHub account. Lastly, we went through some commonly used Git commands.</p>
<p>If you want to dive more deeply into Git and GitHub, you can c<a target="_blank" href="https://www.freecodecamp.org/news/git-and-github-crash-course/">heck out this course on the freeCodeCamp YouTube channel</a>.</p>
<p>Hope this tutorial was helpful to you.</p>
<p>Have fun coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ PHP Array – How to Use Arrays in Your PHP Projects ]]>
                </title>
                <description>
                    <![CDATA[ An array is a special variable that we use to store or hold more than one value in a single variable without having to create more variables to store those values. To create an array in PHP, we use the array function array( ). By default, an array of... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-arrays-in-php/</link>
                <guid isPermaLink="false">66d45e06680e33282da25e55</guid>
                
                    <category>
                        <![CDATA[ arrays ]]>
                    </category>
                
                    <category>
                        <![CDATA[ PHP ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Okoro Emmanuel Nzube ]]>
                </dc:creator>
                <pubDate>Wed, 22 Jun 2022 17:30:59 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/06/Arrays-in-PHP-final.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>An array is a special variable that we use to store or hold more than one value in a single variable without having to create more variables to store those values.</p>
<p>To create an array in PHP, we use the array function <code>array( )</code>.</p>
<p>By default, an array of any variable starts with the <code>0</code> index. So whenever you want to call the first value of an array you start with <code>0</code> then the next is <code>1</code>...and so on.</p>
<p>There are different types of arrays in PHP. They are:</p>
<ul>
<li><p>Numeric/Indexed Arrays</p>
</li>
<li><p>Associative Arrays</p>
</li>
<li><p>Multidimensional Arrays</p>
</li>
</ul>
<p>Let's look at how each one works in more detail.</p>
<h2 id="heading-what-are-numerical-or-indexed-arrays">What are Numerical or Indexed Arrays?</h2>
<p>A numerical array is a type of array which can store strings, numbers, and objects. Here's an example of a numeric array:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
<span class="hljs-comment">// Numeric/ index arrays</span>
$cars = <span class="hljs-keyword">array</span>(<span class="hljs-string">'Mecedes Benz'</span>, <span class="hljs-string">'Hilux'</span>, <span class="hljs-string">'Highlander'</span>, <span class="hljs-string">'Hummer'</span>, <span class="hljs-string">'Limozien'</span>);
var_dump($cars);
<span class="hljs-meta">?&gt;</span>
</code></pre>
<p>From the code above I have a variable of <code>$cars</code> which stores an array of 5 elements. The <code>var_dump($cars)</code> keyword above will show us the total number of elements we have in the array, the index number of each array, and also the length of each element in the array.</p>
<p>You can also chose to use the <code>echo( )</code> keyword, but in my case I prefer to use <code>var_dump( )</code> because it gives a more detailed explanation of the results we get.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/06/localhost_CODE_Arrays_arrays.php---Google-Chrome-6_15_2022-8_44_07-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can also choose to display only one element/item of an array in the web browser by doing this:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
$numbers = <span class="hljs-keyword">array</span>(<span class="hljs-string">'8'</span>, <span class="hljs-string">'20'</span>, <span class="hljs-string">'40'</span>, <span class="hljs-string">'58'</span>, <span class="hljs-string">'88'</span>, <span class="hljs-string">'200'</span>, <span class="hljs-string">'400'</span>, <span class="hljs-string">'500'</span>);
var_dump ($numbers [<span class="hljs-number">4</span>]);
<span class="hljs-meta">?&gt;</span>
</code></pre>
<p>The code above follows the same pattern as our definition of an array, which states that it counts from zero. We want to display the element with the index of <code>4</code>. Counting from <code>0 to 4</code>, we can see that <code>88</code> falls under index <code>4</code>, indicating that <code>88</code> is the number we're seeking and that will be displayed to the browser.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/06/localhost_CODE_Arrays_arrays.php---Google-Chrome-6_17_2022-8_17_58-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-what-are-associative-arrays">What are Associative Arrays?</h2>
<p>An associative array is a type of array where the key has its own value. In an associative array, we make use of <code>key</code> and <code>value</code>.</p>
<p><code>Key</code>s are descriptive captions of the array element used to access the value of the array. And <code>value</code> is the value assigned to the array element.</p>
<p>There are situations where you shouldn't use the numeric/indexed array, such as:</p>
<ul>
<li><p>When you want to store the age of different students along with their names.</p>
</li>
<li><p>When you want to record the salaries of your employees.</p>
</li>
<li><p>When you want to store the score of a student in different subjects</p>
</li>
</ul>
<p>and so on.</p>
<p>Suppose we want to assign ages to a group of high school students with their names.</p>
<p>We can use the Associative array method to get it done. For example:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
$student_age = <span class="hljs-keyword">array</span> (
<span class="hljs-string">'Scott_Mcall'</span> =&gt; <span class="hljs-number">17</span>,
<span class="hljs-string">'Stalenski'</span> =&gt; <span class="hljs-number">18</span>,
<span class="hljs-string">'Lydia'</span> =&gt; <span class="hljs-number">16</span>,
<span class="hljs-string">'Allision'</span> =&gt; <span class="hljs-number">17</span>,
);

<span class="hljs-keyword">echo</span> $student_age [<span class="hljs-string">'Scott_Mcall'</span>]; <span class="hljs-comment">//this code will display the age of Scot_Mcall as 17</span>
<span class="hljs-keyword">echo</span> $student_age [<span class="hljs-string">'Stalenski'</span>]; <span class="hljs-comment">//this code will display the age of stalenski as 18</span>
<span class="hljs-keyword">echo</span> $student_age [<span class="hljs-string">'Lydia'</span>]; <span class="hljs-comment">//this code will display the age of Lydia as 16</span>
<span class="hljs-keyword">echo</span> $student_age [<span class="hljs-string">'Allision'</span>]; <span class="hljs-comment">//this code will display the age of Allision as 17</span>
<span class="hljs-meta">?&gt;</span>
</code></pre>
<p>The code above is an example of an associative array. The <code>key</code>s of the array are <code>scott_Mcall</code>, <code>Stalenski</code>, <code>Lydia</code>, <code>Allision</code>, and we used them to assign the age to each student. The <code>value</code>s of the array are <code>17</code>, <code>18</code>, <code>16</code>, and <code>17</code>.</p>
<h2 id="heading-what-are-multidimensional-arrays">What are Multidimensional Arrays?</h2>
<p>You can think of a multidimensional array as an array of arrays. This means that every element in the array holds a sub-array within it. In general, multidimensional arrays allow you to store multiple arrays in a single variable.</p>
<p>Suppose we want to store the Names, Registration Numbers, and Emails of some of the staff working in a particular company. We can use multidimensional arrays to archive this.</p>
<p>For example:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
$Staffs = [
    [
        <span class="hljs-string">'Name'</span> =&gt; <span class="hljs-string">'Derek Emmanuel'</span>,
        <span class="hljs-string">'Reg_No'</span> =&gt; <span class="hljs-string">'FE/30304'</span>,
        <span class="hljs-string">'Email'</span> =&gt; <span class="hljs-string">'derekemmanuel@gmail.com'</span>
    ],
    [
        <span class="hljs-string">'Name'</span> =&gt; <span class="hljs-string">'Rubecca Michealson'</span>,
        <span class="hljs-string">'Reg_No'</span> =&gt; <span class="hljs-string">'FE/20003'</span>,
        <span class="hljs-string">'Email'</span> =&gt; <span class="hljs-string">'rmichealsongmail.com'</span>
    ],
    [
        <span class="hljs-string">'Name'</span> =&gt; <span class="hljs-string">'Frank Castle'</span>,
        <span class="hljs-string">'Reg_No'</span> =&gt; <span class="hljs-string">'FE/10002'</span>,
        <span class="hljs-string">'Email'</span> =&gt; <span class="hljs-string">'fcastle86@gmail.com'</span>
    ]
];
<span class="hljs-keyword">echo</span> $Staffs [<span class="hljs-number">2</span>] [<span class="hljs-string">'Email'</span>]; <span class="hljs-comment">// This displays the email of the last staff which is fcastle86@gmail.com</span>

<span class="hljs-keyword">echo</span> $staffs [<span class="hljs-number">0</span>] [<span class="hljs-string">'Name'</span>]; <span class="hljs-comment">//This displays the Name of the staff in the first array (index 0) which is Derek Emmanuel </span>

<span class="hljs-comment">// you can access the information of any staff you wish to by using echo $(variable name) [index number] ['array element key'].</span>


<span class="hljs-meta">?&gt;</span>
</code></pre>
<p>Remember, an array starts counting from index <code>0</code>. The code above is an example of a multidimensional array because it contains more than one array (an array of arrays) with one single variable of <code>$staff</code>.</p>
<p>The <code>echo $staff [2] [‘Email’]</code> displays the email of the staff that falls into the index of <code>2</code>. In our case it will display <a target="_blank" href="mailto:fcastle86@gmail.com"><code>fcastle86@gmail.com</code></a>.</p>
<p>If I want to access the Email of the staff in the first array, we'll do the following:</p>
<p><code>echo $staff [0] ['Email'];</code></p>
<p>Using the method above, you can access and display any information in the array from the code above.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>At this point you should be able to use the three different types of arrays when working on a PHP project.</p>
<p>Thank you for reading.</p>
<p>Have fun coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn PHP Syntax, Comments, Variables and Data Types – with Examples ]]>
                </title>
                <description>
                    <![CDATA[ Welcome to today's tutorial, everyone. In my last article, I walked you through what PHP is and how to get it set up along with XAMPP. And today, we'll review those introductory PHP concepts and then dive into the language a bit more in depth. We'll ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/php-syntax-comments-variables-data-types-with-examples/</link>
                <guid isPermaLink="false">66d45e0d7df3a1f32ee7f809</guid>
                
                    <category>
                        <![CDATA[ PHP ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Okoro Emmanuel Nzube ]]>
                </dc:creator>
                <pubDate>Fri, 10 Jun 2022 20:18:35 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/06/PHP--SYNTAX--COMMENTS-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Welcome to today's tutorial, everyone. <a target="_blank" href="https://www.freecodecamp.org/news/how-to-get-started-with-php/">In my last article</a>, I walked you through what PHP is and how to get it set up along with XAMPP.</p>
<p>And today, we'll review those introductory PHP concepts and then dive into the language a bit more in depth. We'll look at PHP syntax, comments, data types, and variables, among other things.</p>
<h2 id="heading-php-setup">PHP Setup</h2>
<p>Here's a quick rundown of how to get PHP up and running in your project.</p>
<p>Go to the <a target="_blank" href="https://www.php.net/">PHP website</a>, click on download in the navigation bar at the top, scroll down to where you see Windows Downloads, and click on it.</p>
<p>When you click on Windows Download, a new page should show up. Just scroll down until you see VS16 x64 Thread Safe (2022-Jun-07 22:31:20), then click on the zip file to download PHP.</p>
<p>When the download is finished, go to the downloads folder in your computer, extract the PHP folder from the zip file, open the extracted PHP folder, right-click php.exe, and choose run as administrator.</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/how-to-get-started-with-php/">You can read more here</a> for a detailed description of how to set up PHP for your code.</p>
<h2 id="heading-php-syntax">PHP Syntax</h2>
<p>You can embed PHP code anywhere in a document. It starts with an opening tag of <code>&lt;?php (the PHP code goes in here)</code> and ends with a closing tag <code>?&gt;</code>.</p>
<p>All PHP statements end with a semicolon <code>;</code>. A PHP file is always named with the file extension of <code>.php</code> – for example, <code>index.php</code> or <code>home.php</code>.</p>
<p>PHP code usually contains HTML code inside, for example:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
    <span class="hljs-keyword">echo</span> “ &lt;h1&gt; GOOD BYE WORLD, SEE YOU NEXT TIME &lt;/h1&gt;”;
    <span class="hljs-keyword">echo</span> “&lt;p&gt; This is me leaving the website at this point in the day &lt;/p&gt;”;
<span class="hljs-meta">?&gt;</span>
</code></pre>
<p>From the code above, it we can see that our PHP code contains two lines of HTML code in it – the <code>h1</code> tag and the <code>p</code> tag. The <code>h1</code> tag (heading 1) will be displayed in a very big and bold format, while the <code>p</code> tag (paragraphs) will be displayed in the browser normally. Note that all the code above ended with a semi-colon <code>;</code>.</p>
<h2 id="heading-comments-in-php">Comments in PHP</h2>
<p>As a developer, comments are crucial. Adding comments to your code makes it easier to read and understand.</p>
<p>In some cases, you may need to return to code that you wrote previously, but you'll struggle to solve the problem if you didn't explain what you were doing with comments.</p>
<p>When you comment something out, it won't show up in the web browser. In PHP, you can write single line comments and multiple line comments.</p>
<h3 id="heading-how-to-write-single-line-comments-in-php">How to Write Single-Line Comments in PHP</h3>
<p>Just as the name states, a single line comment just comments out everything in one line. You can use the forward slash (<code>/</code>) or hash symbol (<code>#</code>) in PHP to denote a single line comment. For example:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
<span class="hljs-comment">//This is a PHP Heading 1 </span>
<span class="hljs-keyword">echo</span><span class="hljs-string">"&lt;h1&gt; PHP Heading 1&lt;/h1&gt;"</span>;

<span class="hljs-comment">#This is a PHP Heading 2</span>
<span class="hljs-keyword">echo</span><span class="hljs-string">"&lt;h1&gt; PHP Heading 2&lt;/h1&gt;"</span>;
<span class="hljs-meta">?&gt;</span>
</code></pre>
<p>The code above shows the two ways to execute a single line comment in PHP.</p>
<h3 id="heading-how-to-write-multiple-line-comments-in-php">How to Write Multiple-Line Comments in PHP</h3>
<p>This comments everything in multiple lines. You can use the symbol <code>/* (the comment goes in-between) */</code> to include a multi-line comment.</p>
<p>When you comment out multiple lines of code, it will not be displayed in the web browser. For example:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
    <span class="hljs-comment">/*This is a PHP Heading
    the h1 tag displays text very bold and big, and the p tag below is the paragraph tag and will be displayed below the heading.
    */</span>
    <span class="hljs-keyword">echo</span><span class="hljs-string">"&lt;h1&gt; PHP Heading&lt;/h1&gt;"</span>;
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"&lt;p&gt; This is the paragraph &lt;/p&gt;"</span>;
<span class="hljs-meta">?&gt;</span>
</code></pre>
<p>The multiple line comment that you can see in the code above can be said to have two tags: one is the opening tag which is <code>/*</code> and the other is the closing tag <code>*/</code>. Your comment text/code goes in-between the two tags.</p>
<h2 id="heading-variables-in-php">Variables in PHP</h2>
<p>A variable is a container that stores or houses data or values. In PHP, you create a variable with the dollar symbol <code>$</code> followed by the variable name.</p>
<p>For a variable to be assigned to a value, we use the <code>=</code> symbol. Here are a few important things to note about PHP variables:</p>
<ul>
<li><p>A variable is declared/executed with a dollar symbol <code>$</code> then the variable name.</p>
</li>
<li><p>Variable names are case sensitive. For example <code>$Derek</code> is very different from <code>$DEREK</code>.</p>
</li>
<li><p>A variable name should not and cannot start with a number, but rather a letter (Aa – Zz) or an underscore (_).</p>
</li>
</ul>
<p>Here are some examples of naming variables in PHP:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
    $color = <span class="hljs-string">"red"</span>;
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"<span class="hljs-subst">$color</span>"</span>; <span class="hljs-comment">//THIS CODE OUTPUTS THE COLOR RED TO THE WEB BROWSER</span>
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"&lt;/br&gt;"</span>;

    $COLOR = <span class="hljs-string">"Blue"</span>;
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"<span class="hljs-subst">$COLOR</span>"</span>; <span class="hljs-comment">//THIS CODE OUTPUTS THE COLOR BLUE TO THE WEB BROWSER</span>
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"&lt;/br&gt;"</span>;

    $_price = <span class="hljs-string">"1000"</span>;
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"<span class="hljs-subst">$_price</span>"</span>; <span class="hljs-comment">//THIS CODE OUTPUTS THE PRICE 1000 TO THE WEB BROWSER</span>
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"&lt;/br&gt;"</span>;

    $_PRICE = <span class="hljs-string">"900"</span>;
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"<span class="hljs-subst">$_PRICE</span>"</span>; <span class="hljs-comment">//THIS CODE OUTPUTS THE PRICE 900 TO THE WEB BROWSER</span>
<span class="hljs-meta">?&gt;</span>
</code></pre>
<p>The code above shows the different ways of naming variables in PHP.</p>
<h2 id="heading-data-types-in-php">Data Types in PHP</h2>
<p>Variables in PHP store values of different data types. Now let's discuss some data types that work with PHP:</p>
<ul>
<li><p><code>String</code></p>
</li>
<li><p><code>Integer</code></p>
</li>
<li><p><code>Float</code></p>
</li>
<li><p><code>Boolean</code></p>
</li>
</ul>
<h3 id="heading-string-data-type">String data type</h3>
<p>A string is a data type which is represented with some text inside double quotes <code>" "</code>. A string can also hold numbers and special characters but they should be enclosed in the quotes. For example:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
    $name = <span class="hljs-string">"Derek Emmmanel"</span>;
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"<span class="hljs-subst">$name</span>"</span>;

    <span class="hljs-keyword">echo</span> <span class="hljs-string">"&lt;br&gt;"</span>;

    $price = “<span class="hljs-number">1234567</span>”;
    <span class="hljs-keyword">Echo</span> “$price”;
<span class="hljs-meta">?&gt;</span>
</code></pre>
<p>From the code above, the variable values <code>“Derek Emmanuel”;</code> and <code>"1234567"</code> are of the <code>string</code> data type because they are enclosed in quotes.</p>
<p>We can use another method to run the above code in our web browser. For example:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
$name = <span class="hljs-string">"Derek Emmmanel"</span>;
var_dump($name);
<span class="hljs-meta">?&gt;</span>
</code></pre>
<p>In the code above, I used the <code>var_dump</code> keyword to execute my PHP code. <code>Var_dump</code> not only displays your code to your web browser, but also helps you identify what data type you are working with and how many values it contains.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/06/localhost_Demo_test.php---Google-Chrome-6_8_2022-7_49_26-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>var_dump keyword</em></p>
<h3 id="heading-integer-data-type">Integer data type</h3>
<p>Integers are whole numbers that have no decimal point. Integers can either be negative numbers (-34567) or positive numbers (34567). For example:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
    $ad = <span class="hljs-number">12345</span>;
    var_dump($ad);
<span class="hljs-meta">?&gt;</span>
</code></pre>
<p>The code above is an example of the integer data type.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/06/localhost_Demo_test.php---Google-Chrome-6_8_2022-8_36_54-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-float-data-type">Float data type</h3>
<p>Floats are not whole numbers, but rather they are numbers with decimal points. Floats can also be negative decimal numbers (-34.567) or positive decimal numbers (34.567). For example:</p>
<pre><code class="lang-python">&lt;?php
    $fl = <span class="hljs-number">34.567</span>;
    var_dump($fl);
?&gt;
</code></pre>
<h3 id="heading-boolean-data-type">Boolean data type</h3>
<p>Boolean is a data type that represents two possible outcome, <code>true</code> or <code>false</code>. Booleans are used mostly when we are working with conditional statements like <code>if</code>, <code>else</code>, <code>elseif</code>, and <code>swtich</code>. For example:</p>
<pre><code class="lang-php">$house = <span class="hljs-literal">true</span>;
$city = <span class="hljs-literal">false</span>;
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I hope you've learned a lot from today's tutorial. Stay tuned for our next topic.</p>
<p>Happy Coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ PHP Tutorial – How to Setup PHP and XAMPP for Your Project ]]>
                </title>
                <description>
                    <![CDATA[ Hello and welcome to this tutorial, everyone. Today, we'll look at how you can set up and use PHP in a project. But before we get started, we'll need to understand what PHP is all about. What is PHP? PHP is an abbreviation or acronym for "Hypertext P... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-get-started-with-php/</link>
                <guid isPermaLink="false">66d45e02b6b7f664236cbdb6</guid>
                
                    <category>
                        <![CDATA[ PHP ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Okoro Emmanuel Nzube ]]>
                </dc:creator>
                <pubDate>Thu, 02 Jun 2022 15:11:07 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/05/PHP.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Hello and welcome to this tutorial, everyone. Today, we'll look at how you can set up and use PHP in a project.</p>
<p>But before we get started, we'll need to understand what PHP is all about.</p>
<h2 id="heading-what-is-php">What is PHP?</h2>
<p>PHP is an abbreviation or acronym for "Hypertext Preprocessor." It's a web-based open source server-side scripting language that's integrated in your HTML files.</p>
<p>You use it to make webpages that are both responsive and interactive with the database.</p>
<h2 id="heading-advantages-of-php">Advantages of PHP</h2>
<p>PHP has many benefits, and here are a few of them:</p>
<h3 id="heading-php-is-simple-to-use">PHP is Simple to Use</h3>
<p>You don't need to study extensively to learn and use PHP because its syntax is sensible and well-organized. The command functions are also easy to work with because they help you understand exactly what they do.</p>
<h3 id="heading-php-is-flexible">PHP is Flexible</h3>
<p>Flexibility is a major benefit that every scripting language should have, and PHP is no exception. Even after a project has been launched, a PHP developer has the ability to make changes to the project.</p>
<h3 id="heading-php-helps-you-collect-data-from-forms">PHP Helps You Collect Data from Forms</h3>
<p>You can use PHP to collect data from a form that has been created with HTML (like Name, E-mail, Phone Number, or Password). Many websites use this particular function of PHP.</p>
<h3 id="heading-php-has-good-security">PHP Has Good Security</h3>
<p>PHP does not outsource the data or information collected from forms. This is part of the reason why most most website and social media apps make use of it because it has a secure database system.</p>
<h2 id="heading-how-to-install-and-setup-php-in-your-project">How to Install and Setup PHP in your Project</h2>
<p>To get started with PHP, you'll need three things: a code editor for writing your code, an installed version of PHP, and XAMPP.</p>
<p>We'll be using Visual Studio code in this example, and I'll teach you how to install a version of PHP and XAMPP on your PC.</p>
<p>Go to the <a target="_blank" href="https://www.php.net/">PHP website</a> and click on download in the navigation bar. The current version should be at the top.</p>
<p>Click on "Windows downloads," and when it opens, scroll down a little and you should see a section that has "VS16 x64 Thread Safe (2022-May-11 09:29:42)." The section contains a "zip" file below it – click on it and wait for your download to finish.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/PHP_-Hypertext-Preprocessor---Google-Chrome-5_30_2022-7_57_44-PM-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Click on the Download Button</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/PHP_-Hypertext-Preprocessor---Google-Chrome-5_30_2022-7_57_58-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Click on Windows downloads</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/PHP_-Hypertext-Preprocessor---Google-Chrome-5_30_2022-7_58_42-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Below Thread Safe click on the zip file to download</em></p>
<p>When the download is complete, go to your computer's downloads folder and look for a PHP zip file. Right-click it and select extract file. It's important to save the file to your local drive.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/bandicam-2022-05-30-20-15-25-892-1.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Zip folder and the extracted folder</em></p>
<p>Open the Local Disk and open the extracted PHP folder. Click once on the bar that shows the current directory then copy the name of the directory, which should be in this format: C:\php-8.1.6.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/06/bandicam-2022-05-30-20-30-59-641.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Click the bar once and copy the Directory name</em></p>
<p>In your windows bar, search for “Edit the systems environment property”. Click on the “environment variables” button, click on “Path”, and then click on the edit button below. It opens a space where you can create a new variable.</p>
<p>So click on the new button and then paste the name of the directory you copied earlier (which should be “C:\php-8.1.6”) and click ok for all of them.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/Environment.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>To test if PHP is now installed in your computer, search for the command prompt in Windows by using the search keyword <code>cmd</code>. Open it then type <code>php --version</code> and click enter. You should see something similar to this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/bandicam-2022-05-30-20-46-16-280.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>PHP version 8.1.6</em></p>
<p>The current version of PHP is installed on our PC as seen in the image above. The next step is to get XAMPP.</p>
<h2 id="heading-what-is-xampp">What is XAMPP?</h2>
<p>The acronym XAMPP stands for cross-platform, Apache, MySQL, PHP, and Perl. XAMPP is a free and open source web server that allows you to develop, test, and build websites on a local server.</p>
<p>Unlike PHP, XAMPP installation is quite simple and uncomplicated. Search for "XAMPP Download" in your browser or go to their <a target="_blank" href="https://www.apachefriends.org/index.html">website</a>. You should see the current version of XAMPP for Windows, Linux, and OSX when it opens.</p>
<p>Because I'm using a Windows computer, I simply need to click on the one for Windows, and the download should begin.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/bandicam-2022-05-30-21-01-27-189.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Click the XAMPP for Windows if you are using Windows</em></p>
<p>When its done downloading, go to your downloads, right click on the setup file and select “run as administrator”.</p>
<p>This will take you to the <strong>Setup-xampp</strong> wizard:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/bandicam-2022-05-30-21-07-14-620.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>click next</em></p>
<p>Click next, and you'll be able to select the components you want:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/bandicam-2022-05-30-21-07-22-682.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><strong><em>Select components and click next</em></strong></p>
<p>Then you'll come to the installation folder. You have to select a folder where you want to install XAMPP. I recommend creating a folder in your local disk to install XAMPP.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/bandicam-2022-05-30-21-07-29-806.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>select an installation folder</em></p>
<p>Then you'll select the language. You can select either English or Deutsch (your choice):</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/bandicam-2022-05-30-21-09-03-881.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>select language</em></p>
<p>Now you'll get Bitnami for XAMPP:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/bandicam-2022-05-30-21-09-08-433.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>click next</em></p>
<p>And you're ready to install:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/bandicam-2022-05-30-21-09-25-333.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>click next</em></p>
<p>Be patient while the installation process completes. When it's, done click ok.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/bandicam-2022-05-30-21-09-30-643.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>wait for the installation to complete</em></p>
<p>Once the installation process is finished, you can now use XAMPP in you project.</p>
<h2 id="heading-why-do-you-need-xampp">Why Do You Need XAMPP?</h2>
<p>To run PHP for the web, you will need to install a web server like Apache and a database like MySQL – and both are supported by XAMPP.</p>
<p>XAMPP is a local server that can run smoothly on our personal computer, and is accepted in both Windows and Linux. It also helps you test websites and see if they work before actually publishing them to a web server.</p>
<h2 id="heading-how-to-run-php-with-xampp">How to Run PHP with XAMPP</h2>
<p>To run PHP with XAMPP you will have to go through some steps, and I will break it down so you can understand.</p>
<p>First, open the local storage folder, go to the “xampp” folder and open it. You should see a folder named “htdocs”. Open it then create a new folder in it. In my case I named the folder I created “Demo” (so give your folder the name of your choice).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/06/1-2-3.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Next, open your VS code, click on open folder, then go to the location where you saved the folder you created (which in my case I named “Demo”). Create a file with the extension <code>.php</code> – in my case I named mine <code>test.php</code>. The extension <code>.php</code> tells the code editor that we are working on a PHP code/project.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/06/bandicam-2022-06-01-22-08-09-094.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>create a file with an extension of .php</em></p>
<p>PHP is run with the <code>&lt;?php (Code goes in here) ?&gt;</code> tag. The opening tag is <code>&lt;?php</code> then your PHP code goes next before the closing tag <code>?&gt;</code>. For example:</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
<span class="hljs-keyword">echo</span> “&lt;h1&gt; My Name is Derek &lt;/h2&gt;;
<span class="hljs-meta">?&gt;</span>
</code></pre>
<p>The echo keyword tells the browser to display <code>My Name is Derek</code> while the <code>&lt;h1&gt;&lt;/h1&gt;</code> tells the web browser to format the text to be bold/bigger. Then save it.</p>
<p>After writing the code, open the XAMPP control panel, and start the Apache module by clicking on start under the action section.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/06/test.php---Demo---Visual-Studio-Code-6_2_2022-1_23_21-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Then go to your web browser and in the search bar type <code>localhost/Demo/test.php</code>, then enter. Your web browser should be display this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/06/bandicam-2022-06-01-22-07-50-039.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>web display</em></p>
<p>If your code was displayed on the web browser, congratulations! You're up and running.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Thank you very much for following along with this tutorial. I hope you got some value out of this lesson and I hope you'll try using PHP and XAMPP.</p>
<p>Stay tuned for my next tutorial.</p>
<p>Have fun coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use CSS Grid Layout – Grid Properties Explained with Examples ]]>
                </title>
                <description>
                    <![CDATA[ Have you ever had a problem positioning items on your web browser? Perhaps every time you try to think of a solution, you become tired and give up. If so, stay tuned as I reveal a new method for resolving these kinds of problems with minimal or no st... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-css-grid-layout/</link>
                <guid isPermaLink="false">66d45e0a182810487e0ce139</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CSS Grid ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Design ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Okoro Emmanuel Nzube ]]>
                </dc:creator>
                <pubDate>Wed, 25 May 2022 15:32:31 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/05/CSS-GRID-3.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Have you ever had a problem positioning items on your web browser? Perhaps every time you try to think of a solution, you become tired and give up.</p>
<p>If so, stay tuned as I reveal a new method for resolving these kinds of problems with minimal or no stress.</p>
<p>Welcome everyone. In this tutorial, we'll go through how to use the CSS grid layout.</p>
<p>First we'll learn what CSS Grid is and what it's meant to do. Then we'll go through the features of CSS grid, reasons why we should study it, and the benefits it brings to our projects. Finally, we'll discuss when it's best to use it.</p>
<h2 id="heading-what-is-css-grid">What is CSS Grid?</h2>
<p>So what is CSS Grid?</p>
<p>CSS Grid is a two-dimensional layout that you can use for creating responsive items on the web. The Grid items are arranged in columns, and you can easily position rows without having to mess around with the HTML code.</p>
<p>Here is a concise definition of the CSS Grid layout:</p>
<blockquote>
<p>CSS Grid is a powerful tool that allows for two-dimensional layouts for columns and rows to be created on the web. (<a target="_blank" href="https://learncssgrid.com/">Source</a>)</p>
</blockquote>
<h2 id="heading-features-of-css-grid-layout">Features of CSS Grid Layout</h2>
<h3 id="heading-flexible-track-sizes">Flexible Track Sizes</h3>
<p>You can use the <code>fr</code> unit (Fraction Unit) to assign any specified pixel value to the grid. This will make your grid organized and responsive.</p>
<h3 id="heading-item-placement">Item Placement</h3>
<p>CSS grid has made it much easier to position items in the container in any area you want them to be without having to mess with the HTML markup.</p>
<h3 id="heading-alignment-controls">Alignment Controls</h3>
<p>The alignment of an element/item in a container is easier than ever before with CSS Grid. In the container, you can now arrange elements/items horizontally and vertically as you wish.</p>
<h2 id="heading-benefits-of-css-grid">Benefits of CSS Grid</h2>
<p>CSS Grid is very flexible and responsive. It makes it easy to create two-dimensional layouts. CSS Grid also easy to use and is supported by most web browsers.</p>
<p>The CSS grid makes your mark-up cleaner (in your HTML code) and gives you a lot more flexibility. This is partly because you don’t have to change the mark-up (HTML code) to change the position of an item using the CSS grid.</p>
<p>All in all, CSS Grid Layout helps us build a more complex layouts using both columns and rows.</p>
<h2 id="heading-when-should-you-use-css-grid">When Should You Use CSS Grid</h2>
<p>Although you can use CSS Grid in practically any aspect of web development, there are certain situations when it's ideal.</p>
<p>For example, when we have a complex design layout to implement, CSS Grid is better than the CSS float property. This is because Grid is a two-dimensional layout (with columns <strong>and</strong> rows), whereas the CSS float property is a one-dimensional layout (with columns <strong>or</strong> rows).</p>
<p>Grid is also a good choice when we need a space or gap between elements. By using the CSS grid <code>gap</code> property, the spacing of two elements is much easier than using the CSS <code>margin</code> and <code>padding</code> properties which might end up complicating things.</p>
<h2 id="heading-css-grid-properties">CSS Grid Properties</h2>
<p>The CSS grid layout consists of many grid properties. Now we'll take a look at some of them so we can learn how to use them.</p>
<h3 id="heading-grid-container-property">Grid container property</h3>
<p>This is a CSS grid property that houses the grid items/elements. We implement the CSS grid container property by setting the container to a <code>display</code> property of <code>grid</code> or <code>in-line grid</code>.</p>
<p>For Example:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">display</span>: <span class="hljs-selector-tag">grid</span>;
</code></pre>
<p>or</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">display</span>: <span class="hljs-selector-tag">in-line</span> <span class="hljs-selector-tag">grid</span>;
</code></pre>
<h3 id="heading-grid-template-column-property">Grid-template-column property</h3>
<p>This is a property used to set each column’s width. It can also define how many columns you want to set to your project.</p>
<p>You can implement the CSS gird column property using <code>grid-template-column</code>.</p>
<p>For Example:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">grid-template-column</span>: 100<span class="hljs-selector-tag">px</span> <span class="hljs-selector-tag">auto</span> 100<span class="hljs-selector-tag">px</span>;
</code></pre>
<p>The code above shows that we have three columns. The width of columns one (the first column) and three (the third column) are set to <code>100px</code>. The width of column two (the middle column) is set to <code>auto</code>.</p>
<p>This means that as the size of your screen increases, columns one and three take <code>100px</code> of the screen width, while column two takes the remaining width of the screen (which is <code>auto</code>).</p>
<h3 id="heading-grid-template-row-property">Grid-template-row property</h3>
<p>You use the CSS row property to set the height of each column. You can also use it to define how many rows you want to set in your project.</p>
<p>You can implement the CSS gird row property using <code>grid-template-row</code>, like this:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">grid-template-row</span>: 50<span class="hljs-selector-tag">px</span> 50<span class="hljs-selector-tag">px</span>;
</code></pre>
<p>The code above shows that we have a total of two rows and those two rows are <code>50px</code> high.</p>
<p>Note that we can also assign the column and row property to our HTML code at once by simply using <code>gird-template</code>. <code>Grid-template</code> is another way of representing the <code>grid-template column</code> and <code>grid-template-row</code>.</p>
<p>For example:</p>
<pre><code class="lang-css"> <span class="hljs-selector-tag">grid-template</span>: 50<span class="hljs-selector-tag">px</span> 50<span class="hljs-selector-tag">px</span> / 100<span class="hljs-selector-tag">px</span> <span class="hljs-selector-tag">auto</span> 100<span class="hljs-selector-tag">px</span>;
</code></pre>
<p>The code above will give you the same result as <code>grid-template-column</code> and <code>grid-template-row</code>.</p>
<p>To use the <code>grid-template</code> property, you will have to assign the value to the row first before assigning the column's value, just like the code above. The <code>50px 50px</code> is for the row while <code>100px auto 100px</code> is for the column.</p>
<p>A way to remember this is by thinking of the letter L:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/image-90.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>grid-template</em></p>
<p>Try this out and see it for yourself.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/CSS-GRID-2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>A gird with a column of 100px auto 100px and row of 50px 50px</em></p>
<h3 id="heading-column-gap-property">Column-gap property</h3>
<p>As the name states, it is a grid property that assigns a space between two or more columns in a container. You can do this by using the <code>column-gap</code> property and giving it a value. For example:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">column-gap</span>: 20<span class="hljs-selector-tag">px</span>;
</code></pre>
<p>From the code above, you can see that a gap of <code>20px</code> was assigned to the column.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/COLUMN-GAP-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>20px column-gap</em></p>
<h3 id="heading-row-gap-property">Row-gap property</h3>
<p>Just like <code>column-gap</code>, <code>row-gap</code> is a CSS property that assigns a space between two or more rows in a container. For example:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">row-gap</span>: 50<span class="hljs-selector-tag">px</span>;
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/ROW-GAP-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>row-gap: 50px;</em></p>
<p>Note that we can also assign a gap to both the columns and rows of a container by using the <code>gap</code> property. For this to work, we only assign one value to both the columns and the rows of the container, just like we did in the code above.</p>
<p>Here's an example:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">gap</span>: 20<span class="hljs-selector-tag">px</span>;
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/GAP-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>gap: 20px</em></p>
<p>From the diagram above, we can see that a <code>gap</code> of <code>20px</code> was set to both the columns and rows of the container making them equally spaced.</p>
<h3 id="heading-justify-content-property">Justify-content property</h3>
<p>This is a grid property that you use in positioning items (columns and rows) horizontally in a container. It displays how the web browser positions the spaces around the items (columns and rows).</p>
<p>The justify-content property has six possible values:</p>
<ul>
<li><p><code>Start</code></p>
</li>
<li><p><code>end</code></p>
</li>
<li><p><code>center</code></p>
</li>
<li><p><code>space-around</code></p>
</li>
<li><p><code>space-between</code></p>
</li>
<li><p><code>space-evenly</code></p>
</li>
</ul>
<h4 id="heading-start">Start</h4>
<p>This positions the items at the left side of the browser and can be executed with the following code:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">justify-content</span>: <span class="hljs-selector-tag">start</span>;
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/JUSTIFY-START-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>justify-content: start;</em></p>
<h4 id="heading-end">End</h4>
<p>This positions the items at the right side of the browser and can be executed with the following code:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">justify-content</span>: <span class="hljs-selector-tag">end</span>;
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/JUSTIFY-END-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>justify-content: end;</em></p>
<h4 id="heading-center">Center</h4>
<p>This positions the items at the center of the browser and can be executed with the following code:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">justify-content</span>: <span class="hljs-selector-tag">center</span>;
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/JUSTIFY-CENTER-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>justify-content: center;</em></p>
<h4 id="heading-space-around">Space-around</h4>
<p>This property distributes the items in the container evenly, where each item in the container has an equal amount of space from the next container.</p>
<p>This code can be executed like this:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">justify-content</span>: <span class="hljs-selector-tag">space-around</span>;
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/JUSTIFY-SPACE-AROUND-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>justify-content: space-around</em></p>
<h4 id="heading-space-between">Space-between</h4>
<p>Just like the <code>space-around</code> property, <code>space-between</code> distributes the items in the container evenly, where each item in the container has an equal amount of space from the next one in the container. It takes up the entire width of the container.</p>
<p>This code can be executed like this:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">justify-content</span>: <span class="hljs-selector-tag">space-between</span>;
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/JUSTIFY-SPACE-BETWEEN-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>justify-content: space-between</em></p>
<h4 id="heading-space-evenly">Space-evenly</h4>
<p>Just as the name states, this property distributes the items in the container evenly, where each item in the container has an equal amount of space from the next one in the container.</p>
<p>This code can be executed like this:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">justify-content</span>: <span class="hljs-selector-tag">space-evenly</span>;
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/JUSTIFY-SPACE-EVENLY-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>justify-content: space-evenly;</em></p>
<p>Note that all the <code>justify-content</code> properties position their items/elements horizontally. Try doing it yourself to understand it more.</p>
<h3 id="heading-align-content-property">Align-content property</h3>
<p><code>Align-content</code> is the opposite of <code>justify-content</code>. You use the <code>align-content</code> property in positioning items vertically in a container.</p>
<p>Just like <code>justify-content</code>, the <code>align-content</code> property has six possible values:</p>
<ul>
<li><p><code>Start</code></p>
</li>
<li><p><code>end</code></p>
</li>
<li><p><code>center</code></p>
</li>
<li><p><code>space-around</code></p>
</li>
<li><p><code>space-between</code></p>
</li>
<li><p><code>space-evenly</code></p>
</li>
</ul>
<h4 id="heading-start-1">Start</h4>
<p>This positions the items at the top of the browser and can be executed with the following code:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">align-content</span>: <span class="hljs-selector-tag">start</span>;
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/ALIGN-CONTENT-START-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>align-content: start;</em></p>
<h4 id="heading-end-1">End</h4>
<p>This positions the items at the bottom of the browser and can be executed with the following code:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">align-content</span>: <span class="hljs-selector-tag">end</span>;
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/ALIGN-CONTENT-END-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>align-content: end</em></p>
<h4 id="heading-center-1">Center</h4>
<p>This positions the items at the center of the browser and can be executed with the following code:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">align-content</span>: <span class="hljs-selector-tag">center</span>;
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/ALIGN-CONTENT-CENTER-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>align-content: center;</em></p>
<h4 id="heading-space-around-1">Space-around</h4>
<p>This property distributes the items along the side of the container evenly, where each item in the container has an equal amount of space from the next one vertically.</p>
<p>This code can be executed like this:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">align-content</span>: <span class="hljs-selector-tag">space-around</span>;
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/ALIGN-CONTENT-SPACE-AROUND-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>align-content: space-around</em></p>
<h4 id="heading-space-between-1">Space-between</h4>
<p>Just like the <code>space-around</code> property, <code>Space-between</code> distributes the items in the container evenly, where each item in the container has an equal amount of space from the next one in the container, and takes up the entire width of the container in the vertical direction.</p>
<p>This code can be executed like this:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">align-content</span>: <span class="hljs-selector-tag">space-between</span>;
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/ALIGN-CONTENT-SPACE-BETWEEN-2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>align-content: space-between</em></p>
<h4 id="heading-space-evenly-1">Space-evenly</h4>
<p>Just as the name states, this property distributes the items in the container evenly, where each item in the container has an equal amount of space from the next one vertically.</p>
<p>This code can be executed like this:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">align-content</span>: <span class="hljs-selector-tag">space-evenly</span>;
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/ALIGN-CONTENT-SPACE-EVENLY-2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>align-content: space-evenly</em></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In today's article, we studied what CSS Grid Layout is all about, why we should learn it, and the properties of CSS grid.</p>
<p>Thank you for reading.</p>
<p>Have fun coding!</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
