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
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 demiddlewareen 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í derivoalternates.languagesengenerateMetadatay ensitemap.ts. - SEO como invariante: OG dinámico vía
/api/og, JSON-LD por página, sitemap conalternatespor 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.