Personal Portfolio & Consulting Site
This site. Migrated from a Vite SPA to Next.js after identifying real architectural constraints — Contentful token exposure, SEO, and edge runtime limitations.
The Problem
Problem: I needed a site that worked for two audiences at once — freelance clients evaluating me for contract work, and recruiters evaluating me for full-time roles — without compromising on either.
Approach
Started with a Vite + React SPA, then migrated to Next.js after identifying three concrete problems: the Contentful API token would be exposed client-side, a pure SPA would hurt SEO for a site meant to be found by search, and the contact form had no clean server-side path without a third-party workaround. Next.js solved all three — server components keep the Contentful token server-side, API routes handle the contact form in the same repo, and server-rendered HTML fixes the SEO problem.
Tech Decisions
Case study content lives in Contentful as a headless CMS, fetched server-side only. Everything else — services, project metadata, stack — lives in typed static data files, deliberately avoiding CMS coupling for content that doesn't need it. I also attempted a Cloudflare Workers deployment and hit a real ecosystem constraint — their Next.js adapter doesn't yet support Next.js 15 — so I diagnosed the root cause and moved to Vercel, which has first-class support. The contact form itself moved from Nodemailer over SMTP to Mailgun's HTTP API, since SMTP requires a Node.js runtime and an HTTP call is portable to any environment.
Outcome
A site that's fast, server-rendered, and architecturally defensible in an interview — every non-default decision was made against a real constraint, not a preference.