Building My Portfolio Website: React, Vercel, and Client-Side Markdown
From a blank repo to a deployed multilingual portfolio with a markdown blog — what I built, the decisions I made, and what I'd do differently.
TL;DR Technical Overview: React-based portfolio with CI/CD via Vercel.
- Client-side markdown parsing for blog posts (no backend, no CMS)
- Trilingual support (EN / NO / UK) with client-side language context
- Dedicated routes for project gallery and blog
- No backend infrastructure — static generation and frontend routing
Starting point
Every portfolio starts the same way: you buy a domain and then figure out what to actually put on it.
I chose React, which is overkill for a static portfolio. That was a deliberate call — I wanted experience with component-based architecture and a real deployment pipeline, not just a static HTML file. Everything runs on Vercel, which handles CI/CD automatically: push to main, site deploys. No manual uploads, no FTP.
The first version was minimal. A single-page CV with the basics. But it was live, it had my name on it, and I could find it on Google by typing the domain. That was enough to keep going.
Building it out
Once the foundation was in place, I started adding real features:
- Navigation bar with dedicated client-side routes for each section
- Project gallery page for 3D design work
- Blog section with markdown parsing
- Language switcher supporting English, Norwegian, and Ukrainian
The multilingual support was the most interesting to implement. Rather than spinning up a backend or using a translation service, I handled it client-side with a language context that persists across navigation. Three complete content sets, one component tree, no server involved.
The blog
The blog runs on client-side markdown parsing. No backend, no CMS, no database — markdown files live in the public folder and a parser renders them at runtime. The tradeoff is no server-side rendering for blog content, but for a personal portfolio the performance difference is negligible, and the authoring workflow is simple: write a .md file, push, done.
The main challenge after getting it working was formatting. Initial versions had too much whitespace, uneven spacing, inconsistent heading sizes. Several rounds of CSS adjustments later, it reads cleanly.
What I actually learned
The most useful thing was building something that needed to work and look good under real conditions, not just pass a tutorial. Component architecture forces you to think about what's reusable and what isn't. Deployment pipelines stop being abstract when you misconfigure one and your site breaks.
Scope creep is real. Features that seemed important early — animations, dark mode, extra pages — kept getting deprioritized in favor of things that were actually useful. The multilingual support made the cut. Animated transitions did not.
The site is functional, loads fast, and does what it needs to do. Future work will be content, not features.