How I Built A Basic Portfolio With GitHub API

After learning the fundamentals of fetching data from an API in ReactJS, I built a basic portfolio page to display my repository data from Github's REST API. This article covers:

  • the tools I used

  • how I implemented features

  • challenges I experienced

For the project, I made use of GET /users/<username>/repos endpoint, which allowed me to list all public repositories for a specific username. The endpoint gave me the first 30 public repositories from my GitHub profile. This project features these functionalities:

  • error boundary

  • nested routes

  • SEO

  • pagination

  • 404 page

The Setup

My react project was set up easily with vite in my vscode.

npm create vite@latest

npm create vite@latest my-react-app -- --template react

cd my-react-app

npm install
npm run dev

I used dependencies such as react-router-dom, react-error-boundary, react-helmet-async, react-icons, and react-spinners. The styling of the project was done with vanilla CSS.

Code Development

My approach for fetching the data from the API was with the async/await method. Async functions perform an asynchronous operation in JavaScript. Here's a quick rundown of the code;

  useEffect(() => {
    getProjects();
  }, []);

  const getProjects = async () => {
    try {
      const response = await fetch("https://api.github.com/users/lhorla/repos")
      const data = await response.json();
      setProjects(data);
      setLoading(false);
    } catch (error) {
      console.log("Something went wrong", error);
    }
  };

Pagination was implemented to show 10 projects per page, here's my code run down;

  const [projects, setProjects] = useState([]);
  const [loading, setLoading] = useState(true);
  const [currentPage, setCurrentPage] = useState(1);
  const [projectsPerPage] = useState(10);

  const totalProjects = projects.length;

  const indexOfLastProject = currentPage * projectsPerPage;
  const indexOfFirstProject = indexOfLastProject - projectsPerPage;
  const currentProjects = projects.slice(
    indexOfFirstProject,
    indexOfLastProject

  <Pagination
    projectsPerPage={projectsPerPage}
    totalProjects={totalProjects}
    currentPage={currentPage}
    setCurrentPage={setCurrentPage}
    loading={loading}
    className="pagination"
  />

For nested routes, I install react-router dom, using BrowserRouter to wrap the App.jsx component in the main.jsx file

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <ErrorBoundary>
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </ErrorBoundary>
  </React.StrictMode>
);

Error boundary code

class ErrorBoundary extends Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // You can also log the error to an error reporting service
    console.log(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return (
        <div className="errorboundary-container">
          <h1>Something went wrong.</h1>
          <a href="/">Go back to home</a>
        </div>
      );
    }

    return this.props.children;
  }
}

404 page

import { useRouteError } from 'react-router-dom';

function NotFound() {
    const error = useRouteError();
    return (
        <div>
            <h1>Oops!!!</h1>
            <p>Sorry, an unexpected error occured</p>
            <p>
                <i>{error.statusText} || {error.message}</i>
            </p>
        </div>
    );
}

A major challenge I encountered while building this project was implementing pagination and SEO. I ran into a lot of errors, but all thanks to Google and people I reached out, I was able to fix some of them.

Deployment

The project was deployed with Netlify. It is platform for hosting websites free. All I had to do was create a github repository and commit all my project, then I signed in on netlify.

Conclusion

This is my first react project using an API, react router dom, pagination and error boundary. I'm hoping to modify the project with a better UI and improved responsiveness, you can view the project live here. Feel free to drop your suggestions, I'll love to see the corrections I can make. Thanks for reading!