README.md

Cómo está hecha esta web

El stack, la estructura y los principios que hay detrás de esta web.

Saltar a las secciones de este artículo

Principios

Todo está construido alrededor de tres ideas:

  • Simplicidad. Cada dependencia tiene que justificar por qué está ahí.
  • Claridad. La web enseña cómo está hecha mientras la lees, por eso el sidebar muestra los ficheros Markdown reales.
  • Personal. Una web personal tiene que parecerse a la persona que hay detrás.

Si quieres la versión larga:

Stack

  • Astro para generar la web estática y las rutas basadas en ficheros.
  • MDX para que los artículos sean ficheros Markdown que pueden importar componentes.
  • Tailwind CSS a través de @tailwindcss/vite, con la personalización en src/styles/global.css.
  • Lucide para los iconos, renderizados en la build.
  • Shiki para el resaltado de código, con los temas night-owl-light y night-owl.
  • TypeScript en modo estricto, con el alias @/* apuntando a src/*.
  • pnpm con un catálogo de workspace, para fijar las versiones en un solo sitio.
  • Netlify para desplegar al instante en cada push.

Tipografías

Tres tipografías alojadas en el propio servidor, servidas como woff2 desde public/fonts, para no hacer ninguna petición a terceros y evitar saltos en el layout:

  • DM Sans para los títulos y los encabezados. Es variable, así que un solo fichero cubre todos los pesos.
  • Inter para el texto y la interfaz, también variable y recortada a latin para que ocupe poco.
  • IBM Plex Mono para el código, los nombres de fichero y la barra de estado, en un único peso 400.

Las dos tipografías que se ven al entrar se precargan en el layout, y las tres usan font-display: swap.

Cómo funciona

Colecciones de contenido. Los artículos y las páginas viven en src/content/{en,es}/{blog,pages} y se validan con esquemas de Zod en src/content.config.ts. Cada artículo lleva un postId que lo empareja con su traducción, que es lo que hace funcionar el selector de idioma y las etiquetas hreflang.

Internacionalización. La web se enruta por URL, así que / es inglés y /es/ es español. Los textos de interfaz están en src/i18n/translations.json y cada componente los lee con un único helper, useTranslations.

Casi nada de JavaScript. El sidebar es un checkbox oculto y unos cuantos selectores de CSS, las carpetas son <details> y <summary>, y los tooltips son solo CSS. Los tres scripts que he escrito son vanilla e insertados en línea: uno guarda el estado del sidebar en localStorage, otro guarda ahí también el tema elegido y el tercero arregla un bug de iOS con los tooltips.

La excepción es Google Analytics, el único script de terceros que hay aquí y, con diferencia, el más grande. Se carga de forma asíncrona.

Accesibilidad y rendimiento. Todo se genera en la build, las imágenes se sirven en WebP con tamaños adaptables, y lo único que guardo en el navegador es el estado del sidebar y el tema elegido, además de las cookies que Analytics se guarda por su cuenta.