<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: missbaah</title>
    <description>The latest articles on DEV Community by missbaah (@missbaah).</description>
    <link>https://dev.to/missbaah</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F681999%2Fbe0a905b-4683-4523-bc9b-cb55a0a6ee9b.jpeg</url>
      <title>DEV Community: missbaah</title>
      <link>https://dev.to/missbaah</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/missbaah"/>
    <language>en</language>
    <item>
      <title>Implementing A GitHub Repository API Call.</title>
      <dc:creator>missbaah</dc:creator>
      <pubDate>Sun, 08 Jan 2023 20:19:41 +0000</pubDate>
      <link>https://dev.to/missbaah/implementing-a-github-repository-api-call-593k</link>
      <guid>https://dev.to/missbaah/implementing-a-github-repository-api-call-593k</guid>
      <description>&lt;p&gt;As part of the second-semester examination for &lt;a href="https://www.altschoolafrica.com/"&gt;Alt School Africa&lt;/a&gt; Frontend Engineering track. We were tasked to implement key features such as API fetch, routing, error boundary, and SEO using React.js. Check out the &lt;a href="https://missbaahsgithubsite.netlify.app/"&gt;live site&lt;/a&gt; here. Below reads the task&lt;/p&gt;

&lt;h3&gt;
  
  
  Task
&lt;/h3&gt;

&lt;p&gt;Implement an API fetch of your GitHub portfolio, show a page with a list of all your repositories on GitHub(the page should implement pagination for the repo list), and create another page showing data for a single repo clicked from the list of repos using nested routes while using all the necessary tools in react. Implement the proper SEO, Error Boundary (show a page to test the error boundary), and 404 pages. Good UI and Designs are important.&lt;/p&gt;

&lt;h3&gt;
  
  
  Approach
&lt;/h3&gt;

&lt;p&gt;I split the task into components, i.e. ;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implement an API fetch of my GitHub Portfolio &lt;/li&gt;
&lt;li&gt;Show a page with a list of all my repositories&lt;/li&gt;
&lt;li&gt;Implement pagination for the repo list&lt;/li&gt;
&lt;li&gt;Show a page for single repo clicked from the list of repos using nested routes.&lt;/li&gt;
&lt;li&gt;Implement proper SEO&lt;/li&gt;
&lt;li&gt;Show a page to test boundary error&lt;/li&gt;
&lt;li&gt;Create a 404 page&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Project Setup
&lt;/h3&gt;

&lt;p&gt;To set up my project I used the online IDE &lt;a href="//www.replit.com"&gt;Replit&lt;/a&gt; and selected a react template. In the src file, I set up react-router to dynamically access all the pages necessary for this task in the &lt;code&gt;App.js&lt;/code&gt; file. &lt;/p&gt;

&lt;p&gt;For this project, I create 5 pages namely &lt;code&gt;home&lt;/code&gt;, &lt;code&gt;repos&lt;/code&gt;, repo-project, &lt;code&gt;not found&lt;/code&gt;, and &lt;code&gt;error boundary page&lt;/code&gt;. The repo project in a nested route within the repos page from a single repository clicked and the &lt;code&gt;error page&lt;/code&gt; is the 404 page for a URL not found.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import './App.css'
import { Routes, Route, Link } from "react-router-dom"
import { Repos, Home, NotFound, ErrorPage, Project } from "./components"

export default function App() {
  return (
      &amp;lt;Routes&amp;gt;
        &amp;lt;Route index element={&amp;lt;Home /&amp;gt;} /&amp;gt;
        &amp;lt;Route path="home" element={&amp;lt;Home /&amp;gt;} /&amp;gt;
        &amp;lt;Route path="repos/*" element={&amp;lt;Repos /&amp;gt;} /&amp;gt;
        &amp;lt;Route path="repos/:projectId" element={&amp;lt;Project /&amp;gt;} /&amp;gt;
        &amp;lt;Route path="error" element={&amp;lt;ErrorPage /&amp;gt;} /&amp;gt;
        &amp;lt;Route path="*" element={&amp;lt;NotFound /&amp;gt;} /&amp;gt;
      &amp;lt;/Routes&amp;gt;
    &amp;lt;/main&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The project started with a nav bar with links that routed to 3 pages i.e. the &lt;code&gt;home&lt;/code&gt;, &lt;code&gt;repos&lt;/code&gt;, and &lt;code&gt;error boundary page&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;lt;main&amp;gt;
      &amp;lt;nav className="main-nav"&amp;gt;
        &amp;lt;Link className="nav-link" to="/home"&amp;gt;Home&amp;lt;/Link&amp;gt;
        &amp;lt;Link className="nav-link" to="/repos"&amp;gt;Repos&amp;lt;/Link&amp;gt;
        &amp;lt;Link className="nav-link" to="/error"&amp;gt;Error Boundary&amp;lt;/Link&amp;gt;
      &amp;lt;/nav&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I created a components folder in src to carry the component created in this project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Home Page
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PuQ2l_Rh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1dc7ifi2h15a9p10tpz9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PuQ2l_Rh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1dc7ifi2h15a9p10tpz9.png" alt="Image of the home page" width="880" height="420"&gt;&lt;/a&gt;&lt;br&gt;
I wanted the home page to show details such as my name, photo, number of repositories, followers, and following from my GitHub profile. To handle the data, I used &lt;code&gt;useState&lt;/code&gt; to be able to set the user and set the loading state. To be able to display the data I need, I needed to fetch it from the GitHub API to render it. I used &lt;code&gt;useEffect&lt;/code&gt;with the help of &lt;a href="https://axios-http.com/"&gt;Axios&lt;/a&gt; to fetch the data and set it to &lt;code&gt;setUser&lt;/code&gt;. From there, the data needed could be obtained using dot notation. Find the code below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import axios from "axios";
import { useState, useEffect } from "react";
import { Helmet } from "react-helmet-async";
import { LinearProgress } from "@mui/material";
import "../App.css"


const Home = () =&amp;gt; {
  const [user, setUser] = useState([]);
  const [loading, setLoading] = useState(false);

  useEffect(
    () =&amp;gt; {
      const fetchUser = async () =&amp;gt; {
        setLoading(true)
        const response = await axios.get('https://api.github.com/users/missbaah')
        setUser(response.data);
        setLoading(false)
      }
      fetchUser()
    }, []
  )

  if (loading) {
    return &amp;lt;div&amp;gt;
      &amp;lt;h2&amp;gt;Loading&amp;lt;/h2&amp;gt;
      &amp;lt;LinearProgress /&amp;gt;
    &amp;lt;/div&amp;gt;
  }

  return (
    &amp;lt;section&amp;gt;
      &amp;lt;Helmet&amp;gt;
        &amp;lt;title&amp;gt;Home&amp;lt;/title&amp;gt;
        &amp;lt;meta name="description" content="This page is the home page containing introductory info" /&amp;gt;
        &amp;lt;link rel="canonical" href="/home" /&amp;gt;
      &amp;lt;/Helmet&amp;gt;


      &amp;lt;div className="intro-container"&amp;gt;
        &amp;lt;div className="box-A"&amp;gt;

          &amp;lt;img src={user.avatar_url} alt="image of the user" loading="eager" title="Image of Adwoa Baah Addo-Brako" width="460" height="460" /&amp;gt;
          &amp;lt;h1 className="intro"&amp;gt;Hello 👋,  I'm {user.name} &amp;lt;/h1&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;section className="box-B"&amp;gt;
          &amp;lt;div className="user-bio"&amp;gt;{user.bio}&amp;lt;/div&amp;gt;
          &amp;lt;div className="stats"&amp;gt;
            &amp;lt;div className="stat"&amp;gt;&amp;lt;span className="bold"&amp;gt;{user.public_repos}&amp;lt;/span&amp;gt; repositories&amp;lt;/div&amp;gt;
            &amp;lt;div className="stat"&amp;gt;&amp;lt;span className="bold"&amp;gt;{user.followers}&amp;lt;/span&amp;gt; followers&amp;lt;/div&amp;gt;
            &amp;lt;div className="stat"&amp;gt;&amp;lt;span className="bold"&amp;gt;{user.following}&amp;lt;/span&amp;gt; following&amp;lt;/div&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/section&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/section&amp;gt;
  )
}

export default Home;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  GitHub API Fetch (Repos Page)
&lt;/h3&gt;

&lt;p&gt;The next component was the &lt;code&gt;repos&lt;/code&gt;component which will show the list of all my GitHub repos. Similar to the home page, &lt;code&gt;useState&lt;/code&gt;was used to handle the dynamic data, and &lt;code&gt;useEffect&lt;/code&gt;was used to fetch the data and set it to a state. To render every individual repo, I used the &lt;code&gt;.map()&lt;/code&gt; method and returned a list of the repos with the specific data I wanted to display.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import axios from "axios";
import { useState, useEffect } from "react";
import { Routes, Route, Link } from "react-router-dom"
import '../App.css';

const Repos = () =&amp;gt; {
  // setting states 
  const [repos, setRepos] = useState([]);
  const [loading, setLoading] = useState(false);

  // fetching the data from the API using axios
  useEffect(
    () =&amp;gt; {
      const fetchRepos = async () =&amp;gt; {
        setLoading(true)
        const response = await axios.get('https://api.github.com/users/missbaah/repos')
        setRepos(response.data);
        setLoading(false)
      }
      fetchRepos()
    }, []
  )

 // looping throught the repos to create a list item of each repo
  const listOfProjects = repos.map((repo) =&amp;gt; {
    return (
      &amp;lt;li className="card" key={repo.id}&amp;gt;
        &amp;lt;Link className="card-link" to={`/repos/${repo.id}`}&amp;gt;
          &amp;lt;div className="name"&amp;gt;
            {repo.name}
          &amp;lt;/div&amp;gt;
          &amp;lt;br /&amp;gt;
          &amp;lt;div className="lang" &amp;gt;
            {repo.language ? `Prominent Languge: ${repo.language}` : "Language: None"}
          &amp;lt;/div&amp;gt;
          &amp;lt;br /&amp;gt;
          &amp;lt;div className="contributors" &amp;gt;
            Contributors: @{repo.owner.login}
          &amp;lt;/div&amp;gt;
        &amp;lt;/Link&amp;gt;
      &amp;lt;/li&amp;gt;)
  });

return (
    &amp;lt;&amp;gt;
      &amp;lt;h2&amp;gt;GitHub Repositories&amp;lt;/h2&amp;gt;
      {/*renders an unordered list of repos*/}
      &amp;lt;ul&amp;gt;
        {listOfProjects}
      &amp;lt;/ul&amp;gt;
      &amp;lt;Routes&amp;gt;
        &amp;lt;Route path=":id" element={&amp;lt;Project /&amp;gt;} /&amp;gt;
      &amp;lt;/Routes&amp;gt;

    &amp;lt;/&amp;gt;
  )

}

export default Repos;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pagination
&lt;/h3&gt;

&lt;p&gt;After getting the list of repos on my GitHub profile, I implemented pagination for the page. To do that, I created a pagination component that takes 3 props; &lt;code&gt;reposPerPage&lt;/code&gt;, &lt;code&gt;totalRepos&lt;/code&gt;, and &lt;code&gt;paginate&lt;/code&gt;. The &lt;code&gt;pageNum&lt;/code&gt;variable was created in the pagination component to track page numbers and set to an empty array. A for loop was used to loop over the &lt;code&gt;totalRepos/reposPerPage&lt;/code&gt; and pushed into the &lt;code&gt;pageNum&lt;/code&gt;array. To render each page number individually, a list of the &lt;code&gt;pageNum&lt;/code&gt;array was created using the &lt;code&gt;.map()&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";

const Pagination = ({reposPerPage, totalRepos, paginate}) =&amp;gt; {
  // set the page number to an empty array
 const pageNum = [];

  // loop throw the total over repos per each page
  for (let i=1; i &amp;lt;= Math.ceil(totalRepos/reposPerPage); i++){
    // add the numbers unto the the pageNum array
  pageNum.push(i)
  }

  // Create a list of the array of page numbers 
  const listOfPageNums = pageNum.map((num)=&amp;gt;{ 
    return &amp;lt;li className="list-box" key={num}&amp;gt;
      {/*each page number is a link that accepts a prop called paginate*/}
            &amp;lt;a className="paginate-link" href="#" onClick={()=&amp;gt;paginate(num)}&amp;gt;{num}&amp;lt;/a&amp;gt;
          &amp;lt;/li&amp;gt; 
  })

  return (
    &amp;lt;nav &amp;gt;
       {/*render an unorder list of page numbers*/}
      &amp;lt;ul className="paginate-box"&amp;gt;
        {listOfPageNums}
      &amp;lt;/ul&amp;gt;
    &amp;lt;/nav&amp;gt;
  )
}

export default Pagination;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pagination component was then imported into repos component. To be able to render only the repos needed per page, I found the index of the last and first repos and created a variable called &lt;code&gt;currentRepos&lt;/code&gt;which uses &lt;code&gt;.slice()&lt;/code&gt; to store the repos needed for each page. The variable &lt;code&gt;currentRepos&lt;/code&gt;replaces the &lt;code&gt;repos&lt;/code&gt;array to be looped over to create a list of repos with the specific data needed. A paginate function was created in repos with accepts &lt;code&gt;num&lt;/code&gt;as a parameter and sets the &lt;code&gt;currentPage&lt;/code&gt;to &lt;code&gt;num&lt;/code&gt;. After adding pagination, the code for the repos component will look like this;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import axios from "axios";
import { useState, useEffect } from "react";
import { Routes, Route, Link } from "react-router-dom"
import '../App.css';
import Pagination from "./Pagination.jsx"
import Project from "./Project.jsx"
import { Helmet } from "react-helmet-async"
import { LinearProgress } from "@mui/material";

const Repos = () =&amp;gt; {
  // setting states 
  const [repos, setRepos] = useState([]);
  const [loading, setLoading] = useState(false);
  const [currentPage, setCurrentPage] = useState(1);
  const [reposPerPage] = useState(3);

  // fetching the data from the API using axios
  useEffect(
    () =&amp;gt; {
      const fetchRepos = async () =&amp;gt; {
        setLoading(true)
        const response = await axios.get('https://api.github.com/users/missbaah/repos')
        setRepos(response.data);
        setLoading(false)
      }
      fetchRepos()
    }, []
  )



  const indexOfLastRepo = currentPage * reposPerPage;
  const indexOfFirstRepo = indexOfLastRepo - reposPerPage;
  // limiting the number of repos per page
  const currentRepos = repos.slice(indexOfFirstRepo, indexOfLastRepo);


  // looping throught the repos to create a list item of each repo
  const listOfProjects = currentRepos.map((repo) =&amp;gt; {
    return (
      &amp;lt;li className="card" key={repo.id}&amp;gt;
        &amp;lt;Link className="card-link" to={`/repos/${repo.id}`}&amp;gt;
          &amp;lt;div className="name"&amp;gt;
            {repo.name}
          &amp;lt;/div&amp;gt;
          &amp;lt;br /&amp;gt;
          &amp;lt;div className="lang" &amp;gt;
            {repo.language ? `Prominent Languge: ${repo.language}` : "Language: None"}
          &amp;lt;/div&amp;gt;
          &amp;lt;br /&amp;gt;
          &amp;lt;div className="contributors" &amp;gt;
            Contributors: @{repo.owner.login}
          &amp;lt;/div&amp;gt;
        &amp;lt;/Link&amp;gt;
      &amp;lt;/li&amp;gt;)
  });

  // Create paginate function
  const paginate = (num) =&amp;gt; setCurrentPage(num);
  if (loading) {
    return &amp;lt;div &amp;gt;
      &amp;lt;h2&amp;gt;Loading&amp;lt;/h2&amp;gt;
      &amp;lt;LinearProgress/&amp;gt;
    &amp;lt;/div&amp;gt;

  }

  return (
    &amp;lt;&amp;gt;
      &amp;lt;Helmet&amp;gt;
        &amp;lt;title&amp;gt;Repos&amp;lt;/title&amp;gt;
        &amp;lt;meta name="description" content="Here is a list of Repos for the user's github profile" /&amp;gt;
        &amp;lt;link rel="canonical" href="/repos" /&amp;gt;
      &amp;lt;/Helmet&amp;gt;

      &amp;lt;h2&amp;gt;GitHub Repositories&amp;lt;/h2&amp;gt;
      {/*renders an unordered list of repos*/}
      &amp;lt;ul&amp;gt;
        {listOfProjects}
      &amp;lt;/ul&amp;gt;
      {/*renders the pagination component*/}
      &amp;lt;Pagination reposPerPage={reposPerPage} totalRepos={repos.length} paginate={paginate} /&amp;gt;
      {/*nested route to individual repos*/}
      &amp;lt;Routes&amp;gt;
        &amp;lt;Route path=":id" element={&amp;lt;Project /&amp;gt;} /&amp;gt;
      &amp;lt;/Routes&amp;gt;

    &amp;lt;/&amp;gt;
  )

}

export default Repos;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Viewing Data From A Single Repo
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K4PXWK8z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b9nfwzggemmfi69d762j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K4PXWK8z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b9nfwzggemmfi69d762j.png" alt="For a single repo clicked" width="880" height="428"&gt;&lt;/a&gt;&lt;br&gt;
When a single repo is clicked it should open up to another page with details of the repo. To achieve this I used nested routes. In the &lt;code&gt;App.js&lt;/code&gt;file, I nested &lt;code&gt;repos/:projectId&lt;/code&gt; to represent a single project clicked on and linked it to the &lt;code&gt;project&lt;/code&gt; component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;Route path="repos/*" element={&amp;lt;Repos /&amp;gt;} /&amp;gt;
        &amp;lt;Route path="repos/:projectId" element={&amp;lt;Project /&amp;gt;} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To build the &lt;code&gt;project&lt;/code&gt; component, the data for the clicked repo was fetched using the API and then destructed &lt;code&gt;projectId&lt;/code&gt; using &lt;code&gt;useParams&lt;/code&gt;. I created a variable named &lt;code&gt;project&lt;/code&gt; which tracked which if the id of the single repo clicked matched with the id project id. &lt;code&gt;Project&lt;/code&gt; was then destructured to obtained the data need from the API call.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import axios from "axios";
import { useState, useEffect } from "react";
import { Link, useParams } from "react-router-dom";
import { Helmet } from "react-helmet-async";

const Project = () =&amp;gt; {
  const [repos, setRepos] = useState([]);
  const [loading, setLoading] = useState(false);

  useEffect(
    () =&amp;gt; {
      const fetchRepos = async () =&amp;gt; {
        setLoading(true)
        const response = await axios.get('https://api.github.com/users/missbaah/repos')
        setRepos(response.data);
        setLoading(false)
      }
      fetchRepos()
    }, []
  )

  const { projectId } = useParams();
  // console.log(repos)
  const project = repos.find(repo =&amp;gt; repo.id == projectId);
  const {name, html_url, forks, stargazers_count, updated_at} = project || {};

  return (
    &amp;lt;&amp;gt;
      &amp;lt;Helmet&amp;gt;
        &amp;lt;title&amp;gt;Project&amp;lt;/title&amp;gt;
        &amp;lt;meta name="description" content="This page contains the data for a single repo clicked on"/&amp;gt;
        &amp;lt;link rel="canonical" href="/repos/:projectId" /&amp;gt;
      &amp;lt;/Helmet&amp;gt;

      &amp;lt;h2&amp;gt;{name}&amp;lt;/h2&amp;gt;
      &amp;lt;section className="data-box"&amp;gt;
      &amp;lt;div className="details"&amp;gt;Stars: &amp;lt;span className="deets"&amp;gt;{stargazers_count}&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;
      &amp;lt;div className="details"&amp;gt;Forks: &amp;lt;span className="deets"&amp;gt;{forks}&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;
      &amp;lt;div className="details"&amp;gt;Last Update: &amp;lt;span className="deets"&amp;gt;{updated_at}&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;
      &amp;lt;a  className="details" href={html_url} target="_blank"&amp;gt;Visit Source Code&amp;lt;/a&amp;gt;
        &amp;lt;/section&amp;gt;
      &amp;lt;Link className="home" to="/repos"&amp;gt;Back to Repos&amp;lt;/Link&amp;gt;
    &amp;lt;/&amp;gt;
  )
}

export default Project;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Error Boundary Page
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WMxMsq8T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uq4v51u6457ygu4se7ei.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WMxMsq8T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uq4v51u6457ygu4se7ei.png" alt="Error Boundary Page" width="880" height="429"&gt;&lt;/a&gt;&lt;br&gt;
The next page tackled was error boundary. To create the error boundary page , I created an &lt;code&gt;errorpage&lt;/code&gt; component which had a heading, a text body and an &lt;code&gt;errorbutton&lt;/code&gt; component nested between an &lt;code&gt;errorboundary&lt;/code&gt;component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import ErrorButton from "./ErrorButton.jsx"
import ErrorBoundary from "./ErrorBoundary.jsx"
import {Helmet} from "react-helmet-async"
import "../App.css"

const ErrorPage = () =&amp;gt; {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;Helmet&amp;gt;
        &amp;lt;title&amp;gt;ErrorPage&amp;lt;/title&amp;gt;
        &amp;lt;meta name="description" content="This page displays the error boundary test setup"/&amp;gt;
        &amp;lt;link rel="canonical" href="/error" /&amp;gt;
      &amp;lt;/Helmet&amp;gt;
      &amp;lt;h2&amp;gt;Error Boundary Test&amp;lt;/h2&amp;gt;
      &amp;lt;p className="p-body"&amp;gt;When the button is clicked, it shows throws and error and shows a fallback UI to prevent the entire component tree from unmounting&amp;lt;/p&amp;gt;
      &amp;lt;ErrorBoundary&amp;gt;
        &amp;lt;ErrorButton /&amp;gt;
      &amp;lt;/ErrorBoundary&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

export default ErrorPage;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;errorbutton&lt;/code&gt; component used &lt;code&gt;useState&lt;/code&gt; to handle if the error data was true or false and returned a button with an &lt;code&gt;onClick&lt;/code&gt; event listener which accepted the function &lt;code&gt;handleClick&lt;/code&gt;. The fuction &lt;code&gt;handleClick&lt;/code&gt; was used to set the state to true.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { useState } from "react"
import "../App.css"


const ErrorButton = () =&amp;gt; {
// setting the state of the error
  const [error, setError] = useState(false);

 // handling error button click event 
  const handleClick = () =&amp;gt; {
    setError(true);
  }

  // throw string if error is successful
  if (error) throw new Error("Error Boundary Test Successful!");

  // render the error buttom
  return (
    &amp;lt;div className="err-button"&amp;gt;
    &amp;lt;button  onClick={handleClick}&amp;gt;Throw Error&amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
  )
}

export default ErrorButton;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;errorboundary&lt;/code&gt; component code is down below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { Component } from "react";
import "../App.css"

 export default class ErrorBoundary extends Component {
  constructor(props) {
    super(props);
    this.state = { error: null, errorInfo: null };
  }


  componentDidCatch(error, errorInfo) {
    this.setState({
      error: error,
      errorInfo: errorInfo
    })
  }

  render() {
    // if there is an error render...
    if (this.state.errorInfo) {
      return (
        &amp;lt;div&amp;gt;
          {/*a phrase and details of the error */}
          &amp;lt;h2&amp;gt;Something went wrong.&amp;lt;/h2&amp;gt;
          &amp;lt;details&amp;gt;
            {this.state.error &amp;amp;&amp;amp; this.state.error.toString()}
            &amp;lt;br/&amp;gt;
            {this.state.errorInfo.componentStack}
          &amp;lt;/details&amp;gt;
        &amp;lt;/div&amp;gt;
      );
 }
    return this.props.children;
  }  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  404 Page
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qPMtYpjN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sbrbxmqiskj9e0fkcqwx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qPMtYpjN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sbrbxmqiskj9e0fkcqwx.png" alt="404 Page" width="880" height="562"&gt;&lt;/a&gt;&lt;br&gt;
The 404 page was created using the &lt;code&gt;NotFound&lt;/code&gt; component. Below is the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { Helmet } from "react-helmet-async";
import {Link} from "react-router-dom"
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faArrowRight} from "@fortawesome/free-solid-svg-icons";
import "../App.css"

const NotFound = () =&amp;gt; {
   return (

        &amp;lt;section className="err-container"&amp;gt;
      &amp;lt;Helmet&amp;gt;
        &amp;lt;title&amp;gt;NotFound&amp;lt;/title&amp;gt;
        &amp;lt;meta name="description" content="This is the 404 error page for this site"/&amp;gt;
        &amp;lt;link rel="canonical" href="*" /&amp;gt;
      &amp;lt;/Helmet&amp;gt;

     &amp;lt;div className="err"&amp;gt;404&amp;lt;/div&amp;gt;
      &amp;lt;p className="err-title"&amp;gt;Oops !&amp;lt;/p&amp;gt;
    &amp;lt;br/&amp;gt;
      &amp;lt;p className="err-body"&amp;gt;Looks like the page you are looking for cannont be found&amp;lt;/p&amp;gt;
     &amp;lt;Link className="home" to="/home"&amp;gt;Back to Home &amp;lt;FontAwesomeIcon icon={faArrowRight} /&amp;gt;&amp;lt;/Link&amp;gt;

    &amp;lt;/section&amp;gt;


  )
}

export default NotFound;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Implementing SEO
&lt;/h3&gt;

&lt;p&gt;To improve the SEO of the site, &lt;code&gt;react-helmet&lt;/code&gt; was used to help assign titles, meta information, and links to each page on the site. An example code below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;lt;Helmet&amp;gt;
        &amp;lt;title&amp;gt;NotFound&amp;lt;/title&amp;gt;
        &amp;lt;meta name="description" content="This is the 404 error page for this site"/&amp;gt;
        &amp;lt;link rel="canonical" href="*" /&amp;gt;
      &amp;lt;/Helmet&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also made use of the &lt;a href="//omiod.com/meta-seo-inspector/"&gt;META SEO inspector&lt;/a&gt; by viewing the suggestions assigned to each page and implementing them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Improvements
&lt;/h3&gt;

&lt;p&gt;I made sure to make my site media responsive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Additional Notes
&lt;/h3&gt;

&lt;p&gt;All styling was done using an external style sheet and the 404 page used Font Awesome icons. Thank you for reading. I hope you found this helpful. Find below the live site and the GitHub repository for this project&lt;br&gt;
&lt;a href="https://missbaahsgithubsite.netlify.app/"&gt;Live Site&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/missbaah/Question-1--Semester-2-Exams"&gt;GitHub Repository&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
