Creating a personal portfolio that blends music, visual art, and technology into one seamless experience was both thrilling and challenging. In this post, I’ll share the journey of building this site; from picking the stack to deploying it live.
Technology Stack
I built this portfolio with performance, flexibility, and aesthetics in mind:
- Framework: Next.js (v15) for hybrid rendering and seamless routing.
- Language: TypeScript to catch bugs early and improve dev speed.
- Styling: Tailwind CSS for utility-first styling and responsive design.
- Content: Markdown, powered by Gray Matter for metadata and
remark
for rendering. - Audio: WaveSurfer.js for interactive, customizable audio players.
- Deployment: Vercel with GitHub integration for instant CI/CD workflows.
Key Features
- Markdown Blog: Dynamic routes, metadata support, and tag filtering.
- Music Section: Waveform audio previews, collapsible lyrics, and release metadata.
- Art Gallery: Responsive layouts showcasing digital and traditional works.
- Theme Toggle: Light, Dark, Ocean, and more—customized via Tailwind config.
- Fully Responsive: Tailored UI for mobile, tablet, and desktop users.
Development Process
1. Setting Up the Project
npx create-next-app@latest portfolio --typescript
This bootstrapped a modern Next.js 15 project with TypeScript support right out of the gate.
2. Styling with Tailwind CSS
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init
Then I extended the tailwind.config.js
to include custom color themes and breakpoints.
3. Blog Functionality
Each post is written in Markdown with front matter:
---
title: "Post Title"
excerpt: "Short description of the post."
tags: ["Tag1", "Tag2"]
category: "Category"
---
gray-matter
parses this data, while remark
handles the rendering pipeline.
4. Music Portfolio
Using WaveSurfer.js, I added waveform-based audio players with custom themes:
import WaveSurfer from "wavesurfer.js";
const waveform = WaveSurfer.create({
container: "#waveform",
waveColor: "#7c3aed",
progressColor: "#9333ea",
height: 80,
responsive: true,
});
I eventually deprecated this feature, but found it fun to implement at the time.
5. Deployment with Vercel
Integrated with GitHub for continuous deployment:
git push origin main
Each push triggers an automatic build and deploy on Vercel.
Challenges and Lessons Learned
- Dynamic Routing: Next.js dynamic routes made things modular, but organizing slugs and file structures early was crucial.
- Type Safety: TypeScript's benefits really showed up in edge cases; worth the learning curve.
- Performance: Lazy loading images and audio components helped keep things snappy, even on slower connections.
- Content Management: Writing posts in Markdown worked well, but abstracting logic for front matter handling saved me headaches later.
Conclusion
This portfolio is more than a website; it's a reflection of my work, identity, and growth. Whether you're a developer, artist, or curious visitor, I hope this breakdown helps you craft something of your own.
Dive into the source code on GitHub, remix it, or reach out if you'd like to chat more.