Saltar al contenido principal
Transparencia radical

Cómo funciona: stack, pipeline y IA

Stack, pipeline de publicación, IA build-time,
SEO/GEO e infraestructura de despliegue.

Astro 6
Output estático con JavaScript mínimo para interacción
Tailwind CSS v4
Estilos utilitarios, CSS inlinado en build
MDX
Posts y tutoriales en Markdown con soporte de componentes
Cloudflare Workers
Workers + Assets, despliegue manual con wrangler
Modelos de IA
Claude, GPT-4o, Gemini… registrado en metadatos
Satori + resvg
Imágenes Open Graph generadas en build time
Sharp
Optimización hero: AVIF quality 30 + srcset automático (ahorro ~30% vs quality 50)
Datos derivados
Mapa semántico, lecturas IA y radar editorial en build-time
NewsData.io
Titulares de IA en español en tiempo real vía CF Worker. Edge cache de 30 min. Fallback estático si la API no responde.
  1. Definir tema del artículo o tutorial
  2. El modelo recibe prompt + guía de estilo del repo
  3. El modelo genera el .mdx completo con frontmatter
  4. Revisión humana obligatoria antes de publicar
  5. Commit y push al repositorio GitHub
  6. Se ejecuta npm run deploy desde la CLI (el despliegue es manual)
  7. build:data genera mapa semántico, lecturas IA y radar editorial
  8. generate-og.mjs genera PNG 1200×630 para el contenido publicado
  9. Sharp convierte imágenes hero locales a AVIF + srcset cuando existen
  10. Astro compila HTML estático, llms-full.txt, RSS y sitemap
  11. Wrangler despliega a la red de Cloudflare en ~90s
identidad-artificial/
├── source/
│   ├── assets/post/      ← Imágenes hero de los posts
│   ├── content/blog/     ← Posts en .mdx
│   ├── content/tutoriales/ ← Tutoriales IA paso a paso en .mdx
│   ├── components/       ← UI, expediente IA, lecturas y grafo
│   ├── data/generated/   ← Artefactos IA generados en build-time
│   ├── layouts/          ← BaseLayout, PostLayout
│   ├── pages/            ← Rutas del sitio, blog, tutoriales, métricas y legales
│   └── styles/           ← CSS global
├── scripts/
│   ├── content-utils.mjs             ← Lectura segura del corpus MDX
│   ├── generate-og.mjs              ← Imágenes OG
│   ├── generate-knowledge-map.mjs   ← Grafo semántico
│   ├── generate-post-insights.mjs   ← Lecturas por artículo
│   ├── generate-editorial-radar.mjs ← Radar editorial
│   ├── google-search-console-*.mjs  ← Autenticación, informes e inspección GSC
│   ├── submit-search-console-sitemap.mjs ← Envío de sitemap a GSC
│   └── submit-indexnow.mjs          ← Notificación IndexNow (URLs desde sitemap en vivo)
├── docs/
│   ├── guia-crear-post.md     ← Instrucciones para generar posts
│   └── guia-crear-tutorial.md ← Instrucciones para generar tutoriales
├── public/
│   ├── fonts/            ← Inter TTF para satori
│   ├── og/               ← Imágenes OG generadas (no en git)
│   ├── llms.txt          ← Índice breve para motores de IA
│   └── _headers          ← Cabeceras de seguridad para Cloudflare
├── wrangler.toml         ← Configuración del despliegue
└── astro.config.mjs

Metadatos de transparencia validados con Zod en build time y mostrados al pie de cada artículo:

---
title: 'Título del post'
description: 'Descripción para SEO'
pubDate: 2026-04-21
category: 'Modelos'
tags: ['llm', 'agentes']
generatedBy: 'claude-sonnet-4-6'
generatedAt: '2026-04-21T10:00:00Z'
promptBase: 'El prompt que se usó para generar este post'
humanReviewed: true
heroImage: '../../assets/post/imagen-del-post.jpg'  # opcional
correctionNote: 'Texto si el post corrige errores de una versión anterior.'  # opcional
sourceQuality: 'Media'        # opcional
confidenceLevel: 'Media'      # opcional
reviewNotes: 'Notas visibles de revisión.'  # opcional
claimsReviewed:
  - 'Afirmación técnica verificada manualmente.'  # opcional
---

correctionNote aparece como bloque de aviso visible en el post cuando se publica una corrección. heroImage referencia una imagen local que Astro optimiza y convierte a AVIF en build time. Los campos sourceQuality, confidenceLevel, reviewNotes y claimsReviewed alimentan el nuevo expediente IA.

Los tutoriales viven en una colección separada para tener campos propios: herramienta, dificultad y tiempo estimado.

---
title: 'Título del tutorial'
description: 'Qué aprenderá el lector'
pubDate: 2026-05-18
herramienta: 'ChatGPT'
dificultad: 'Principiante'
tiempoEstimado: '20 minutos'
generatedBy: 'gpt-5'
generatedAt: '2026-05-18T18:00:00Z'
promptBase: 'Resumen del encargo usado para generar el tutorial'
humanReviewed: true
heroImage: '../../assets/post/imagen.jpg'  # opcional
correctionNote: 'Texto si el tutorial corrige una versión anterior.'  # opcional
---

La IA no aparece como un chatbot en vivo. El enfoque es más barato, auditable y estable: el build transforma el corpus en datos derivados que luego se renderizan como páginas estáticas.

Mapa semántico
generate-knowledge-map.mjs extrae categorías, tags, empresas y conceptos para alimentar /mapa-ia/ y el bloque "Conecta con" de cada post.
Lecturas generadas
generate-post-insights.mjs crea resumen ejecutivo, lectura técnica, puntos clave, glosario y FAQ por artículo sin llamar a una API en runtime.
Radar editorial
generate-editorial-radar.mjs compara el corpus con temas técnicos pendientes y publica señales filtradas en /radar/.
Expediente IA
Cada post muestra modelo, prompt base, revisión humana, confianza, calidad de fuentes, claims revisados y correcciones cuando existen.
npm run build
└── npm run build:data
    ├── source/data/generated/knowledge-map.ts
    ├── source/data/generated/post-insights.ts
    └── source/data/generated/editorial-radar.ts

El sitio aplica las APIs modernas del navegador para mejorar Core Web Vitals y la experiencia de navegación sin dependencias extra:

View Transitions API
Crossfade suave entre páginas del sitio. Se activa con @view-transition en CSS, respeta prefers-reduced-motion y degrada graciosamente en navegadores sin soporte.
Speculation Rules API
Prefetch eager + prerender moderate de todos los enlaces internos. El navegador anticipa la siguiente página antes de que el usuario haga clic, consiguiendo navegación casi instantánea.
fetchpriority="high"
La imagen hero del post destacado en portada lleva fetchpriority="high" para que el navegador la cargue antes que otras imágenes y mejore el LCP.
Sin forced reflow
El tooltip del timeline usa visualViewport.width/height en lugar de window.innerWidth/Height. visualViewport no fuerza un layout flush durante la inicialización del módulo, eliminando 192ms de reflow en el critical path.
Aspect ratio alineado
Las PostCard generan imágenes a 800×310 (ratio 2.58:1) igualando el ratio del contenedor .mona-card-img (140px alto × ~362px ancho). Elimina los píxeles descartados por object-fit: cover y reduce ~23% el peso de cada imagen de card.
font-size-adjust: from-font
Sincroniza el x-height de la fuente de respaldo con Inter antes de que la webfont cargue, eliminando el CLS (Cumulative Layout Shift) visual durante el font swap.
text-wrap: balance / pretty
Los títulos usan text-wrap: balance para distribuir líneas simétricamente. Los párrafos usan text-wrap: pretty para evitar huérfanos al final de párrafo.

El sitio cumple WCAG 2.1 AA como mínimo. Las mejoras se aplican progresivamente sin romper la estética ni añadir dependencias externas:

Skip link
Enlace "Saltar al contenido principal" visible solo al recibir foco (tecla Tab). El <main> tiene tabindex="-1" para ser focusable programáticamente, siguiendo WCAG 2.4.1.
Atributo inert en menú móvil
Al abrir el menú hamburger, se aplica inert a <main> y <footer>. El navegador elimina ambos del árbol de accesibilidad y del flujo de teclado sin necesidad de un focus trap JS manual.
:focus-visible global
Outline morado (#A78BFA) de 2px en todos los enlaces y botones al navegar con teclado. No afecta a usuarios de ratón. Complementa los estilos específicos de componentes como AITimeline.
Nav landmarks completos
El footer envuelve sus enlaces en <nav aria-label="Legal y redes sociales"> para que lectores de pantalla anuncien el grupo. La paginación usa <nav aria-label="Paginación"> con aria-current="page" y aria-label en prev/next.
Indicador activo accesible por color
El link activo en el menú móvil muestra borde izquierdo morado además del cambio de color, visible para usuarios con daltonismo que no perciban la diferencia de tono.
Hover solo con puntero fino
El estado hover de las PostCard usa @media (hover: hover) para que solo se active en desktop con ratón. En móvil no hay estados hover falsos que confundan al usuario táctil.

GEO (Generative Engine Optimization) es el equivalente del SEO para motores de respuesta como ChatGPT, Perplexity o Claude. El sitio está preparado para ambos:

Open Graph + Twitter Card
og:image usa la heroImage del post convertida a JPEG 1200×630 quality 75 en build-time con getImage() de Astro — compatible con scrapers sociales que no leen AVIF. Si no hay heroImage, usa la tarjeta de texto PNG generada por Satori con título, categoría y fecha. og:url, og:locale es_ES y twitter:card summary_large_image en todas las páginas.
JSON-LD por tipo de página
WebSite + Organization + Blog en home, TechArticle en /como-funciona/, Dataset en /mapa-ia/, CollectionPage + ItemList en /archivo/ y /radar/, Article en posts y tutoriales. Generados en build-time, en el HTML inicial — no requieren JS.
Person schema con sameAs
Ignacio Cubelas como entidad en cada post: url apunta a /sobre/, sameAs enlaza LinkedIn y GitHub. Permite a sistemas de IA vincular el autor con su identidad real.
Sitemap XML
Generado por @astrojs/sitemap con lastmod real de cada archivo fuente. Excluye páginas legales, paginación y posts retirados. /tutoriales/ incluye lastmod vía detección recursiva de subdirectorios.
robots.txt con todos los crawlers IA
GPTBot, ChatGPT-User, PerplexityBot, ClaudeBot, Google-Extended, OAI-SearchBot, Bytespider, Applebot-Extended, CCBot, anthropic-ai — todos con Allow: /. Charset UTF-8 explícito en _headers.
llms.txt + llms-full.txt + RSL 1.0
llms.txt lista artículos individuales con descripciones y declara permisos RSL 1.0 (indexing, training, citation required). llms-full.txt genera en runtime el corpus completo con texto íntegro de cada post.
Byline rel="author"
Cada post muestra "Por Ignacio Cubelas" con rel="author" enlazado a /sobre/. Señal E-E-A-T visible en HTML — no solo en schema.
RSS
Feed estándar para lectores y agregadores. Referenciado en <head> con rel="alternate" en todas las páginas.
IndexNow
submit-indexnow.mjs notifica a Bing, Yandex y motores compatibles tras cada despliegue. Las URLs se derivan del sitemap desplegado en tiempo real — siempre en sync con lo publicado, sin hardcoding.

Cabeceras HTTP aplicadas a nivel de Cloudflare via public/_headers:

HSTS Fuerza HTTPS durante 1 año con preload
X-Frame-Options: DENY Previene clickjacking
Content-Security-Policy Restringe el origen de scripts, estilos y fuentes
X-Content-Type-Options Evita MIME sniffing
Referrer-Policy Limita la información de referencia enviada
Permissions-Policy Deshabilita acceso a cámara, micrófono y geolocalización

Ninguna credencial está en el repositorio. Las variables de entorno se gestionan exclusivamente en el panel de Cloudflare.