Cambiar tema

Guía completa de SEO para sitios Astro: de meta tags al posicionamiento en buscadores

Easton editorial illustration: island architecture model

Pasaste una semana montando un blog bonito con Astro, lo publicaste con ilusión y, dos meses después, buscas el título de tus artículos en Google y no aparecen ni en la tercera página. Abres Google Analytics y los visitantes siguen en single digits. ¿Algo falla?

Yo pasé por lo mismo. Acababa de migrar de Next.js a Astro; había oído que Astro rinde muy bien, hasta un 40 % más rápido que frameworks React clásicos y con Lighthouse al 100. El sitio volaba, pero el posicionamiento no despegaba. Luego entendí que rendimiento no basta: la configuración SEO es clave.

La buena noticia: optimizar SEO en Astro no es complicado. En este artículo te guío paso a paso por meta tags, sitemap, robots.txt y datos estructurados, con ejemplos que puedes copiar. En unos 30 minutos tienes lo esencial; en una o dos semanas deberías ver indexación en Google Search Console.

¿Por qué Astro encaja tan bien con SEO?

Antes de entrar en configuración concreta, veamos por qué elegí Astro para sitios de contenido.

Ventajas SEO naturales de Astro

Lo más destacado de Astro es cero JavaScript por defecto. Sí, cero. Genera HTML estático; los crawlers ven contenido puro sin esperar a que se ejecute JS.

La arquitectura Islands es muy inteligente: el cuerpo de la página es HTML estático y solo las partes interactivas (un botón de like, por ejemplo) cargan su JS. El first paint es rapidísimo y a Google le encanta.

Con Next.js, aun con SSR, el bundle de JS seguía siendo grande. Tras migrar a Astro, el volumen de JavaScript bajó un 90 %. Lighthouse pasó de 78 a 98.

90%
Reducción de JS
Tras migrar de Next.js a Astro
78→98
Mejora Lighthouse
+20 puntos de una vez
30 min
Tiempo de config
SEO esencial completado

¿Cómo se compara con otros frameworks?

Cada framework tiene su escenario. Comparación rápida:

Astro: blogs, documentación, marketing — sitios donde manda el contenido. Carga muy rápida; en 2025 la adopción entre desarrolladores ronda el 18 %.

Next.js: apps con mucha interacción — paneles admin, e-commerce. Si necesitas mucho estado en cliente, Next.js encaja mejor.

Gatsby: también estático, parecido a Astro. Pero los bundles suelen ser más grandes y el build más lento.

Caso real: el blog técnico de un amigo migró de Next.js a Astro y la velocidad subió ~50 %. En Search Console, el tiempo medio en página pasó de 1:20 a 2:10. Se nota.

Lo imprescindible: meta tags completos

Meta tags son el primer paso del SEO y también el más ignorado.

Trío básico: title, description, keywords

Al empezar con Astro me atasqué con los meta tags. Tanta etiqueta <meta> y no sabía por dónde empezar. Al final son tres:

Etiqueta title: la más importante — el titular grande en Google. Mejor 50-60 caracteres; más largo se trunca. Este artículo: «Guía completa de SEO para sitios Astro: de meta tags al posicionamiento».

Etiqueta description: el texto gris bajo el resultado. 120-160 caracteres con la keyword principal. Google usa el CTR; una buena description puede subir clics un 20-30 %.

Etiqueta keywords: hoy poco relevante para Google, pero no cuesta poner 3-5 términos.

En Astro, en el <head> del .astro:


---

const title = "Guía completa de SEO para sitios Astro";
const description = "Guía paso a paso para SEO en Astro: meta tags, sitemap, robots.txt y datos estructurados.";

---

<head>
  <title>{title}</title>
  <meta name="description" content={description} />
  <meta name="keywords" content="Astro SEO, optimización Astro, meta tags, sitemap" />
</head>

Open Graph y Twitter Card

Sirven al compartir en redes: título, descripción e imagen automáticos. Tras probar muchas og:*, estas son las esenciales:

<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content="https://tusitio.com/og-image.jpg" />
<meta property="og:url" content="https://tusitio.com/ruta-actual" />
<meta property="og:type" content="article" />

<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} />
<meta name="twitter:image" content="https://tusitio.com/twitter-image.jpg" />

Trampa de og:image: usa 1200x630 px. La primera vez puse 500x300 y en WeChat se veía borroso; con 1200x630, otro rollo.

Centralizar con un componente

Escribir meta tags en cada página cansa. Mejor un BaseHead.astro:

Crea src/components/BaseHead.astro:


---

interface Props {
  title: string;
  description: string;
  image?: string;
}

const { title, description, image = "/default-og-image.jpg" } = Astro.props;
const canonicalURL = new URL(Astro.url.pathname, Astro.site);

---

<head>
  <!-- Meta básicos -->
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />

  <!-- SEO -->
  <title>{title}</title>
  <meta name="description" content={description} />
  <link rel="canonical" href={canonicalURL} />

  <!-- Open Graph -->
  <meta property="og:type" content="website" />
  <meta property="og:url" content={canonicalURL} />
  <meta property="og:title" content={title} />
  <meta property="og:description" content={description} />
  <meta property="og:image" content={new URL(image, Astro.site)} />

  <!-- Twitter -->
  <meta name="twitter:card" content="summary_large_image" />
  <meta name="twitter:title" content={title} />
  <meta name="twitter:description" content={description} />
  <meta name="twitter:image" content={new URL(image, Astro.site)} />
</head>

En la página:


---

import BaseHead from '../components/BaseHead.astro';

---

<html>
  <BaseHead
    title="Título de mi artículo"
    description="Descripción del artículo"
    image="/my-article-cover.jpg"
  />
  <body>
    <!-- Contenido -->
  </body>
</html>

Con Content Collections, title y description salen del frontmatter y los meta quedan automáticos.

Configuración avanzada: sitemap y robots.txt

Con meta tags listos, toca que Google encuentre tus URLs: sitemap y robots.txt.

Sitemap: listar tus páginas

Un XML con todas las URLs. Los crawlers saben qué rastrear; con sitemap, la indexación puede acortarse ~50 %.

Astro ofrece @astrojs/sitemap:

npx astro add sitemap

Modifica astro.config.mjs:

import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  site: 'https://tusitio.com',  // tu dominio real
  integrations: [sitemap()],
});

Importante: sin site, no hay sitemap. La primera vez lo olvidé y el build fallaba.

Tras npm run build, en dist/ aparecen sitemap-0.xml y sitemap-index.xml (más archivos si superas ~50k URLs).

En <head>:

<link rel="sitemap" href="/sitemap-index.xml" />

Robots.txt: reglas de rastreo

Indica qué puede indexarse. Admin y entornos de prueba suelen excluirse.

Método 1: archivo estático (recomendado para empezar)

En public/robots.txt:

User-agent: *
Allow: /

Sitemap: https://tusitio.com/sitemap-index.xml

Para bloquear rutas:

User-agent: *
Allow: /
Disallow: /admin/
Disallow: /test/

Sitemap: https://tusitio.com/sitemap-index.xml

Método 2: generación dinámica

src/pages/robots.txt.ts:

import type { APIRoute } from 'astro';

const robotsTxt = `
User-agent: *
Allow: /

Sitemap: ${import.meta.env.SITE}/sitemap-index.xml
`.trim();

export const GET: APIRoute = () => {
  return new Response(robotsTxt, {
    headers: { 'Content-Type': 'text/plain' },
  });
};

Método 3: plugin

npm install astro-robots-txt

En astro.config.mjs:

import robotsTxt from 'astro-robots-txt';

export default defineConfig({
  site: 'https://tusitio.com',
  integrations: [
    sitemap(),
    robotsTxt(),
  ],
});

Particularidades de Baidu SEO

Baidu no admite sitemap-index.xml. Si lo pones en robots.txt, puede bloquear el rastreo.

Opciones:

  1. En robots.txt, solo la ruta de un sitemap individual (p. ej. sitemap-0.xml), no sitemap-index
  2. Sitemap simplificado enviado manualmente en la plataforma de webmasters de Baidu

Yo priorizo Google y envío sitemap a Baidu a mano; en blogs técnicos, Google suele traer más tráfico.

Enviar a Google Search Console

Tras sitemap y robots.txt, entra en Google Search Console:

  1. Añade el sitio y verifica propiedad
  2. Menú «Sitemaps»
  3. Envía sitemap-index.xml

En 1-3 días suele empezar el rastreo. Ver «Descubierto» pasar a «Indexado» compensa el esfuerzo.

Optimización avanzada: datos estructurados (JSON-LD)

Suena técnico, pero es sencillo y el impacto en resultados enriquecidos es claro.

¿Qué son y para qué sirven?

Algunos resultados muestran valoración, fecha, autor o tiempos de receta — son rich snippets, basados en datos estructurados.

Le dices a Google en un formato que entiende: «esto es un artículo», «este es el autor», «esta es la fecha». Google recomienda JSON-LD. En mi blog, el CTR subió ~15 % tras configurarlo.

JSON-LD en Astro

Usa set:html. Ejemplo src/components/StructuredData.astro:


---

interface Props {
  type: 'WebSite' | 'BlogPosting' | 'Article';
  title: string;
  description: string;
  author?: string;
  datePublished?: string;
  image?: string;
}

const {
  type = 'Article',
  title,
  description,
  author = 'Tu nombre',
  datePublished,
  image
} = Astro.props;

const canonicalURL = new URL(Astro.url.pathname, Astro.site);

const structuredData = {
  "@context": "https://schema.org",
  "@type": type,
  "headline": title,
  "description": description,
  "author": {
    "@type": "Person",
    "name": author
  },
  "datePublished": datePublished,
  "image": image ? new URL(image, Astro.site).href : undefined,
  "url": canonicalURL.href,
  "mainEntityOfPage": {
    "@type": "WebPage",
    "@id": canonicalURL.href
  }
};

---

<script type="application/ld+json" set:html={JSON.stringify(structuredData)} />

En el artículo:


---

import StructuredData from '../components/StructuredData.astro';

const frontmatter = {
  title: "Guía completa de SEO para sitios Astro",
  description: "Guía paso a paso de SEO en Astro",
  author: "Autor",
  pubDate: "2025-12-02",
  coverImage: "/cover.jpg"
};

---

<html>
  <head>
    <StructuredData
      type="BlogPosting"
      title={frontmatter.title}
      description={frontmatter.description}
      author={frontmatter.author}
      datePublished={frontmatter.pubDate}
      image={frontmatter.coverImage}
    />
  </head>
  <body>
    <!-- Contenido -->
  </body>
</html>

Nota: usa set:html; sin eso Astro escapa el JSON y no funciona.

Tipos Schema habituales

WebSite — inicio:

{
  "@context": "https://schema.org",
  "@type": "WebSite",
  "name": "Nombre de tu sitio",
  "url": "https://tusitio.com",
  "description": "Descripción del sitio"
}

BlogPosting — artículos de blog:

{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "Título del artículo",
  "author": {
    "@type": "Person",
    "name": "Nombre del autor"
  },
  "datePublished": "2025-12-02",
  "image": "URL de portada"
}

Article — noticias; similar a BlogPosting, con requisitos algo más estrictos en Google.

Para TypeScript, astro-seo-schema:

npm install schema-dts astro-seo-schema

Validación

  1. Validador Schema.org — comprueba JSON-LD
  2. Google Rich Results Test — lo que Google interpreta

Usa ambos; a veces uno pasa y el otro avisa.

Errores frecuentes:

  • Campos obligatorios faltantes (datePublished)
  • URL de imagen relativa (usa absoluta)
  • JSON mal formado (comas o comillas)

Ver tu artículo con fecha y autor en Google merece la pena.

El rendimiento también es SEO

Google usa la velocidad en el ranking. ~55 % de usuarios abandona si la carga supera 3 segundos.

Core Web Vitals

LCP (Largest Contentful Paint): contenido principal visible. Objetivo < 2,5 s; > 4 s es malo.

FID (First Input Delay): respuesta al primer clic. Objetivo < 100 ms.

CLS (Cumulative Layout Shift): saltos de layout (botón que se mueve al cargar una imagen). Objetivo < 0,1.

Astro parte con buena base; con poco cuidado sueles cumplir.

Trucos de rendimiento en Astro

Imágenes

Suelen ser el cuello de botella. @astrojs/image (ahora en el core) optimiza:

# Versiones antiguas
# npm install @astrojs/image

Componente <Image>:


---

import { Image } from 'astro:assets';
import myImage from '../assets/my-image.jpg';

---

<Image
  src={myImage}
  alt="Descripción de la imagen"
  width={800}
  height={600}
  loading="lazy"
/>

Genera variantes responsive, WebP y lazy load. En un proyecto, LCP pasó de 4,2 s a 1,8 s con diez imágenes grandes.

Fuentes

Añade font-display: swap:

@font-face {
  font-family: 'MyFont';
  src: url('/fonts/my-font.woff2') format('woff2');
  font-display: swap; /* clave */
}

Mientras carga la fuente, texto con fuente del sistema — sin pantalla en blanco.

Google Fonts optimizado:

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">

El &display=swap al final importa.

Code splitting y lazy load

Islands ya parten el JS. Con React/Vue:


---

import MyHeavyComponent from '../components/MyHeavyComponent.jsx';

---

<!-- Carga JS solo cuando entra en viewport -->
<MyHeavyComponent client:visible />

Lighthouse

F12 → pestaña Lighthouse → «Analyze page load». Puntúa hasta 100 e lista problemas.

Antes de cada release corro Lighthouse y busco 90+. Si baja, investigo.

PageSpeed Insights mide URL en producción con datos de usuarios reales.

Con Astro en cero JS por defecto, mi blog pasó de 78 a 98 en Lighthouse.

Checklist práctico y problemas frecuentes

Checklist SEO (15 puntos)

Básico

  • site en astro.config.mjs
  • Componente BaseHead.astro centralizado
  • title único por página (50-60 caracteres)
  • description (120-160 caracteres)
  • Open Graph (title, description, image, url)
  • Twitter Card

Sitemap y robots

  • @astrojs/sitemap instalado
  • Enlace sitemap en <head>
  • robots.txt creado
  • Sitemap enviado en Search Console

Datos estructurados

  • JSON-LD WebSite en inicio
  • JSON-LD BlogPosting/Article en posts
  • Validador Schema.org OK
  • Google Rich Results Test OK

Rendimiento

  • Lighthouse ≥ 90
  • Core Web Vitals (LCP < 2,5 s, FID < 100 ms, CLS < 0,1)

Marca cada ítem. Con todo ✓, el SEO base de tu Astro está listo.

Solución de problemas

P1: Google no indexa

  1. robots.txt bloquea: revisa Disallow: /
  2. Sin sitemap en Search Console
  3. Sitio nuevo: 1-2 semanas es normal
  4. Contenido pobre: Google ignora páginas sin valor

P2: Error tras enviar sitemap

  • site correcto en astro.config.mjs
  • URL del sitemap accesible en el navegador
  • Páginas 404
  • En Baidu, no uses sitemap-index

P3: SEO en Baidu

  1. robots.txt con sitemap individual, no sitemap-index
  2. Envío manual en plataforma de webmasters de Baidu
  3. Indexación más lenta que Google
  4. Valora calidad y originalidad en chino

P4: Sitio multilingüe

Etiquetas hreflang:

<link rel="alternate" hreflang="zh-CN" href="https://tusitio.com/zh/article" />
<link rel="alternate" hreflang="en-US" href="https://tusitio.com/en/article" />
<link rel="alternate" hreflang="x-default" href="https://tusitio.com/en/article" />

x-default es la versión por defecto; Google entiende la relación entre idiomas.

Optimización continua

SEO no es «configurar y olvidar»:

Actualiza contenido: sitios vivos suelen posicionar ~30 % mejor. Publica 1-2 artículos por semana si puedes.

Monitoriza Search Console:

  • Keywords que traen tráfico
  • Páginas con muchas impresiones y poco CTR — mejora title/description
  • Errores de rastreo

Analiza búsquedas:

  • Qué términos llevan usuarios a tu sitio
  • Nuevo contenido alineado con esas queries
  • Refuerza keywords en artículos existentes

Mejora CTR bajo:

  • Title/description poco atractivos
  • Description más convincente
  • Números, preguntas o gancho emocional en title

Yo dedico ~1 h/semana a Search Console; a largo plazo se nota en rankings.

Conclusión

Astro nace con ventaja SEO y la configuración es manejable.

Tres pilares:

  1. Meta tags: title, description, OG — centralizados en BaseHead
  2. Sitemap y robots.txt: plugins oficiales + envío en Search Console
  3. JSON-LD: rich results en buscadores

No ignores rendimiento: Lighthouse 90+, lazy load en imágenes, font-display: swap.

Configurar SEO lleva tiempo; ver subir posiciones lo compensa. Con esta guía, 30 minutos para lo esencial; en una o dos semanas deberías ver indexación.

Abre tu proyecto Astro, sigue el checklist, envía el sitemap y espera. Vuelve en una semana: a menudo hay sorpresa agradable en rankings.

¡Ánimo!

Flujo completo de optimización SEO para sitios Astro

Configuración SEO completa en 30 minutos, de meta tags al posicionamiento, incluyendo sitemap, robots.txt y JSON-LD

⏱️ Estimated time: 30 min

  1. 1

    Step 1: Entender las ventajas SEO de Astro y configurar meta tags básicos

    Ventajas SEO naturales de Astro:
    • Cero JavaScript por defecto, genera HTML estático
    • Los crawlers ven contenido HTML puro
    • Arquitectura Islands: cuerpo estático, solo las partes interactivas cargan JS
    • Volumen de JS reducido un 90 %, Lighthouse de 78 a 98 puntos

    Trío básico:

    title (título)
    • Único y descriptivo en cada página
    • 50-60 caracteres
    • Incluye palabras clave

    description (descripción)
    • Descripción en cada página
    • 150-160 caracteres
    • Atrae clics

    keywords (palabras clave)
    • Google ya no las usa, otros buscadores sí pueden
    • Conviene mantenerlas, 3-5 palabras clave bastan

    En Astro:
    • Añade componente Head en el Layout
    • Lee title y description del frontmatter
    • Genera meta tags dinámicamente
  2. 2

    Step 2: Configurar Open Graph y Twitter Card

    Etiquetas Open Graph:
    • og:title: título al compartir, suele coincidir con title
    • og:description: descripción al compartir
    • og:image: imagen al compartir, recomendado 1200x630 px
    • og:url: URL completa de la página
    • og:type: tipo de página, article para blog, website para inicio

    Etiquetas Twitter Card:
    • twitter:card: summary_large_image o summary
    • twitter:title, twitter:description, twitter:image

    En Astro:
    • Crea componente SEO con title, description, image, etc.
    • Genera todas las etiquetas OG y Twitter
    • Úsalo en el Layout
  3. 3

    Step 3: Configurar sitemap y robots.txt

    Instalar integración Sitemap:
    • Ejecuta: npm install @astrojs/sitemap
    • Añade sitemap en astro.config.mjs
    • Configura la URL del sitio

    sitemap.xml automático:
    • Astro escanea todas las páginas
    • Genera sitemap.xml con URL, fecha de modificación, prioridad, etc.

    Crear robots.txt:
    • Archivo robots.txt en public/
    • Reglas para crawlers (permitir todo, indicar sitemap)

    Enviar sitemap:
    • Google Search Console
    • Envía la URL de sitemap.xml
    • Revisa indexación periódicamente
  4. 4

    Step 4: Añadir datos estructurados JSON-LD

    Por qué datos estructurados:
    • Resultados enriquecidos en búsqueda
    • Más información visible (valoración, autor, fecha, etc.)
    • Mejor CTR

    Tipos habituales:
    • Article: título, autor, fecha, categoría
    • BreadcrumbList: estructura del sitio
    • Organization: logo, contacto

    En Astro:
    • Componente de datos estructurados
    • JSON-LD según tipo de página
    • Usar en Layout

    Validar:
    • Google Rich Results Test
    • Revisar errores y advertencias
  5. 5

    Step 5: Mejores prácticas SEO y optimización continua

    Mejores prácticas: title y description únicos por página, HTML semántico (<article>, <section>, <header>), imágenes con alt, WebP, lazy load, URLs significativas, enlaces internos. Optimización continua: actualizar contenido (sitios actualizados suelen posicionar ~30 % mejor), monitorizar Search Console, analizar palabras clave de búsqueda. Rendimiento: Lighthouse 90+, lazy load en imágenes, font-display: swap.

FAQ

¿Por qué Astro es especialmente adecuado para SEO? ¿Qué ventajas naturales tiene?
Ventajas SEO de Astro:
• Cero JavaScript por defecto, HTML estático
• Los crawlers ven HTML puro sin esperar ejecución de JS

Arquitectura Islands:
• Cuerpo estático, solo partes interactivas cargan JS
• First paint muy rápido, ideal para crawlers de Google

Tras migrar de Next.js, el volumen de JS bajó un 90 % y Lighthouse pasó de 78 a 98.

Comparación:
• Astro: blogs, docs, marketing; datos 2025 muestran ~18 % de adopción entre desarrolladores
• Next.js: apps con mucha interacción (admin, e-commerce)
• Gatsby: estático similar, pero bundles más grandes y builds más lentos
¿Cómo configurar meta tags en un sitio Astro?
Trío básico:
• title (único, 50-60 caracteres, con keywords)
• description (150-160 caracteres, atractiva)
• keywords (Google no las usa, otros buscadores sí; conviene mantenerlas)

En Astro: Head en Layout, leer frontmatter, meta dinámicos.

Open Graph: og:title, og:description, og:image (1200x630), og:url, og:type.

Twitter Card: twitter:card, twitter:title, twitter:description, twitter:image.

Crea componente SEO centralizado en el Layout.
¿Cómo configurar sitemap y robots.txt?
Instalar: npm install @astrojs/sitemap, integración en astro.config.mjs, configurar site URL.

sitemap.xml: Astro genera automáticamente URL, lastmod, prioridad.

robots.txt en public/: reglas de crawlers y ruta del sitemap.

Enviar sitemap en Google Search Console.

Baidu SEO:
• No uses sitemap-index.xml en robots.txt; usa un sitemap individual
• Envío manual en la plataforma de webmasters de Baidu
• Indexación más lenta que Google
• Valora calidad y originalidad del contenido en chino
¿Cómo añadir datos estructurados JSON-LD?
Beneficios: resultados enriquecidos, más metadatos visibles, mejor CTR.

Tipos: Article, BreadcrumbList, Organization.

En Astro: componente JSON-LD según tipo de página en Layout.

Validar con Google Rich Results Test.

Errores habituales: formato JSON incorrecto, campos obligatorios faltantes.
¿Cuáles son las mejores prácticas SEO y cómo optimizar de forma continua?
Prácticas: title/description únicos, HTML semántico, imágenes optimizadas (alt, WebP, lazy load), URLs claras, enlaces internos.

Continuo: actualizar contenido (~30 % mejor ranking), monitorizar Search Console, analizar keywords de búsqueda.

Rendimiento: Lighthouse 90+, lazy load, font-display: swap.
¿Cómo configurar SEO en sitios multilingües?
Configura etiquetas hreflang:
• <link rel="alternate" hreflang="zh-CN" href="https://tusitio.com/zh/article" />
• <link rel="alternate" hreflang="en-US" href="https://tusitio.com/en/article" />
• <link rel="alternate" hreflang="x-default" href="https://tusitio.com/en/article" />

x-default indica la versión por defecto. Cada idioma con sitemap propio en Search Console.

11 min de lectura · Publicado el: 2 dic 2025 · Actualizado el: 21 ago 2026

Comentarios

Inicia sesión con GitHub para dejar un comentario

Easton BlogEaston Blog