Saltar al contenido
Milian Lastre ZequeiraES
Web· Diseño, código y contenido· 2026

saintmilian.com — este sitio

El sitio que estás leyendo. En dos idiomas, sin CMS ni plantilla comprada. Lo diseñé, lo construí y lo escribo yo.

Next.js 16TypeScriptTailwind CSS 4next-intlVeliteMDXResendVercel
Vista conceptual

Este es el sitio que estás leyendo. Lo diseñé, lo construí y lo escribo yo — sin CMS, sin plantilla comprada.

El problema

Un sitio editorial bilingüe que compite por búsqueda orgánica no puede improvisar el i18n. Cada nota necesita su par de idioma correctamente enlazado (hreflang recíproco + x-default), una URL canónica estable y contenido que valide en build, no en producción.

El enfoque

  • Next.js 16 App Router con proxy.ts (el rename de middleware en 16) manejando el ruteo de next-intl.
  • Content layer type-safe con Velite: cada frontmatter se valida con Zod y genera tipos a .velite/. Un post inválido rompe el build, no el sitio.
  • hreflang por par de traducción: cada nota lleva un translationKey; de ahí derivo alternates.languages en generateMetadata y en sitemap.ts.
  • SEO como invariante: OG dinámico vía /api/og, JSON-LD por página, sitemap con alternates por locale.
// i18n/routing.ts — las carpetas quedan en español; las URLs EN se mapean
pathnames: {
  "/sobre-mi": { es: "/sobre-mi", en: "/about" },
  "/blog/[slug]": { es: "/notas/[slug]", en: "/writeups/[slug]" },
}

El resultado

Lighthouse mobile ≥95 en las cuatro categorías, SEO 100, dark-mode por defecto y CI en GitHub Actions que corre typecheck + build en cada push. Todo el contenido vive en git como MDX — versionado, revisable, portable.

Construyamos algo propio

Hablemos