A Guide to Display Your GitHub Contribution Graph on Your Personal Website
This blog post will walk you through how to create a responsive GitHub contribution graph on your website, inspired by the implementation on this portfolio.
We'll cover how to achieve two key layout goals:
- A full-width, immersive view on desktop screens.
- A contained, horizontally scrollable view on mobile devices to maintain a clean layout.
You can see the final implementation in the src/components/github-contributions.tsx
file of this project.
Step 1: Fetching Your Contribution Data with the GitHub GraphQL API
The first step is to get your contribution data from GitHub. While you could scrape your profile page, a much more robust and reliable method is to use the GitHub GraphQL API. This provides a structured way to query for the exact data you need.
In src/components/github-contributions.tsx
, we use an async function to send a POST request to https://api.github.com/graphql
. The query is structured to fetch the contribution calendar for the past year.
Here's the GraphQL query used in the component:
query {
user(login: "${username}") {
contributionsCollection {
contributionCalendar {
totalContributions
weeks {
contributionDays {
date
contributionCount
color
}
}
}
}
}
}
To authenticate your request, you'll need a Personal Access Token (PAT) from GitHub with the read:user
scope. This token is then included in the Authorization header of your request.
Important: Never expose your PAT on the client-side. In this project, it's stored as an environment variable (NEXT_PUBLIC_GITHUB_TOKEN
) and used during the build process to fetch the data.
The fetched data provides an array of weeks, with each week containing an array of contributionDays
. Each day object includes the date, contributionCount
, and the color that GitHub uses for that day's activity level.
Step 2: Rendering the Contribution Graph
Once you have the contribution data, you can render it as a grid. In the renderContributionGraph
function within the component, the data is processed to create a grid of colored squares, with each square representing a day.
const renderContributionGraph = () => {
const days = contributions.slice(-365); // Last 365 days
const weeks = [];
for (let i = 0; i < days.length; i += 7) {
weeks.push(days.slice(i, i + 7));
}
return (
<div className="flex gap-1">
{weeks.map((week, weekIndex) => (
<div key={weekIndex} className="flex flex-col gap-1">
{week.map((day, dayIndex) => (
<div
key={dayIndex}
className="w-3 h-3 rounded-sm"
style={% raw %}{{
backgroundColor: day.color,
}}{% endraw %}
title={`${day.date}: ${day.contributionCount} contributions`}
/>
))}
</div>
))}
</div>
);
};
This function organizes the days into weeks and then maps over them to create a grid of div elements. Each div is styled with the background color provided by the GitHub API, and a title attribute is added to show the date and contribution count on hover.
Step 3: Implementing a Responsive Layout
This is where we address the two key layout goals. The component uses a responsive design approach to provide an optimal viewing experience on both desktop and mobile.
Full-Width on Desktop
On larger screens, we want the contribution graph to be fully visible. The component uses Tailwind CSS's responsive prefixes (md:
) to apply different styles for desktop.
// In src/components/github-contributions.tsx
{/* Desktop: Full width with left-aligned graph */}
<div className="hidden md:block bg-card border rounded-lg p-6">
{/* ... legend ... */}
<div className="flex justify-start">
{renderContributionGraph()}
</div>
</div>
The hidden md:block
class ensures that this container is only visible on medium-sized screens and up. Inside, the graph is simply rendered within a flex container, allowing it to expand to its natural width.
Scrollable on Mobile
On smaller screens, a full-width graph would overflow and break the layout. To solve this, we wrap the graph in a container with overflow-x-auto
.
// In src/components/github-contributions.tsx
{/* Mobile: Fixed width container with scrollable graph */}
<div className="md:hidden w-full max-w-4xl">
<div className="bg-card border rounded-lg p-4">
{/* ... legend ... */}
<div className="overflow-x-auto">
<div className="flex justify-center min-w-[600px]">
{renderContributionGraph()}
</div>
</div>
</div>
</div>
Here's a breakdown of the mobile layout:
md:hidden
: This ensures the container is only visible on screens smaller than themd
breakpoint.overflow-x-auto
: This is the key. It tells the browser to create a horizontal scrollbar if the content inside (renderContributionGraph
) is wider than the container.min-w-[600px]
: We set a minimum width on the inner container to ensure that the graph doesn't get squished, even on very narrow screens. This forces theoverflow-x-auto
to activate and create the scrollbar.
This approach provides a clean and user-friendly experience on all devices, presenting the full graph on desktop while keeping it neatly contained on mobile.
Conclusion
By following these steps, you can create a dynamic and visually appealing GitHub contribution graph for your own personal website, showcasing your dedication and passion for coding. The responsive design ensures that your contribution graph looks great and functions well on any device, from mobile phones to large desktop monitors.
The key takeaways are:
- Use the GitHub GraphQL API for reliable data fetching
- Implement responsive design with different layouts for desktop and mobile
- Use horizontal scrolling on mobile to maintain the full graph visibility
- Always keep your API tokens secure and never expose them on the client-side
This implementation provides a professional way to showcase your GitHub activity and coding consistency to visitors of your personal website.