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)