The GitHub Contributions component displays a GitHub-style contribution graph showing coding activity over time.
Overview
Location: src/app/components/sections/GithubContributions.tsx
This component integrates the react-github-calendar library to visualize GitHub contribution data in the familiar heatmap calendar format.
Implementation
import React, { useEffect, useState } from "react";
import GitHubCalendar from "react-github-calendar";
const GithubContributions: React.FC = () => {
const [loading, setLoading] = useState(true);
useEffect(() => {
const timer = setTimeout(() => {
setLoading(false);
}, 0);
return () => clearTimeout(timer);
}, []);
return (
<div
className="flex py-2 px-3 max-lg:col-span-1 max-lg:row-span-1 col-span-4 row-span-2 col-start-1 row-start-7 bg-spotify-light-dark rounded-xl h-fit"
id="contribution"
>
{loading ? (
<div className="rounded-md p-4 max-w-lg w-full mx-auto">
<div className="animate-pulse flex space-x-4">
<div className="flex-1 space-y-6 py-1">
<div className="h-2 bg-spotify-green rounded"></div>
<div className="space-y-3">
<div className="grid grid-cols-3 gap-4">
<div className="h-2 bg-spotify-green rounded col-span-2"></div>
<div className="h-2 bg-spotify-green rounded col-span-1"></div>
</div>
<div className="h-2 bg-spotify-green rounded"></div>
</div>
</div>
</div>
</div>
) : (
<div className="w-full items-center content-center justify-center justify-items-center">
<GitHubCalendar
username="LuaanNguyen"
blockSize={11}
blockMargin={2}
fontSize={12}
colorScheme="dark"
theme={{
dark: ['#161616', '#0e4429', '#006d32', '#26a641', '#39d353'],
light: ['#ebedf0', '#9be9a8', '#40c463', '#30a14e', '#216e39']
}}
/>
</div>
)}
</div>
);
};
export default GithubContributions;
Features
Loading State
The component displays a skeleton loader while the GitHub calendar data loads:
const [loading, setLoading] = useState(true);
useEffect(() => {
const timer = setTimeout(() => {
setLoading(false);
}, 0);
return () => clearTimeout(timer);
}, []);
The setTimeout with 0ms delay ensures the loading state is displayed briefly, even if data loads instantly, preventing layout shift.
Skeleton Loader Design
<div className="rounded-md p-4 max-w-lg w-full mx-auto">
<div className="animate-pulse flex space-x-4">
<div className="flex-1 space-y-6 py-1">
<div className="h-2 bg-spotify-green rounded"></div>
<div className="space-y-3">
<div className="grid grid-cols-3 gap-4">
<div className="h-2 bg-spotify-green rounded col-span-2"></div>
<div className="h-2 bg-spotify-green rounded col-span-1"></div>
</div>
<div className="h-2 bg-spotify-green rounded"></div>
</div>
</div>
</div>
</div>
The skeleton uses animate-pulse for a smooth loading animation with Spotify-green placeholder bars.
GitHub Calendar Configuration
GitHub username to fetch contribution data forExample: "LuaanNguyen"
Size of each contribution square in pixels
Spacing between contribution squares in pixels
Font size for calendar labels (month names, days)
colorScheme
'light' | 'dark'
default:"dark"
Color scheme for the calendar (matches site theme)
Custom color palette for contribution levels
Color Theme
The component uses a custom dark theme matching GitHub’s contribution graph:
theme: {
dark: [
'#161616', // Level 0: No contributions (darkest)
'#0e4429', // Level 1: Low contributions
'#006d32', // Level 2: Medium-low contributions
'#26a641', // Level 3: Medium-high contributions
'#39d353', // Level 4: High contributions (brightest green)
],
light: [
'#ebedf0', // Light theme fallback
'#9be9a8',
'#40c463',
'#30a14e',
'#216e39'
]
}
The dark theme colors progress from dark grey (no activity) to bright green (high activity), providing clear visual feedback on contribution frequency.
Grid Layout
Desktop Layout
.github-contributions {
grid-column: span 4; /* Takes 4 columns */
grid-row: span 2; /* Takes 2 rows */
grid-column-start: 1; /* Starts at column 1 */
grid-row-start: 7; /* Starts at row 7 */
}
Mobile Responsive
max-lg:col-span-1 max-lg:row-span-1 /* Single cell on tablet/mobile */
Styling
Container Styles
/* Main container */
.github-contributions {
display: flex;
padding: 0.5rem 0.75rem; /* py-2 px-3 */
background: #121212; /* bg-spotify-light-dark */
border-radius: 0.75rem; /* rounded-xl */
height: fit-content; /* h-fit */
}
/* Inner container */
.calendar-wrapper {
width: 100%;
align-items: center;
justify-content: center;
justify-items: center;
}
Skeleton Loader Styles
/* Skeleton container */
.skeleton {
border-radius: 0.375rem; /* rounded-md */
padding: 1rem; /* p-4 */
max-width: 32rem; /* max-w-lg */
width: 100%;
margin: 0 auto; /* mx-auto */
}
/* Pulse animation */
@keyframes pulse {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
.animate-pulse {
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
Data Source
The component fetches contribution data from GitHub’s public API via the react-github-calendar library:
https://github-contributions-api.jogruber.de/v4/{username}
No authentication is required as it uses publicly available contribution data from the GitHub profile.
Calendar Features
The GitHub calendar displays:
- 12 months of contribution history
- Week labels (Mon, Wed, Fri)
- Month labels across the top
- Hover tooltips showing contribution count for each day
- Responsive sizing that adapts to container width
Contribution Levels
The calendar uses 5 intensity levels:
| Level | Color | Description |
|---|
| 0 | #161616 | No contributions |
| 1 | #0e4429 | 1-3 contributions |
| 2 | #006d32 | 4-6 contributions |
| 3 | #26a641 | 7-9 contributions |
| 4 | #39d353 | 10+ contributions |
The exact contribution thresholds are determined by GitHub’s algorithm and may vary.
Error Handling
The react-github-calendar library handles API errors gracefully:
- Network failures show empty calendar
- Invalid usernames display error message
- Rate limiting is handled automatically
Lazy Loading
The component can be lazy-loaded to improve initial page load:
import dynamic from 'next/dynamic';
const GithubContributions = dynamic(
() => import('./sections/GithubContributions'),
{ ssr: false }
);
Cleanup
The component properly cleans up timers on unmount:
useEffect(() => {
const timer = setTimeout(() => {
setLoading(false);
}, 0);
return () => clearTimeout(timer); // Cleanup
}, []);
Dependencies
{
"react": "useState, useEffect hooks",
"react-github-calendar": "GitHub contribution calendar component"
}
Library Version
Install the required package:
npm install react-github-calendar
Accessibility
- Calendar includes ARIA labels for screen readers
- Keyboard navigation supported
- Semantic HTML structure
- High contrast colors for visibility
- Focus indicators on interactive elements
Customization Options
To customize the calendar appearance:
Adjust blockSize and blockMargin props:blockSize={15} // Larger squares
blockMargin={4} // More spacing
Modify the theme colors:theme={{
dark: ['#1a1a1a', '#1DB954', '#1DB954', '#1AA34A', '#0D7D31']
}}
Change font size:fontSize={14} // Larger text