Sitio Astro (site/)
Proyecto pnpm independiente (lockfile propio, no forma parte de la compilación del plugin). Astro + @astrojs/sitemap + @astrojs/check. Desplegado en GitHub Pages en https://vadimonix.github.io/xray-decky/.
cd site
pnpm install
pnpm run check # astro check — verifica tipos de diccionarios de idioma; puerta de CI
pnpm run build # → site/dist
pnpm run dev
Contrato de URL y SEO (la parte que se rompe silenciosamente)
Todo funciona solo si estos se mantienen consistentes:
build.format: 'preserve'→ las páginas planas se compilan achangelog.html, las raíces de idioma aru/index.html(directorios).- Formas canónicas: las páginas planas terminan en
.html; las raíces de idioma usan barra inclinada final (…/ru/); la raíz del sitio es…/xray-decky/. Generadas porsrc/lib/urls.ts(absoluteUrl,withBase,localeHref). - El sitemap debe coincidir exactamente con las URLs canónicas. El hook
serializeenastro.config.mjsreescribe tanto<loc>como las alternativas hreflang<xhtml:link>generadas automáticamente: los segmentos de raíz de idioma (LOCALE_DIRS) obtienen/, todo lo demás sin extensión obtiene.html. Historial: antes de 2026-08 solo reescribía<loc>y añadía.htmlde forma general, enviando a los rastreadores aru.html/zh.html/fa.html/es.htmlinexistentes. - El conjunto hreflang del sitemap debe ser igual al conjunto hreflang de la página.
Base.astroemite 5 idiomas +x-default; la integración emite solo los 5, por lo queserializeagregax-default(= la URL enen). Google lee las anotaciones de ambos métodos de entrega y trata los conjuntos diferentes como conflictivos, no como un subconjunto.seo-check --sitelos compara por URL. robots.txtes inerte en este despliegue. Se envía a/xray-decky/robots.txt, pero los rastreadores solo leenhttps://vadimonix.github.io/robots.txt, que devuelve 404 (sin repositorio de sitio de usuario) — un 404 significa "rastrea todo", por lo que nada está bloqueado, pero la líneaSitemap:nunca se ve. El descubrimiento del sitemap depende completamente del envío en Search Console. La solución real, fuera de este repositorio: un repositorioVadimOnix/vadimonix.github.ioque sirva un robots.txt raíz del host, o un dominio personalizado.- GitHub Pages es indulgente (archivo sin extensión → 200, directorio sin barra → 301) — nunca confíes en eso; coincide exactamente con las canónicas.
compressHTML: falsees deliberado: mantiene<head>(canónico, hreflang, OG, JSON-LD) grepeable para auditorías SEO; gzip recupera el tamaño.
Agregar un idioma = un lugar: src/i18n/locales.ts (LOCALES, localePrefixes, hreflangCodes) + archivo de diccionario tipado por src/i18n/types.ts + LOCALE_DIRS en astro.config.mjs + mapa locales en la configuración de la integración del sitemap. astro check falla si faltan claves del diccionario — por eso CI lo ejecuta antes de la compilación.
Despliegue
.github/workflows/pages.yml: se activa al hacer push a master tocando site/** (o el propio workflow). Node 22, pnpm 9, --frozen-lockfile, check → build → subir site/dist → desplegar. Sin compilaciones de PR — CI de PR no compila el sitio, por lo que un PR verde no dice nada sobre el sitio.
Verificación de un bump mayor de Astro (empírico, no lectura de changelog)
Dependabot solo actualiza astro — las integraciones pares (@astrojs/sitemap, @astrojs/check) se quedan atrás; verifica que aún funcionen en lugar de asumirlo.
- Compila la versión actualizada localmente:
pnpm install --frozen-lockfile && pnpm run check && pnpm run build. - Compara la estructura de
dist/con la compilación anterior (mismas rutas 11+, directorios de idioma intactos, nada aplanado). grep -o '<loc>[^<]*</loc>' dist/sitemap-0.xml— cada URL debe coincidir con la forma canónica de un archivo real.- Verifica puntualmente
<link rel="canonical">y hreflang endist/index.htmly una página de idioma. - Después de fusionar, observa la ejecución de Pages y prueba las URLs en vivo (
curl -s -o /dev/null -w "%{http_code}").
Umbrales conocidos: Astro 6 requiere Node ≥22 (pages.yml ya está en 22) y eliminó las configuraciones CJS (la nuestra es .mjs); el valor predeterminado de i18n.routing.redirectToDefaultLocale cambió (irrelevante aquí — prefixDefaultLocale: false). Astro 7 se movió a Vite 8/Rolldown + compilador Rust — afecta principalmente a integraciones/configuración personalizada de Vite, que este sitio no tiene. Guías de actualización: https://docs.astro.build/en/guides/upgrade-to/v6/, https://docs.astro.build/en/guides/upgrade-to/v7/.
Varios
optimize-images.sh— pipeline de imágenes parapublic/; ejecútalo después de agregar activos pesados.- Las etiquetas de verificación de Search Console / Yandex viven en el head del layout — no las elimines.
- Las reglas de redacción/posicionamiento para el texto del sitio (y cualquier otra superficie orientada al usuario — READMEs, plugin.json, metadatos del repositorio) viven en el skill
seo-surfaces+ AGENTS.md "Superficies SEO". CI:node scripts/seo-check.mjs --sitese ejecuta contradist/en el workflow de Pages.