List user Repos using the GitHub API

List user Repos using the GitHub API

Table of contents

No heading

No headings in the article.

In this project, I am displaying a list of all my GitHub repositories and a details page for each repo. Here are the key features of the app. I also implemented error boundary to catch javascript errors within the app.

  • Pagination

  • SEO

  • Error Boundary

  • API fetch

  • Nested Routes

  • 404 page

First I initialized a new project using the create-react-app command, next I installed all the necessary packages I need to build the app.

react-helmet-async // to implement SEO
react-router-dom // for routing and nested routes
node-sass // I use scss for syling
react-icons // icons library

To get the list of repos, I sent a GET request to

`https://api.github.com/users/mo-renike/repos?sort=${sort.sort}&direction=${sort.order}&per_page=100`  
// mo-renike is my github username 

//I had set the sort and order states to be dynamic
//   const [sort, setSort] = useState({
//        sort: "created",
//        order: "desc",
//    });

The response sent to me in JSON format as seen below. You can check the endpoint here https://api.github.com/users/mo-renike/repos

0
: 
{id: 582022522, node_id: 'R_kgDOIrD1eg', name: 'portfolio', full_name: 'mo-renike/portfolio', private: false, …}
1
: 
{id: 580917524, node_id: 'R_kgDOIqAZFA', name: 'nest-app', full_name: 'mo-renike/nest-app', private: false, …}
2
: 
{id: 573953868, node_id: 'R_kgDOIjXXTA', name: 'methcreate', full_name: 'mo-renike/methcreate', private: false, …}
3
: 
{id: 562556135, node_id: 'R_kgDOIYfs5w', name: 'zc_main', full_name: 'mo-renike/zc_main', private: false, …}
4
: 
{id: 560920897, node_id: 'R_kgDOIW75QQ', name: 'ALTSch-FE-Exam', full_name: 'mo-renike/ALTSch-FE-Exam', private: false, …}

Here is how I choose to display the data

Each repo has an onClick function that links to a details page to get more information about the selected repo. To implement this, I used nested route and useParams to get the id of the selected repo. To get the details of the the repo I sent a new request to

`https://api.github.com/repos/mo-renike/<repoID>`

I build the details page using this data like this

To implement Pagination, first I set the number of repos to be displayed according to the page size. (this is a UX feature to prevent long scrolling for mobile devices)

   // set dynamic reposPerPage value according to screen size
    if (window.innerWidth <= 768) {
        var dynamicPerPage = 3;
    } else {
        dynamicPerPage = 6;
    }

    const [currentPage, setCurrentPage] = useState(1);
    const [reposPerPage] = useState(dynamicPerPage);
    const indexOfLastRepo = currentPage * reposPerPage;
    const indexOfFirstRepo = indexOfLastRepo - reposPerPage;
    const currentRepos = repos.slice(indexOfFirstRepo, indexOfLastRepo);

// paginate function to set the pages when ou click the buttons
    const paginate = (pageNumber) => {
        setCurrentPage(pageNumber);
        window.scrollTo({ top: 0, behavior: "smooth" });
    };

    // function to calculate page numbers
    const pageNumbers = [];
    for (let i = 1; i <= Math.ceil(repos.length / reposPerPage); i++) {
        pageNumbers.push(i);
    }

Implementing SEO was pretty straightforward using react-hemet-async

// first import package from the library 
import { Helmet } from "react-helmet-async";
  <Helmet>
                <title>Repos</title>
                <meta name="description" content="Github Repos" />
                <meta
                    name="keywords"
                    content="altschool, github api,SEO, react hooks,"
                />
   </Helmet>