Back to portfolio

Case Study

How I Built This Portfolio

Most portfolios are static pages with hardcoded data. This one is a production system — database-driven, SEO-first, and automated. Here's exactly how it's engineered.

Next.js 15App RouterTypeScriptTailwind CSSFramer MotionISRJSON-LDNetlify
01

The Problem with Static Portfolios

Standard portfolios hard-code project data in a TypeScript file. Adding a new project requires editing code, committing, and re-deploying. That's not how production systems work.

I wanted a portfolio where I could add a project from a README file in under 2 minutes — with full SEO, dynamic routing, and case-study pages generated automatically.

02

System Architecture

The portfolio is a hybrid static/dynamic Next.js 15 App Router application deployed on Netlify. Key architectural decisions:

  • Server Components for all data-fetching — zero client bundle cost for project data
  • Static project data in TypeScript — type-safe, no external DB dependency
  • ISR (revalidate: 3600) on project pages, daily on homepage
  • generateStaticParams() pre-renders all project slugs at build time
// app/projects/[slug]/page.tsx
export const revalidate = 3600;

export async function generateStaticParams() {
  const slugs = await getProjectSlugs();       // static project data
  return slugs.map((slug) => ({ slug }));       // pre-rendered at build time
}

export async function generateMetadata({ params }) {
  const project = await getProjectBySlug(params.slug);
  return {
    title: project.title,
    description: project.description,
    openGraph: { type: "article", ... },
  };
}
03

Project Data Architecture

The projects data schema was designed for two consumers: the UI and search engines.

// projects data schema (src/lib/appwrite/queries.ts)
{
  title:            string   // required
  slug:             string   // unique — used as URL path
  description:      string   // 160 chars max — used as meta description
  content:          string   // full case study text
  techStack:        string[] // e.g. ["Next.js", "MongoDB"]
  features:         string[] // bullet list for SEO + UI
  category:         enum     // saas | ai | ecommerce | fullstack | other
  status:           enum     // production | building | archived
  featured:         boolean  // controls homepage section
  problemStatement: string   // for case study UX
  githubUrl:        url      // optional
  liveUrl:          url      // optional
  createdAt:        datetime // ISO — used in sitemap lastModified
}

The queries layer wraps all data access with typed functions — making it easy to swap data sources without touching UI code.

04

SEO Strategy

Three layers of SEO — each one independently valuable:

  • Per-page generateMetadata() — title, description, canonical URL, OG image from project data
  • JSON-LD structured data — Person schema on homepage, SoftwareSourceCode schema on project pages
  • Dynamic sitemap.ts — includes all /projects/[slug] routes generated at build time
  • robots.ts — programmatic robots file allowing all pages, disallowing /api/
05

Why Static Data Over a Database

For a portfolio site, static data in TypeScript gives the best tradeoffs:

// Benefits of static project data:
// 1. Zero cold starts — no DB connection needed
// 2. Type-safe — TypeScript catches errors at build time
// 3. No external dependency — site never goes down
// 4. Instant builds — no network calls during SSG
// 5. Easy to update — just edit the array and deploy

Adding a new project means adding an object to the array and pushing to Git — Netlify auto-deploys in under 60 seconds.

06

Performance Decisions

  • System font stack — no Google Fonts network request, no layout shift
  • All data fetching in Server Components — zero client-side waterfall
  • ProjectFilter is the only client component — minimal JS hydration
  • next/image with explicit width/height everywhere — no CLS
  • RevealOnScroll uses Framer Motion useInView — no scroll event listeners
  • GitHub stats API cached at 1-hour revalidate — never blocks page render
  • Static fallback means the site works instantly with zero external dependencies
07

What This Demonstrates

This isn't about the tech choices. It's about the thinking:

  • System design before coding — schema decisions made for both UI and SEO needs
  • Resilient architecture — the system degrades gracefully, never breaks
  • Automation mindset — removing manual steps from repetitive workflows
  • Performance as a constraint — Lighthouse scores treated as requirements
  • SEO as engineering — structured data and canonical URLs are code, not configuration

Available Now

Looking for a Full Stack or Backend role

I'm actively looking for roles where I can build scalable systems, design clean APIs, and contribute to production applications. Open to full-time and contract work.

Udaipur, Rajasthan, India(+91) 7427837782

© 2026 Chirag Bhoi. Built with Next.js & Tailwind.