Hay dos formas de equivocarse con la arquitectura del contenido y la mayoría de los proyectos elige una. De un lado están los puristas del todo-en-Git, para quienes corregir una errata implica una rama, un pull request y un despliegue completo. Del otro están los que deciden que el CMS debería contenerlo todo —cadenas de interfaz, configuración de layout, design tokens, todo— hasta que el sitio no puede renderizar un botón sin una petición de red. He construido mi portafolio y este blog sobre la misma capa de contenido, y lo único que ha aguantado es una frontera dura entre las dos.
Al principio, todo lo que construía vivía en archivos dentro del repositorio —INI, luego JSON—, todo bajo control de versiones y enteramente en mi mano. Era simple hasta que dejó de serlo. El día que quieres corregir una frase desde el móvil, o publicar una idea sin abrir un editor, el contenido solo-en-archivos se convierte en un muro. Forzar un despliegue para mover una coma es desperdiciar un despliegue.
Así que la primera vez que cogí un CMS headless me pasé de frenada y lo metí todo dentro —etiquetas de UI, ajustes de tema, estado de componentes—, en tablas remotas junto al texto de verdad. Eso cambia un modo de fallo por otro peor. Ahora el chrome de la interfaz llega por la red, la internacionalización significa una llamada a la API, y un hipo del CMS puede tirar una página que no tiene por qué depender del CMS. La respuesta nunca fue un lado o el otro. Es un contrato entre lo que cambia a diario y lo que define el sistema.
El CMS se queda con el contenido narrativo y mutable, y con nada más: las cosas que crecen y cambian sin que nadie tenga que refactorizar. En este blog eso es cada artículo, extracto y tema: escribo y publico desde una pantalla de administración sin tocar el código fuente. En el portafolio son las descripciones de proyectos, los hitos, las habilidades; terminar un contrato es una edición de contenido, no una release. También es el sitio adecuado para los pocos ajustes globales que necesitan cambiar sin un despliegue: un anuncio, los metadatos del autor, un feature flag. Si podría redactarlo, revisarlo o borrarlo por capricho, pertenece a la base de datos.
Cualquier cosa que decida cómo se comporta la aplicación, o que necesite que el compilador la verifique, se queda en el código. El diccionario de interfaz es el caso más claro: ambos sitios están localizados en seis idiomas, pero las etiquetas de navegación, los textos de los botones, los placeholders y los aria-labels viven en JSON tipado en el repositorio, porque traerlos de un CMS añadiría latencia al renderizar el marco y arriesgaría una clave ausente a mitad de la hidratación. Lo mismo con las reglas de enrutado, la configuración de temas, los tiempos de animación, los esquemas de validación: quieren comprobación en tiempo de compilación, no una fila en una base de datos. Y los recursos estáticos: imágenes, iconos y miniaturas pertenecen al proyecto, donde el build puede optimizarlos y la caché puede confiar en ellos, sin un viaje de ida y vuelta a los medios del CMS en el camino del renderizado.
Algunas cosas no encajan en ninguna caja. Comentarios, likes, contadores de vistas, registros de rate-limit, sesiones —de alta frecuencia, transaccionales, que necesitan integridad real— no pertenecen a un CMS pensado para redactar ni a archivos que se reconstruyen en cada despliegue. Los hilos de comentarios necesitan respuestas, comprobaciones de autenticación, moderación. Un contador de likes aplastaría una reconstrucción estática y se arrastraría por una API de escritura de un CMS. Los rate limits y los registros de acceso necesitan una base de datos real haciendo trabajo en tiempo real. Ese es un tercer almacén, y fingir que es uno de los otros dos es como acabas con una versión lenta y frágil de ambos.
Las historias van en el CMS. La estructura va en el código. Todo lo que cuenta, tictaquea o limita va en una base de datos que no hace ninguna de esas cosas.
La arquitectura es sobre todo el acto de trazar líneas y luego negarse a moverlas por comodidad. El contenido y el código tienen ciclos de vida distintos; en cuanto dejas de fingir lo contrario, las herramientas dejan de pelearse contigo. El CMS me deja publicar desde cualquier sitio. El repositorio mantiene las partes que tienen que estar bien en tiempo de build realmente bien en tiempo de build. La frontera entre ambos es la única razón por la que cualquiera de los dos resulta agradable de usar.
Los cimientos están puestos; ahora toca construir.