SEO Estático
Audita y mejora la configuración SEO de un sitio HTML estático en nueve categorías: metadatos de cabecera, datos estructurados, calidad de contenido, imágenes Open Graph, sitemaps e indexación, descubrimiento de agentes, rendimiento, redirecciones y validación en CI. Las recetas son independientes de la plataforma: etiquetas <meta> en crudo, JSON-LD en crudo, sitemap.xml hecho a mano y herramientas CI genéricas. El marco de auditoría es paralelo al de astro-seo pero sin la columna vertebral de @jdevalk/astro-seo-graph.
Las recetas de código están en AGENTS.md — léelo cuando necesites implementar una corrección específica. Este archivo contiene el flujo de trabajo y la lista de verificación de auditoría.
Flujo de trabajo
- Detectar el proyecto — confirma que es un sitio estático, identifica la herramienta de compilación, encuentra dónde aplicar los cambios.
- Auditar — puntúa nueve categorías y produce hallazgos procesables.
- Mejorar — genera o modifica archivos para cerrar las brechas. Las recetas están en
AGENTS.md. - Pase de metadatos — invoca
metadata-checken cada cadena corta que el skill haya generado (títulos, descripciones, camposdescriptiondel esquema, respuestas de preguntas frecuentes). - Verificar — ejecuta la compilación, valida la salida, recuerda al usuario sobre tareas que no son de archivos (Search Console, Bing Webmaster Tools, envío de clave IndexNow).
Fase 0: Detectar el proyecto
Confirma los conceptos básicos antes de auditar:
- En realidad es un sitio estático. Busca HTML compilado:
index.htmlen la raíz del repositorio, o en_site/(Jekyll),public/(Hugo / 11ty / Gatsby),dist/(Vite / Astro estático),out/(Next.js conoutput: export). Si todo está renderizado en el servidor (Express, PHP, rutas dinámicas), este no es el skill correcto; apunta aastro-seopara Astro,wp-readme-optimizerpara páginas de plugins de WP, o recomienda una auditoría SEO genérica en su lugar. - Herramienta de compilación fuente. Determina dónde aplicar los cambios de metadatos de cabecera:
_config.yml/_layouts/→ Jekyllconfig.toml/config.yaml/themes/→ Hugo.eleventy.js/_includes/→ 11tygatsby-config.js/src/components/SEO.*→ Gatsbynext.config.jsconoutput: 'export'ypages/_document.tsx→ Next.js exportación estáticaastro.config.mjs→ Astro (en cuyo caso usaastro-seoen su lugar)- Sin configuración de compilación, solo archivos HTML → hecho a mano o extraído (por ejemplo, salida de
wp-static-clone). Edita el HTML directamente o usa un script de post-procesamiento.
- URL canónica del sitio. Busca en el repositorio el origen de producción; normalmente en
_config.yml,config.toml,astro.configo codificado en una plantilla. Si falta, está vacía o eslocalhost, márcalo como un problema bloqueante antes de cualquier otra cosa. Los canónicos, sitemaps, URLs de imágenes OG y valores@idde JSON-LD derivan de esto. - Destino de despliegue. Lee
vercel.json,netlify.toml,wrangler.tomlopublic/_headerspara determinar el host. Determina la sintaxis de redirecciones y cabeceras en la Fase 2. - ¿El sitio es multilingüe? Verifica subdirectorios de configuración regional (
/en/,/nl/,/de/) o la configuración de i18n de la herramienta de compilación. Si es así,hreflanges importante; si no, omítelo. - ¿Qué hay ya en
<head>? Abre un archivo HTML compilado e inventaría: título, descripción, canónico, robots, Open Graph, Twitter cards, JSON-LD, hreflang. La auditoría en la Fase 1 es más rápida si puedes referenciar lo que hay.
Pregunta solo lo que no puedas detectar.
Fase 1: Auditoría
Puntúa cada categoría sobre 10. Para cada una, da de 2 a 4 hallazgos específicos que citen el HTML, la configuración o la plantilla reales. Dentro de cada categoría, las comprobaciones están clasificadas:
- Obligatorio — bloqueantes de publicación. Un fallo causa una regresión visible en SEO.
- Recomendado — práctica estándar. Omitirlo cuesta alcance.
- Opcional — con visión de futuro o situacional. Útil pero no es la línea base para cada sitio.
Omita las comprobaciones Opcionales para sitios personales pequeños a menos que el usuario solicite el tratamiento completo.
1. Metadatos de cabecera (/10)
- Obligatorio — cada página tiene un
<title>y un<meta name="description">. - Obligatorio —
<link rel="canonical">establecido, con parámetros de seguimiento eliminados, derivado del origen de producción. - Obligatorio — canónico omitido cuando la página es
noindex(según la recomendación de Google). - Obligatorio —
<title>de 30 a 65 caracteres,<meta name="description">de 70 a 200 caracteres (los límites de truncamiento SERP; igual que los valores predeterminados demetadata-check). - Recomendado —
<meta name="robots">incluyemax-snippet:-1,max-image-preview:large,max-video-preview:-1. - Recomendado — Open Graph (
og:title,og:description,og:image,og:url,og:type,og:site_name) en cada página. - Recomendado — etiquetas de Twitter Card (
twitter:card) suprimidas cuando duplican Open Graph (Twitter retrocede automáticamente). - Recomendado — alternativas
hreflangen sitios multilingües. Omitir si es monolingüe. - Recomendado — un solo
<meta name="robots">y un soloog:imagepor página (las herramientas heredadas a veces emiten duplicados).
2. Datos estructurados / JSON-LD (/10)
- Obligatorio — al menos un bloque
<script type="application/ld+json">en cada página importante. - Recomendado —
@graphenlazado en lugar de un objetoArticleplano: entidades conectadas con referencias@idpara que unBlogPostingpueda apuntar a su autorPersony al padreWebPage. - Recomendado —
WebSite,Blog/WebPage,Person/Organization,BlogPosting/Article,BreadcrumbList,ImageObjecttodos presentes donde sea relevante. - Recomendado — señales de confianza:
publishingPrinciples,copyrightHolder,copyrightYear,knowsAbout,SearchAction. - Obligatorio — valida en la Prueba de resultados enriquecidos y en ClassySchema.
3. Calidad del contenido (/10)
- Obligatorio — cada página tiene un
<title>y un<meta name="description">únicos (sin metadatos duplicados en el sitio). - Obligatorio — exactamente un
<h1>por página. - Recomendado —
<title>y<meta name="description">auditados mediantemetadata-check(Fase 2.5) para carga frontal, concreción y ajuste SERP. - Recomendado — prosa del cuerpo auditada mediante
readability-checkpara publicaciones largas individuales (no auditar en masa). - Recomendado — cada
<img>tiene un atributoalt(oalt=""/role="presentation"para decorativos). - Recomendado — los enlaces internos usan rutas relativas a la raíz (
/foo/) no absolutas (https://...) — sobrevive a cambios de dominio y vistas previas.
4. Imágenes Open Graph (/10)
- Obligatorio — cada página tiene una imagen OG.
- Obligatorio — 1200×675 (mínimo 1200px de ancho para Google Discover, relación 16:9).
- Recomendado — JPEG (las plataformas sociales no admiten de forma confiable WebP / AVIF para OG).
- Recomendado — generadas en tiempo de compilación (satori-cli, sharp, ImageMagick, Vercel OG, Bannerbear) en lugar de subidas manualmente por página; evita la desviación.
- Recomendado — URL derivada de forma determinista a partir del slug (por ejemplo,
/og/<slug>.jpg) para que al agregar una página obtenga automáticamente una imagen. - Recomendado — cada
<img>en el contenido del cuerpo tiene un atributoalt(oalt=""/role="presentation"). Validado en CI mediantehtml-proofero similar.
5. Sitemaps e indexación (/10)
- Obligatorio —
/sitemap.xml(o/sitemap_index.xmlpara sitemaps divididos) accesible, XML válido, cada URL devuelve 200. - Obligatorio —
robots.txtpresente en la raíz del sitio y referencia el sitemap. - Obligatorio — existe feed RSS, anunciado mediante
<link rel="alternate" type="application/rss+xml">, contiene el contenido completo de la publicación (no extractos truncados). - Recomendado — dividido por sección si el sitio tiene varios tipos de contenido (
sitemap-posts.xml,sitemap-pages.xml) — más fácil de depurar la indexación en GSC. - Recomendado —
<lastmod>poblado a partir de marcas de tiempo de commits de git (más preciso), marcas de tiempo de compilación (aceptable) o fechas de frontmatter (último recurso). Lamtimedel sistema de archivos de una comprobación de CI es incorrecta: es la fecha de la comprobación, no la fecha del contenido. - Recomendado — IndexNow integrado. Clave de verificación como una ruta estática
/<key>.txten la raíz del sitio, más un hook de compilación o despliegue que POSTea nuevas URLs ahttps://api.indexnow.org/IndexNow. Limita el envío al host de producción (por ejemplo,CF_PAGES_BRANCH=main,VERCEL_ENV=production,CONTEXT=production) — el envío incondicional pingea el endpoint desde compilaciones locales con URLs que el host de producción aún no ha servido, lo que marca la clave como inválida (403) y obliga a rotarla.
6. Descubrimiento de agentes (/10)
- Recomendado — endpoints de esquema (
/schema/<type>.json) que exponen JSON-LD de todo el corpus por tipo de contenido. Archivos JSON estáticos comprometidos en el repositorio o regenerados por la compilación. - Recomendado — mapa de esquema (
/schemamap.xml) que enumera cada endpoint de esquema, con la directivaSchemamap:enrobots.txt. - Recomendado —
llms.txten la raíz del sitio que enumera páginas (título + descripción) para consumidores LLM. Archivo de texto estático; una línea por página. - Recomendado — URLs alternativas en Markdown (
/blog/post.mdjunto a/blog/post/) que sirven Markdown limpio con frontmatter YAML para que los agentes de IA puedan consumir contenido sin analizar HTML. Comprometer hermanos.md, o usar una regla de transformación de Cloudflare +Vary: Acceptpara negociación de contenido (CF Pages elimina las cabeceras Vary personalizadas, por lo que se usa solo la reescritura de URL de la regla de transformación; receta enAGENTS.md). - Recomendado — catálogo de API en
/.well-known/api-catalogsegún RFC 9727, comoapplication/linkset+json(RFC 9264). Enumera endpoints de esquema, mapa de esquema, feed RSS y cualquier API específica del sitio. Archivo JSON estático. - Recomendado — directiva Content Signals en
robots.txt(Content-Signal: ai-train=yes, search=yes, ai-input=yeso tu política preferida). Una línea, borrador IETF, bajo costo. - Recomendado — cabecera
Linken/*que apunte a archivos de descubrimiento (sitemap, llms.txt, api-catalog, schemamap). Los agentes que leen las cabeceras de respuesta los encuentran sin analizar HTML. Específico del host (_headersen Cloudflare Pages / Netlify,vercel.jsonen Vercel, configuración del servidor en otros casos). - Opcional — tarjeta de servidor MCP en
/.well-known/mcp/server-card.jsony/o tarjeta de agente A2A en/.well-known/agent-card.json. Solo relevante cuando el sitio expone un servidor MCP o un agente A2A. - Opcional —
<link rel="nlweb">que apunta a un endpoint conversacional. La adopción de NLWeb es temprana; la etiqueta es una línea y vale la pena tenerla, pero no es un bloqueo de puntuación en 2026. - Opcional — Catálogo ARD (Agentic Resource Discovery) en
/.well-known/ai-catalog.json, que enumera lo que ofrece el dominio (servidor MCP, agente A2A, paquete OKF, API específicas del sitio). Borrador v0.9, por lo tanto opcional, pero es la capa de descubrimiento a través de la cual las tarjetas MCP / A2A y el paquete OKF se materializan. Dos problemas: la especificación base (Agent-Card/ai-catalog) nombra el campo de tipo de mediomediaTypemientras que la capa ARD (ards-project/ard-spec) lo nombratype— emite ambas claves con el mismo valor para que la entrada valide bajo cualquier lectura (ambas especificaciones requieren que los consumidores ignoren las claves desconocidas). ARD también agrega una matriz opcionalrepresentativeQueriesde ejemplos de prompts por entrada. Archivo JSON estático. - Opcional — paquete OKF (Open Knowledge Format): un árbol de archivos de concepto Markdown con tipos (uno por página, rutas que reflejan URLs canónicas) empaquetados como un único
.tar.gz, con archivos de índice intermedios. Servir y descubrir son objetivos explícitos no cubiertos por OKF — para eso es la entrada del catálogo ARD. Borrador v0.9, opcional. Todavía no hay un tipo de medio registrado, por lo que la cadena provisional esapplication/okf-bundle+gzip(seguimiento en knowledge-catalog#111 y ard-spec#27); márcalo como provisional, puede cambiar. Es mejor generarlo a partir de la misma fuente de la que deriva el resto del sitio en lugar de una copia mantenida manualmente.
7. Rendimiento (/10)
- Obligatorio — los activos con hash sirven
Cache-Control: public, max-age=31536000, immutable(o equivalente) para que se descarguen solo una vez. - Recomendado — la fuente web principal precargada como
woff2mediante<link rel="preload" as="font" crossorigin>. - Recomendado — la cabecera de respuesta
No-Vary-Searchelimina los parámetros UTM de la clave de caché (para que/?utm_source=xy/compartan una entrada de caché). - Recomendado — sin JavaScript que bloquee el renderizado en la primera pintura (diferir o asincronizar scripts no críticos).
- Recomendado — las imágenes usan formatos modernos (WebP / AVIF para contenido en página; JPEG solo para tarjetas OG) y
loading="lazy"debajo del pliegue. - Recomendado — todos los Core Web Vitals de Lighthouse / PageSpeed en verde: LCP < 2.5s, INP < 200ms, CLS < 0.1.
8. Redirecciones y manejo de errores (/10)
- Obligatorio —
_redirects/vercel.json/ configuración del servidor mantenidos para cada URL que haya existido y se haya movido. - Obligatorio —
301no302para movimientos permanentes. - Obligatorio —
404.html(o equivalente) devuelve un estado 404, no 200. Verificar concurl -Icontra una URL deliberadamente incorrecta. - Recomendado — sugerencia de coincidencia aproximada en la página 404 ("quizás quisiste decir…?") para errores tipográficos en URLs. Implementación estática: preconstruir un índice JSON de slugs válidos, coincidencia aproximada en el lado del cliente.
9. Validación en CI (/10)
- Obligatorio — verificador de enlaces rotos en CI. linkinator o lychee en cada push que toque contenido. Enlaces internos y externos: los internos detectan regresiones de compilación, los externos detectan podredumbre de enlaces. Programar una ejecución semanal para comprobaciones solo externas.
- Recomendado — validación de HTML mediante html-proofer o W3C Validator — detecta marcado malformado que rompe los rastreadores.
- Recomendado — Lighthouse CI en cada push, con umbrales de puntuación (por ejemplo, SEO ≥ 95, Rendimiento ≥ 80).
- Recomendado — validación de JSON-LD en CI mediante el validador JSON-LD de Schema.org (no hay CLI oficial; canalizar a través de un script Node que POSTea a la API).
- Recomendado — validación de longitud de título y descripción en CI: un pequeño script que recorre el HTML compilado, extrae
<title>y<meta name="description">, marca cualquier cosa fuera de los límites.