Volver a artículos
8 min de lecturaastro-ssg-aws-s3-cloudfront

Escrito por Rodrigo de Miguel

Preparar un blog en Astro con buen criterio (2/5)

(SSG, sitemap y sin complicarnos la vida)

Cómo preparar un blog en Astro partiendo del template oficial, haciendo pequeños ajustes para dejarlo más ordenado, con HTML estático, sitemap y URLs consistentes, sin complicarse ni montar infraestructura innecesaria.

Astro
Static Site Generation SSG
SEO
Core Web Vitals CWV
Web Performance Optimization WPO

No estamos montando nada grande (y está bien así)

Este post es el segundo de la serie y conviene aclarar algo desde el principio.

No estamos montando:

  • un SaaS
  • una plataforma
  • ni un sistema complejo

Para simplicar, partimos del template de blog de Astro (para entender cómo funciona) y haremos un par de ajustes sencillos —los mismos que yo hice en este portfolio personal— para dejarlo un poco más ordenado, más consistente. Cosas básicas para SEO.

Nada más.

La idea es:

  • entender qué hace cada cosa
  • no aceptar configuraciones “porque sí”
  • y dejar el proyecto en un estado cómodo para seguir avanzando
  • después ya puedes elegir Vercel si quieres, pero entendiendo bien qué hay debajo

Qué buscamos con este post

Al terminar este artículo deberíamos tener:

  • Un blog de Astro funcionando
  • HTML estático generado (SSG)
  • URLs consistentes
  • Sitemap automático
  • Todo probado en local

No es “producción final”.
Es un buen punto de partida, limpio y sin sorpresas.

Paso 1 — Crear el proyecto con el template de blog

Vamos a ir rápido aquí, porque Astro ya hace muy bien este trabajo e internet está lleno de tutoriales sobre cómo empezar con Astro.

BASH
npm create astro@latest

Durante el asistente:

  • Elige el template de blog
  • TypeScript: sí (recomendado)
  • Frameworks extra: no hace falta ahora
  • Instalar dependencias: sí

Con esto ya tienes:

  • páginas
  • posts en Markdown
  • navegación básica

Comprobación rápida

BASH
npm run dev

Abre el navegador y asegúrate de que:

  • carga el blog
  • puedes entrar a un post
  • no hay errores raros

Si aquí todo va bien, seguimos.

Paso 2 — Qué tipo de blog estamos haciendo (SSG)

Antes de tocar configuración, merece la pena parar un segundo.

Este blog:

  • no tiene backend
  • no tiene datos dinámicos
  • no personaliza contenido

Eso lo convierte en un candidato perfecto para Static Site Generation.

SSG significa simplemente:

generar el HTML una vez y servirlo tal cual

Y para un blog o portfolio, suele ser la opción más simple y más efectiva.

Paso 3 — Dejar claro que usamos SSG

Astro usa SSG por defecto, pero a mí me gusta dejarlo explícito. No porque sea obligatorio, sino por claridad mental.

JS
// astro.config.mjs import { defineConfig } from 'astro/config' export default defineConfig({ output: 'static', })

Esto no cambia nada funcionalmente, pero cuando vuelvas dentro de seis meses sabrás exactamente qué tipo de proyecto es.

Probar el build

BASH
npm run build

Si se genera la carpeta "dist/" con HTML dentro, todo está correcto.

Nota rápida: Asegúrate de que dist/ está en tu .gitignore. Es contenido generado, no debe subirse al repo.

Paso 4 — Un pequeño detalle importante: las URLs

Este es uno de esos detalles que no se notan al principio, pero conviene decidir pronto.

En otros proyectos he sufrido por no tener esto claro desde el principio. URLs duplicadas, problemas con los canonicals, ...

Otros frameworks como Wordpress ya te lo imponen, aunque personalmente me gusta más sin el slash final, Google lo prefiere así.

Para este caso usamos:

JS
trailingSlash: 'always'

Eso hace que:

  • /contacto/ sea la URL final
  • se genere /contacto/index.html

No es que sea “mejor” que otras opciones. Es simplemente consistente, y eso es lo que le gusta a Google.

Luego con CloudFront Functions haremos que no haga falta escribir index.html en las URLs y resolveremos al fichero correcto en S3. Si no lo hacemos queda muy de los 90s.

Mientras uses un server Astro (o el npm run preview) no hay problema, la url no contiene el index.html. Pero como vamos a servir desde S3+CloudFront, hay que tenerlo en cuenta, ya que retornamos el fichero estático. Es equivalente a abrir el fichero en el navegador.

Asegurate que el enalzado interno tiene el mismo formato (con slash final). Si no Astro te lo indica.

Ejemplo completo:

JS
export default defineConfig({ output: 'static', // default value, Static Site Generation trailingSlash: 'always', // Manage trailing slashes in URLs for SEO and serve HTML from Cloudfront. We will discuss this later. site: SEO_BASE_URL, // The base URL of your website for sitemap, canonical URLs, internal linking, etc. Should be 'https://yourdomain.com' })

Nota: Google no prefiere always ni never. Prefiere que uses una o la otra, ambas duplican URLs y Google te penaliza.

Paso 5 — Añadir sitemap

Aunque Google no necesita el sitemap para indexar tu web, es una buena práctica tenerlo. Le facilitas el trabajo y le das pistas sobre qué páginas son más importantes y con qué frecuencia cambian.

Astro lo hace fácil con @astrojs/sitemap. En la demo viene incluido, pero aquí te dejo cómo añadirlo desde cero.

Instalar

BASH
npm install @astrojs/sitemap

Configuración sencilla

JS
import sitemap from '@astrojs/sitemap' export default defineConfig({ output: 'static', trailingSlash: 'always', site: SEO_BASE_URL, integrations: [ sitemap({ changefreq: 'weekly', priority: 1, // Google is king, and the truth is that it ignores this. lastmod: new Date(), // Enough to get started i18n: { // If you have multiple languages defaultLocale: 'es', locales: { es: 'es-ES', en: 'en-US', }, }, }), ], })

No es la configuración perfecta del mundo, pero:

  • funciona
  • es clara
  • y se puede mejorar más adelante

Que es justo lo que buscamos ahora.

Paso 6 — Probar todo en local, con calma

Antes de seguir avanzando, prueba esto:

BASH
npm run build npm run preview

Comprueba:

  • que el blog navega bien
  • que las URLs son coherentes
  • que /sitemap.xml existe

No hace falta obsesionarse. Solo asegurarnos de que no hay sorpresas.

Cosas que NO vamos a hacer

Para este tutorial no vamos a añadir:

  • CMS
  • bases de datos
  • SSR
  • analytics complejas
  • plugins innecesarios

No porque estén mal, sino porque no hacen falta aquí.

Menos cosas significa:

  • menos decisiones
  • menos mantenimiento
  • menos ruido

Checklist rápida antes de seguir

  • El blog funciona con el template base
  • El build genera HTML
  • Las URLs son consistentes
  • El sitemap se genera
  • Todo se prueba en local

Si esto está OK, ya tenemos una base más que suficiente.

Qué hemos hecho realmente

Si te fijas, no hemos hecho nada espectacular:

  • Usar el template oficial
  • Aclarar que usamos SSG
  • Definir URLs
  • Añadir sitemap

Pero con eso:

  • el blog queda más ordenado
  • es más fácil de mantener
  • y está mejor preparado para SEO

Pequeños pasos, buen criterio.

No hace falta montar nada complejo para hacer las cosas bien.

Un par de decisiones conscientes al principio hacen que todo lo demás sea más sencillo.

Y de eso va esta serie.

Ahora que el blog genera HTML perfecto:

Vamos a servirlo como es debido.

Posts de la serie

1️⃣ Parte 1: Un blog no debería ser un SaaS
👉 Parte 2: Preparar un blog en Astro con buen criterio
3️⃣ Parte 3: S3 + CloudFront para servir un blog estático rápido y barato
5️⃣ Parte 4: Dominio con Route 53 y CloudFront para un blog Astro SSG
5️⃣ Parte 5: Automatizar el despliegue de un blog Astro SSG con GitHub Actions y AWS
🐙 GitHub Repo: demo-astro-ssg-s3-cloudfront

¿Hablamos?

¿Buscas a alguien que entienda el producto tanto como el código?

Abrir conversación

© 2026 Rodrigo de Miguel. Todos los derechos reservados.