Personal Dashboard
A real-time dashboard built with Next.js featuring live weather, GitHub stats, Hacker News feed, uptime monitoring, and a dynamic clock against an animated city skyline — deployed on Vercel
Tech Stack
Context
The Problem
Checking multiple services — weather, GitHub activity, tech news, and site health — requires constant tab switching that breaks focus and productivity.
Constraints
- API keys must never be exposed to the client
- External API calls should be minimized to stay within free tier limits
- Must be responsive across mobile and desktop
- Clock component must avoid hydration mismatches in Next.js SSR
- Background video must not bloat the repo size
Stakes
Portfolio project demonstrating Next.js App Router, TypeScript, API route design, server-side caching, parallel async patterns, and production deployment on Vercel
My Role
Title
Full-Stack Developer
Team
Personal Project
Ownership
End-to-end ownership: architecture, API route design, widget development, caching strategy, UI design, and Vercel deployment
Approach & Key Decisions
Built a Next.js 16 App Router application with server-side API routes proxying OpenWeatherMap, GitHub REST API, and Hacker News Algolia API. Each widget is an independent component with its own data fetching and error handling. Site status monitoring runs parallel health checks via Promise.all(). An animated city skyline video with frosted glass card effects provides the visual layer.
Server-side API routes to proxy all external API calls
Keeps API keys out of the browser entirely. The client only ever calls internal Next.js routes, never third-party APIs directly.
Per-endpoint response caching via Next.js revalidate (30min weather, 1hr GitHub)
Reduces redundant external API calls and keeps the app within free tier limits while still serving reasonably fresh data.
Parallel health checks using Promise.all() for the site status monitor
Fires all uptime checks simultaneously rather than sequentially, keeping the status widget fast regardless of how many endpoints are monitored.
Hydration-safe clock with client-only rendering via useEffect
Avoids server/client HTML mismatches — a common SSR pitfall in Next.js — by deferring time rendering until after client mount.
External video hosting on GitHub Releases for the animated background
Keeps the repo lightweight while still delivering the animated city skyline. Frosted glass (backdrop-blur) cards sit over the video for a polished UI.
Alternatives Considered
Considered fetching data client-side with SWR but server-side caching via Next.js route handlers provides better credential security and reduces client bundle size
Challenges & Solutions
⚠Challenge
Exposing API keys in a client-rendered app would be a security risk
✓Solution
Implemented server-side Next.js API routes to proxy all external API calls, keeping credentials exclusively on the server
⚠Challenge
Real-time clock caused React hydration errors due to server/client timestamp mismatch
✓Solution
Used a hydration-safe pattern: initialized clock state to null on the server and set the live time only after client mount via useEffect
⚠Challenge
Multiple widgets hitting external APIs on every page load risked rate limiting
✓Solution
Added response caching at the API route level via Next.js revalidate — weather caches for 30 minutes, GitHub stats for 1 hour
⚠Challenge
Site status checks running sequentially would slow down the widget
✓Solution
Used Promise.all() to fire all health checks in parallel, keeping response times fast regardless of the number of monitored endpoints
⚠Challenge
Including a background video in the repo would inflate its size
✓Solution
Hosted the animated city skyline video on GitHub Releases and referenced it externally, keeping the repo lean
Outcomes & Impact
Live Demo
Deployed at personal-dashboard-khaki.vercel.app with automatic CI/CD from the main branch
API Security
Zero client-side API key exposure — all secrets handled server-side via Next.js route handlers
Widgets
6 independent widgets: live clock, weather with city search, GitHub profile stats, Hacker News feed (top 8), site status monitor, and time-based greeting
TypeScript Coverage
95.3% TypeScript across the codebase
Responsive Layout
CSS Grid adapting from 1 column on mobile to 3 columns on desktop using Tailwind CSS 4