Personal Portfolio — The One You're Viewing Right Now

A trilingual Astro portfolio and blog built around one rule: publishing must never become a chore. Why I chose Astro over Nuxt, themed Bootstrap over Tailwind, Markdown over a CMS, and translated UI over translated content.

  • Astro
  • TypeScript
  • MDX
  • i18n
  • Bootstrap
  • Figma
  • Vercel
  • SSR
  • View Transitions
  • Problem: years of technical knowledge with nowhere to share it, and a résumé spread across five platforms.
  • Stack: Astro, TypeScript, Markdown content collections, Bootstrap themed with Sass, Vercel.
  • Key decision: translate the interface into three languages, but write each article only once.
  • Outcome: live, and the single place I send recruiters to.

The problem

After years building software for public administration and freelance clients, my knowledge was scattered across private notes and commit histories. I needed one place for three things: a technical blog, real projects with honest architectural context, and a living résumé for European recruiters, so I could stop updating five platforms by hand.

This case study lives inside the portfolio it describes.

Constraints

  • Three languages from day one: Portuguese, English, Spanish.
  • Publishing has to stay cheap. Once writing a post becomes a chore, it stops happening.
  • No framework lock-in, and code I can explain line by line in an interview.

Key decisions

1. Astro over Nuxt

Problem. A content-first site that can still host interactive components later, without betting on one UI framework.

Decision. Astro. A Nuxt 2 → 3 migration had left scars, and Astro’s islands let me add Vue, React or anything else later without a migration tax.

Why it holds. The site has since gone through major Astro upgrades with content and routing intact, and it ships almost no JavaScript.

2. Markdown in the repo, no CMS

Problem. Every step between an idea and a published post makes it less likely the post gets written.

Decision. Posts and case studies are Markdown files in the repository, checked against schemas at build time.

Why it holds. Publishing is a commit, and a broken field fails the build instead of reaching production.

3. Translate the interface, not the content

Problem. Translating every post into three languages would triple the cost of publishing.

Decision. The site shell (home, résumé, navigation) is fully translated. Articles are written once, and readers in other languages get a one-click machine-translation option.

Why it holds. What recruiters read first is native in all three languages, and the parts that change most stay cheap to publish.

4. Themed Bootstrap over Tailwind

Problem. I wanted to own the CSS fully, with a direct line from design tokens to code.

Decision. Design tokens were defined in Figma first, then wired into Bootstrap’s Sass variables.

Why it holds. The markup stays free of utility-class sprawl, and every style value matches a token in the design file.

Trade-offs

  • Partial translation: articles exist only in one language. Publishing regularly in one language beats never publishing in three.
  • No CMS: no editing from a phone, but publishing is just a file and a push.

Result

The portfolio is live at zwinglio.com. The résumé is the single source of truth for recruitment, and the blog is where technical write-ups finally have a home. A newsletter and a course platform can be added later without structural changes.