DEV Community

Cover image for How to make a repos portfolio Next.JS
Reid Burton
Reid Burton

Posted on

How to make a repos portfolio Next.JS

If you want to make a simple page that displays your GitHub repos, then is this the tutorial for you! First make a Next.JS project (for faster install times, add the --use-pnpm flag.) Make sure to add tailwind css. Then, open it in your favorite editor, I will be using vscode for this tutorial. after that add the code

"Use Client";
Enter fullscreen mode Exit fullscreen mode

to the top of your file. Then add these imports:

import { useEffect, useState } from "react";
import Link from "next/link";
import Image from "next/image";
Enter fullscreen mode Exit fullscreen mode

to import the proper things. In the page component add:

const [repos, setRepos] = useState<
    { name: string; description: string; id: number }[]
  >([]);
  const [emojis, setEmojis] = useState<{ [key: string]: string }>({});
Enter fullscreen mode Exit fullscreen mode

So that the title and description can be parsed correctly. Then add a constant named "username" and set it to your username as a string. After which, we fetch the repos & emojis from the GitHub api:

useEffect(() => {
    async function fetchRepos() {
      try {
        const response = await fetch(
          `https://api.github.com/users/${username}/repos`,
        );
        const data = await response.json();
        const formattedRepos = data.map(
          (repo: { name: string; description: string; id: number }) => ({
            name: repo.name || "No name available",
            description: repo.description || "No description available",
            id: repo.id,
          }),
        );
        setRepos(formattedRepos);
      } catch (error) {
        console.error("Error fetching repos:", error);
      }
    }

    async function fetchEmojis() {
      try {
        const response = await fetch("https://api.github.com/emojis");
        const data = await response.json();
        setEmojis(data); // Store emojis as key-value pairs
      } catch (error) {
        console.error("Error fetching emojis:", error);
      }
    }

    fetchRepos();
    fetchEmojis();
  }, []);
Enter fullscreen mode Exit fullscreen mode

And then, add the code that renders the emojis:

const renderWithEmojis = (text: string) => {
    const parts = text.split(/(:\w+:)/g); // Split text by emoji shortcodes
    return parts.map((part, index) => {
      if (
        part.startsWith(":") &&
        part.endsWith(":") &&
        emojis[part.slice(1, -1)]
      ) {
        return (
          <Image
            key={index}
            src={emojis[part.slice(1, -1)]}
            alt={part}
            title={part}
            width={0}
            height={0}
            className="w-[1em] h-[1em] inline"
            loading="eager"
          />
        );
      }
      return <span key={index}>{part}</span>;
    });
  };
Enter fullscreen mode Exit fullscreen mode

And lastly, add this code in the return for the page function:

<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
        {repos.map((repo) => (
          <div
            key={repo.id}
            className="border p-4 rounded border-black dark:border-white"
          >
            <h2 className="text-xl">
              <Link href={`https://github.com/${username}/${repo.name}/`}>
                {repo.name}
              </Link>
            </h2>
            <p className="hidden md:block">
              {renderWithEmojis(repo.description)}
            </p>
          </div>
        ))}
      </div>
Enter fullscreen mode Exit fullscreen mode

And you're Done! Now you should have a page that dispays all of your public repos!

Top comments (0)