A modern, performant personal portfolio and blog built with Next.js 15, React 19, and Tailwind CSS. Migrated from Hugo to leverage Next.js features while preserving the original design aesthetic.
- Framework: Next.js 15 (App Router)
- React: 19
- Language: TypeScript 5 (strict mode)
- Styling: Tailwind CSS 3 + CSS Variables
- Content: Velite (Type-safe content management)
- Fonts: Next.js Font Optimization (Plus Jakarta Sans, Lora, JetBrains Mono, Caveat)
- Deployment: Vercel
- Package Manager: Bun
- Analytics: Vercel Analytics & Speed Insights
- 14px base font with 18px body text matching original Hugo design
- Serif typography (Lora) for body text, sans-serif (Plus Jakarta Sans) for headings
- Light gray background (#f5f5f5) matching Hugo aesthetic
- Design tokens via CSS variables for colors, spacing, typography
- Text selection styling with wavy underline effect
- Dark mode support with Next.js themes
- Year Progress Bar - Dynamic footer showing percentage of year completed
- Reading Progress Bar - Scroll-based progress indicator on blog posts
- Guitar Easter Egg - Click "the guitar" text to play C Major chord via Web Audio API
- Smooth transitions and hover effects throughout
- Lazy loading - GuitarEasterEgg dynamically imported for smaller initial bundle
- Strategic prefetching - Important links prefetch, less critical don't
- Loading states - Skeleton screens on
/posts
and/posts/[slug]
- Image optimization - Next.js Image component with automatic optimization
- Server Components - RSC by default, client components only where needed
- Static generation - All pages pre-rendered at build time
- Type-safe content with Velite
- Markdown support with rehype plugins (slug, autolink headings, syntax highlighting)
- Featured posts badge system
- Tag system for categorization
- Date formatting utility for consistent display
.
โโโ app/
โ โโโ (marketing)/ # Marketing layout group
โ โ โโโ page.tsx # Home page
โ โ โโโ posts/
โ โ โโโ page.tsx # Blog listing
โ โ โโโ loading.tsx # Loading skeleton
โ โ โโโ [slug]/
โ โ โโโ page.tsx # Blog post detail
โ โ โโโ loading.tsx
โ โโโ layout.tsx # Root layout
โ โโโ globals.css # Global styles & CSS variables
โ โโโ not-found.tsx # Custom 404 page
โโโ components/
โ โโโ ui/ # shadcn/ui components
โ โโโ layout/ # Layout components (Header, Footer, SideMenu)
โ โโโ post-card.tsx # Reusable post card
โ โโโ reading-progress.tsx # Reading progress bar
โ โโโ guitar-easter-egg.tsx # Guitar sound easter egg
โ โโโ theme-toggle.tsx # Dark mode toggle
โโโ lib/
โ โโโ utils/
โ โโโ date.ts # Date formatting utility
โโโ content/
โ โโโ posts/ # Markdown blog posts
โโโ public/
โ โโโ images/ # Static images
โโโ velite.config.ts # Content configuration
- Background:
#f5f5f5
(light gray) - Foreground:
#404040
(dark gray) - Primary:
#007bff
(blue) - Secondary:
#737373
(gray) - Border:
#e5e5e5
(light border)
- Background:
#1a1a1a
(near black) - Foreground:
#ddd
(light gray) - Primary:
#66b0ff
(light blue) - Secondary:
#aaa
(gray) - Border:
#333
(dark border)
- Base: 14px (html), 18px (body)
- Text sizes via CSS variables:
--text-xs
through--text-4xl
- Line heights: tight (1.2), snug (1.4), normal (1.6), relaxed (1.75)
8pt grid system: --spacing-xxs
(2px) through --spacing-3xl
(64px)
- Bun (recommended) or Node.js 18+
- Git
# Clone repository
git clone https://github.com/harshfolio/harshfolio.github.io.git
cd harshfolio.github.io/.worktrees/nextjs-beta
# Install dependencies
bun install
# Run development server
bun run dev
# Open http://localhost:3000
bun run dev # Start development server
bun run build # Build for production
bun run start # Start production server
bun run lint # Run ESLint
bun run format # Format with Prettier
bun run type-check # TypeScript type checking
- Create a new
.md
or.mdx
file incontent/posts/
:
---
title: "Your Post Title"
description: "Brief description"
date: "2025-01-22"
published: true
featured: false
tags: ["tag1", "tag2"]
---
Your content here...
- Run
bun run dev
- Velite will automatically process the content - Access at
/posts/your-post-title
- title: Post title (required)
- description: SEO description (optional)
- date: Publication date YYYY-MM-DD (required)
- published: Boolean, false hides post (default: true)
- featured: Shows "Featured" badge (default: false)
- tags: Array of tag strings (optional)
- Push to GitHub
- Import repository in Vercel
- Framework: Next.js
- Build command:
bun run build
(or use default) - Deploy
No environment variables required for basic deployment. Optional:
- Analytics automatically enabled on Vercel
- โ Original design aesthetic (colors, typography, spacing)
- โ Light gray background (#f5f5f5)
- โ Serif body text, sans-serif headings
- โ Text selection with wavy underline
- โ Year progress bar in footer
- โ Reading progress on blog posts
- โ Guitar sound easter egg
- โ Asterisk logo with rotation effect
- โ Dark mode support
- โก Faster page loads with Next.js optimization
- ๐ฏ Better SEO with Metadata API
- ๐ฆ Smaller bundle size with code splitting
- ๐ Loading states for better UX
- ๐ผ๏ธ Automatic image optimization
- ๐ฑ Better mobile performance
- ๐ Type-safe content with Velite
- โฟ Better accessibility
- Velite over Contentlayer - Active maintenance, better type safety
- CSS Variables + Tailwind - Design tokens + utility classes
- Server Components first - Performance, only use client components when needed
- Dynamic imports - Code splitting for non-critical features
- Strategic prefetching - Balance UX and performance
Issue: webkitAudioContext
type errors in Vercel build
Solution: Use optional type { webkitAudioContext?: typeof AudioContext }
with guard
Issue: Body text appearing 10px instead of 18px
Solution: Set both html { font-size: 14px }
and body { font-size: 18px }
Issue: Pure white instead of light gray
Solution: Use --background: 0 0% 96%
(HSL for #f5f5f5)
Build output showing optimized bundle sizes:
Route (app) Size First Load JS
โ โ / 1.33 kB 107 kB
โ โ /posts 165 B 105 kB
โ โ /posts/[slug] 657 B 103 kB
- โ All routes under 110 kB first load
- โ Lazy-loaded easter egg reduces initial bundle
- โ Static generation for instant page loads
Potential improvements for consideration:
- Add RSS feed generation
- Implement view counts
- Add search functionality
- Table of contents for long posts
- Related posts suggestions
- Code block copy button
- Comments system (giscus?)
- OG image generation
All rights reserved ยฉ 2025 Harsh Sharma
- Original Hugo theme inspiration
- Next.js team for excellent documentation
- Vercel for hosting platform
- shadcn/ui for component patterns