Skip to content
Milian Lastre ZequeiraEN
Web· Design, code and content· 2026

saintmilian.com — this site

The site you're reading. Two languages, no CMS, no bought template. I designed it, built it and write it.

Next.js 16TypeScriptTailwind CSS 4next-intlVeliteMDXResendVercel
Concept view

This is the site you are reading. I designed it, built it, and write it — no CMS, no bought template.

The problem

A bilingual editorial site competing for organic search can't improvise its i18n. Every post needs its language sibling correctly linked (reciprocal hreflang + x-default), a stable canonical URL, and content that validates at build time, not in production.

The approach

  • Next.js 16 App Router with proxy.ts (the Next 16 rename of middleware) driving next-intl routing.
  • Type-safe content layer with Velite: every frontmatter block is Zod-validated and types are generated into .velite/. An invalid post breaks the build, not the site.
  • hreflang per translation pair: each post carries a translationKey; from it I derive alternates.languages in generateMetadata and in sitemap.ts.
  • SEO as an invariant: dynamic OG via /api/og, per-page JSON-LD, and a sitemap with per-locale alternates.
// i18n/routing.ts — folders stay Spanish; EN URLs are mapped
pathnames: {
  "/sobre-mi": { es: "/sobre-mi", en: "/about" },
  "/blog/[slug]": { es: "/notas/[slug]", en: "/writeups/[slug]" },
}

The result

Lighthouse mobile ≥95 across all four categories, SEO 100, dark mode by default, and GitHub Actions CI running typecheck + build on every push. All content lives in git as MDX — versioned, reviewable, portable.

Let's build something of our own

Let's talk