[ ← BACK TO NOTES INDEX ]
FIELD NOTE // BUILD LOG
2026-02-256 min read

Building a Case Study System Instead of a Project Gallery

How I designed a schema-backed project case study architecture in Next.js to provide verified technical proof for freelance clients.

#Next.js App Router#Dynamic Routes#TypeScript#Case Studies

01. THE CONTEXT

Standard web galleries show thumbnail images and bullet points. They fail to explain why a project was built, what problems were solved, what architectural decisions were made, or what source code supports the claims.

02. THE APPROACH

I replaced generic gallery cards with a structured, schema-backed case study system. Project data is defined in `data/projects.ts` using a strict TypeScript `Project` interface. Dynamic App Router routes (`app/projects/[slug]/page.tsx`) render comprehensive case study documents detailing Problem, Approach, Technical Execution, and The Resulting System.

03. THE IMPLEMENTATION

The case study architecture separates project data definitions from layout rendering components.

Centralized TypeScript Project Schema

Every project in `data/projects.ts` includes structured technical attributes: slug, title, category, shortDescription, description, technologies, whyItExists, problem, approach, implementation, result, and lessons.

export interface Project {
  slug: string;
  title: string;
  category: string;
  shortDescription: string;
  description: string;
  technologies: string[];
  liveUrl: string | null;
  githubUrl: string | null;
  whyItExists: string;
  problem: string | null;
  approach: string;
  implementation: string;
  result: string;
  lessons: string | null;
}

// Strict interface definitions enforce consistent engineering documentation across all portfolio case studies.

Static Route Generation & Layout Decoupling

Static params generation statically compiles every case study at build time, while delegating visual layout rendering to the shared `CaseStudyBody` component.

export async function generateStaticParams() {
  return projectsData
    .filter((project) => project.slug !== "modern-calculator")
    .map((project) => ({ slug: project.slug }));
}

export default function ProjectPage({ params }: ProjectPageProps) {
  const project = projectsData.find((p) => p.slug === params.slug);
  if (!project) notFound();

  return <CaseStudyBody project={project} />;
}

// Static page generation delivers fast page loads while maintaining zero duplicate code across case study routes.

04. WHAT CHANGED (VERIFIED)

  • Replaced simple image grid galleries with a centralized TypeScript project data model.
  • Created dynamic case study routes with static page generation (`generateStaticParams`).
  • Added visible breadcrumbs and structured `BreadcrumbList` JSON-LD schemas to all project pages.

05. WHAT I LEARNED

  • Presenting real technical problems, trade-offs, and source code links establishes far higher credibility with potential freelance clients than simple image galleries.
  • Decoupling project data from rendering components makes adding future case studies fast and error-free.

Related Case Studies:

Tactile Portfolio Website

A Next.js developer portfolio with a custom dark tactile desk-themed visual design system and real Spotify integration.

[ READ CASE STUDY → ]

Modern Calculator

A fully functional calculator with keyboard support, clean gradient UI, and all basic mathematical operations.

[ READ CASE STUDY → ]

AI Multi-Module System

A modular AI system supporting multiple AI-powered functionalities through independent, reusable Python modules.

[ READ CASE STUDY → ]

HAVE A SIMILAR PROJECT IN MIND?

Send me your brief. Let's discuss how to apply clean engineering solutions to your website or web application.

let me know what you're building