HOMEABOUTPROJECTS

Portfolio Website

2024-2026Code
Next.jsTypeScriptTailwind CSSReact

Project Overview

This portfolio website was built to document engineering projects and provide a central place to share technical work. It uses a data-driven architecture where each project is defined in a structured TypeScript file, making it easy to add new content.

  • Data-driven content — projects defined as structured TypeScript objects
  • Responsive design — works on phones, tablets, and desktops
  • Dynamic routing — each project gets its own URL automatically

Tech Stack

The site uses a modern web stack with Next.js for routing and static generation, TypeScript for type safety, and Tailwind CSS for styling.

  • Next.js 14 — React framework with file-based routing and static generation
  • TypeScript — type-safe development with compile-time error checking
  • Tailwind CSS — utility-first CSS framework
  • React — component-based UI architecture
TypeScript interfaces keep project data consistent
1// Each project is a typed object
2export interface Project {
3    title: string;
4    subtitle?: string;
5    media: string;
6    tags?: string[];
7    section: Section[];
8}

Architecture

The architecture follows a data-driven approach where each project is defined as a structured TypeScript object. This separation of content from presentation allows for easy updates and ensures consistency across all project pages.

Next.js App Router file structure
1src/app/
2├── components/
3│   ├── data/projects/   # Project content files
4│   ├── project/         # Page components
5│   ├── resume/          # Resume components
6│   └── shared/          # Reusable UI components
7├── projects/
8│   ├── page.tsx         # Project gallery
9│   └── [projectTitle]/  # Dynamic routes
10└── resume/

Dynamic routing with Next.js allows each project to have its own URL (e.g., /projects/multi-robot-frontier-exploration) while sharing a common page template. The project data is fetched based on the URL slug and rendered using reusable section components.

Content System

Rather than using a traditional CMS or database, the site employs a content-as-code approach. Each project is a TypeScript file exporting a structured object that defines all content blocks: text, images, videos, code snippets, and math equations.

Project definition with typed content blocks
1// Adding a new project = creating a new file
2export const myProject: Project = {
3    title: "Project Name",
4    media: "/media/videos/demo.mp4",
5    section: [
6        {
7            title: "Overview",
8            navRef: "overview",
9            content: [
10                { type: "text", content: "Description..." },
11                { type: "image", content: "/media/images/fig.png" },
12            ],
13        },
14    ],
15};

Benefits

  • Version controlled — all content changes tracked in Git
  • Type safe — TypeScript catches errors at compile time
  • No external dependencies — no database or CMS to maintain
  • IDE support — autocomplete and error highlighting

UI Components

The UI uses a dark theme with responsive layouts built using Tailwind's breakpoint utilities.

Tailwind handles responsive breakpoints
1// Responsive grid: 1 column on mobile, 3 on desktop
2<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
3    {projects.map((project) => (
4        <ProjectCard key={project.title} {...project} />
5    ))}
6</div>

Features

  • Sticky sidebar — navigation follows scroll position
  • Section highlighting — sidebar indicates current section
  • Lazy-loaded media — videos load on scroll
  • Dark theme — dark color scheme throughout

Performance

The site leverages Next.js features for performance: static generation, automatic image optimization, and code splitting.

  • Static generation — pages built once, served fast
  • Image optimization — Next.js auto-converts to WebP
  • Code splitting — each page loads its own bundle
  • Lazy video loading — videos wait until you scroll to them

Challenges

Key challenges addressed during development:

  • Dynamic routing with static content — mapping URL slugs to project data files while maintaining type safety
  • Consistent styling — unified component system for different content types (text, images, video, code)
  • Media organization — structured folder system for images, videos, and files

Future Work

Potential future additions:

  • Blog section — longer-form technical writing
  • Search — full-text search across projects
  • Interactive demos — embedded simulations for select projects

Conclusion

The data-driven architecture makes it straightforward to add new projects—each one is just a new TypeScript file following the same structure. All project pages use the same component system shown here.