# Cómo servir tus páginas en Markdown para agentes de IA

> Añadir .md a la URL de un artículo y recibir el texto limpio. Cómo lo hicimos en Next.js con un proxy, una ruta y una conversión de Lexical a Markdown.

URL: https://codegea.com/servir-tus-paginas-en-markdown-para-agentes-de-ia
Web · 2026-10-19 · Derian Pinto

Un asistente de IA que lee tu web recibe HTML: menús, scripts, pie de página, mucho ruido alrededor del texto que le interesa. Una versión en Markdown de cada artículo le da solo lo importante: el título, el resumen y el contenido. En este sitio, añadir `.md` a la URL de un artículo o proyecto lo devuelve. Así está hecho.

Si quieres ver el resultado, prueba con este mismo artículo: `/servir-tus-paginas-en-markdown-para-agentes-de-ia.md`.

## Las tres piezas

1. Una **reescritura en el proxy**: cualquier URL que termina en `.md` se envía a una ruta interna.
2. Un **route handler** que busca el contenido y responde con `text/markdown`.
3. Una **función que convierte** el contenido a Markdown.

## Pieza 1: el proxy

En `proxy.ts`, antes de la lógica de idiomas:

```ts
// Versión Markdown para agentes: /<articulo>.md y /projects/<slug>.md
if (pathname.endsWith('.md')) {
  const name = rest.at(-1)?.slice(0, -3);
  const section =
    rest.length === 1 ? 'blog' : rest.length === 2 ? matchSegment(locale, rest[0])?.internal : undefined;
  if (!name || (section !== 'blog' && section !== 'projects')) return NextResponse.next();
  return NextResponse.rewrite(new URL(join('md', locale, section, name), req.url));
}
```

Los artículos viven en la raíz (`/mi-articulo`), así que una URL con un solo segmento es un artículo (`blog`). Con dos segmentos, el primero indica la sección, por ejemplo `projects`. Lo que no encaja sigue su camino normal.

## Pieza 2: el route handler

En `app/md/[locale]/[section]/[slug]/route.ts`:

```ts
const markdown = (body: string) =>
  new Response(body, {
    headers: {
      'Content-Type': 'text/markdown; charset=utf-8',
      'X-Robots-Tag': 'noindex',
      'Cache-Control': 'public, s-maxage=3600, stale-while-revalidate=86400',
    },
  });

export async function GET(_req: NextRequest, { params }: Ctx) {
  const { locale, section, slug } = await params;
  if (!isLocale(locale)) return new Response('Not found', { status: 404 });

  if (section === 'blog') {
    const post = await getPost({ slug, locale });
    return post ? markdown(postMarkdown(post, locale)) : new Response('Not found', { status: 404 });
  }
  // …lo mismo para projects
}
```

Dos decisiones:

- **`X-Robots-Tag: noindex`****.** La versión Markdown no debe competir con la página HTML en Google. Es para máquinas, no para el buscador.
- **Caché pública de una hora.** El texto cambia poco, y un agente que pide muchas páginas no debería golpear la base de datos cada vez.

## Pieza 3: de Lexical a Markdown

El contenido de nuestros artículos vive en Payload, que usa el editor Lexical, y lo guarda como un árbol JSON. Hay que recorrerlo y escribir Markdown. Nuestra función `postMarkdown` arma el documento:

```ts
export function postMarkdown(post: Post, locale: Locale): string {
  return join([
    `# ${post.title}`,
    `> ${post.excerpt}`,
    [
      `URL: ${SITE_URL}${postPath(locale, post.slug)}`,
      `${category.title} · ${post.publishedAt?.slice(0, 10)} · ${author.name}`,
    ].join('\n'),
    lexicalToMarkdown(post.content.root),
  ]);
}
```

Título, resumen en cita, una línea con la URL original, la categoría, la fecha y el autor, y luego el cuerpo. La URL original sirve para que quien lea la versión Markdown sepa dónde está la canónica.

`lexicalToMarkdown` recorre los nodos y devuelve encabezados, citas, listas, tablas, imágenes, enlaces y bloques de código con su lenguaje. Si tu contenido está en Markdown desde el principio (por ejemplo, un [CMS basado en Markdown](/cms-basado-en-markdown-que-es-ventajas-y-cuando-conviene)), te saltas esta pieza y devuelves el archivo.

## Un complemento: `llms.txt`

Además de las versiones `.md`, servimos `llms.txt` y `llms-full.txt` en la raíz: índices en texto con la descripción del sitio y los enlaces a servicios, proyectos y artículos. Es una convención reciente, y no hay garantía de que todos los agentes la lean. Cuesta poco mantenerla, porque se genera desde la misma base de datos.

## Qué no hace

Esto no garantiza que ningún modelo te cite ni mejora tu posición en Google. Lo que hace es facilitar la lectura a quien decida leerte, y es un trabajo pequeño: un proxy, una ruta y un conversor.

Si estás preparando una web para ser leída por máquinas, también te servirá [auditar el SEO técnico en 30 minutos](/auditoria-seo-tecnica-en-30-minutos-checklist).
