Escribe en Markdown, sírvelo dinámico

Read in English

Tenemos tres tipos de visitantes: uno es un primate y los otros dos son robots. Tres tipos de lectores muy distintos, con necesidades muy distintas, y a los que casi todo el mundo sirve exactamente lo mismo. Por ello, en mi blog, dinámicamente sirvo el mismo contenido en tres formatos distintos, adaptado a cada forma de consumo.

Antes de que continúes leyendo, quiero que sepas que esto podría considerarse como una explicación extendida de uno de los puntos de mi otro artículo El lado oscuro de los sitios estáticos.

Un mismo artículo, tres lectores

Piensa en quién llega a esta página:

  • Humanos: Quieren una experiencia rica. Diseños agradables y con buenos contrastes, funcionalidades como paginadores infinitos, comentarios, navegación fluida sin recargar. En otras palabras: diseño, contenido y experiencia. Todo lo que hace que la web sea un lugar agradable para estar.
  • Indexadores: Los bots de Google, Bing o DuckDuckGo. Quieren HTML limpio y estable, sin depender de que se ejecute JavaScript. Solo leen tu contenido y clasifican por la estructura de etiquetas. Les dan igual los fuegos artificiales, los menús desplegables o los sliders. Solo quieren el contenido, y lo quieren rápido.
  • IAs y agentes: Claude, ChatGPT, Perplexity y compañía. Al igual que los indexadores, no quieren tu maquetación, ni tu menú, ni tu pie de página. Pero tampoco la estructura, jerarquía o etiquetas de contenido (<section>, <article>, <h1>, <h2>). Quieren tu texto en bruto y barato, gastando el mínimo de tokens posible.

Pero los tres acceden a la misma URL.

El mismo contenido, negociado

La solución no es tener tres webs, sino una sola fuente de contenido y servirla en el formato que cada visitante pide. Y resulta que HTTP ya tenía la respuesta desde hace décadas: la cabecera Accept.

Cada petición al servidor dice qué formato prefiere. Un navegador pide text/html. Un agente puede pedir text/markdown. El servidor mira esa cabecera y responde en consecuencia. Se llama content negotiation, negociación de contenido, y lleva en el estándar HTTP casi treinta años. El mismo mecanismo que sirve HTML a un navegador, JSON a una app o RSS a un lector de feeds. Lo raro es que, hasta hace poco, casi nadie lo usara para servir Markdown a las IAs.

En mi caso, cualquiera puede comprobarlo. Pide este mismo artículo en Markdown:

curl -H "Accept: text/markdown" https://andros.dev/blog/...

Y si quieres HTML, pide:

curl -H "Accept: text/html" https://andros.dev/blog/...

La misma URL. El mismo contenido. Otro formato.

flowchart TD
    A[Petición a la misma URL] --> B{¿Qué dice la cabecera Accept?}
    B -->|text/markdown| C[IA / Agente: Markdown puro, mínimos tokens]
    B -->|text/html, bot indexador| D[Indexador: HTML estático, sin ejecutar JS]
    B -->|text/html, navegador| E[Humano: HTML sobre WebSockets, SPA dinámica]
    C --> F[Mismo contenido, una sola fuente]
    D --> F
    E --> F

Quizá hayas oído hablar de llms.txt, el archivo que lista tus contenidos en Markdown para las IAs. Es complementario, no lo mismo: llms.txt sirve para que te descubran, la negociación de contenido para servir cada página cuando ya te han encontrado. Yo me quedo con la segunda, porque no me obliga a mantener un índice aparte que sincronizar.

Por qué a las IAs les das Markdown

No es un capricho estético. Es economía.

Un modelo de lenguaje paga por tokens. Cada etiqueta HTML, cada clase de CSS, cada <div> anidado son tokens que consume para llegar a tu texto. Ponle número: mi artículo El lado oscuro de los sitios estáticos pesa unos 37 KB en HTML y unos 9 KB en Markdown. Cuatro veces menos, un 75% de reducción, y eso que mi página ya es bastante ligera. En sitios más recargados la diferencia llega del 80% al 99%. Menos tokens es menos coste, menos ruido y más probabilidad de que el modelo entienda bien lo que dices.

Piénsalo desde el otro lado. Si tu contenido es fácil de leer para una IA, es más probable que te cite correctamente cuando alguien le pregunte. En un mundo donde cada vez más gente pregunta a un asistente en lugar de a un buscador, esa es la nueva optimización. El SEO de la próxima década igual se llama servir buen Markdown.

¿Esto no es hacer trampas?

Es la pregunta legítima. Si sirves algo distinto a los bots que a los humanos, ¿no es eso cloaking, la técnica que Google penaliza?

No, y la diferencia es importante. El cloaking consiste en servir contenido diferente en la misma URL para engañar: una cosa al buscador para posicionar, otra distinta al humano. Aquí el contenido es el mismo. Lo único que cambia es el formato de presentación, y cambia porque el propio cliente lo pide con su cabecera Accept. No hay engaño. Hay cortesía. El artículo dice exactamente lo mismo en las tres versiones.

La regla es sencilla: mismos hechos, misma estructura, mismos enlaces y fechas. Solo quitas el envoltorio que a ese visitante no le sirve.

Los humanos, sin renunciar a nada

Para las personas hago justo lo contrario que para las IAs: les doy la experiencia más rica posible. El sitio se comporta como un SPA con un HTML sobre WebSockets: navegas sin recargas, el buscador responde al instante, la navegación es veloz.

Sin embargo, si no tienes activo JavaScript, el sitio sigue funcionando. El contenido se sirve en HTML estático, con enlaces y paginación. No hay nada que no puedas leer, ni nada que no puedas navegar. Solo pierdes la experiencia enriquecida.

Por qué lo dinámico lo hace fácil

Quizá pienses que todo esto se puede hacer con un generador estático. Y en parte es cierto. Puedes generar un .md duplicado por cada página junto a su HTML. De hecho, hay quien lo hace con Eleventy. Incluso Cloudflare y Vercel lo ofrecen ya, convirtiendo tu HTML a Markdown al vuelo en el edge.

Pero fíjate en el matiz. Cloudflare parte de tu HTML y lo reconvierte a Markdown: parte de la versión ya envuelta para deshacer el envoltorio. Un generador estático duplica un .md en cada build y confía en no desincronizarlo. Yo no reconvierto nada ni duplico nada: sirvo la fuente original en Markdown, que es exactamente lo que escribí.

La diferencia es dónde vive la complejidad. En un sitio estático, cada formato nuevo es un artefacto más que generar, versionar y mantener sincronizado. En un backend dinámico, el contenido vive una sola vez en Markdown y el formato se decide en el momento de la petición. No hay copias que se desincronicen. No hay build que recordar. Miras la cabecera Accept y respondes. Añadir un cuarto formato mañana es una función, no un pipeline.

Esa es, para mí, la ventaja que no se ve a primera vista de un sitio dinámico. No es tener comentarios o un buscador. Es poder tratar a cada visitante como lo que es, en lugar de servir el mismo paquete a todos y esperar que les valga.

Conclusión

Y aquí está la idea que quiero que te lleves.

Cuando alguien defiende los sitios estáticos, el argumento estrella suele ser el mismo: escribo en texto plano, en Markdown, con mi editor y mi repositorio de git. Y es un gran argumento. Yo también escribo así. No pienso renunciar a ello. Pero fíjate en la trampa. "Escribo en Markdown" y "uso un generador estático" se han fundido en la cabeza de todo el mundo como si fueran la misma decisión. No lo son. Una cosa es cómo escribes. Otra muy distinta es cómo sirves lo que escribes. Puedes quedarte con lo primero y cambiar lo segundo.

Un generador estático coge tu Markdown, lo compila a HTML en el build y, a efectos prácticos, tira el Markdown a la basura. Lo que sirve es HTML. Si luego quieres darle Markdown a una IA, tienes que volver a generarlo aparte, como una copia. El Markdown dejó de ser la fuente en el momento del build.

Un sitio dinámico hace lo contrario. El Markdown sigue vivo. Es la fuente, no un ingrediente que se consume al compilar. Cada petición lo renderiza al formato que toca: HTML para el humano, HTML plano para el indexador, Markdown tal cual para la IA. Servir el original no cuesta nada, porque el original nunca se fue.

Así que ya sabes: escribe en Markdown, pero no lo sirvas con un generador estático, sino desde un backend dinámico.

Fuentes

Este trabajo está bajo una licencia Attribution-NonCommercial-NoDerivatives 4.0 International.

¿Me invitas a un café?

Así sigo escribiendo sin publicidad ni muros de pago.

Comentarios

Todavía no hay ningún comentario.

Sigue leyendo

Visitantes en tiempo real

Estás solo: