Conclusión: un sitio Astro multilingüe es un problema estructural antes que un problema de traducción. Configura carpetas de contenido limpias por idioma, extrae cada fragmento traducible en un solo CSV, tradúcelo en el modo Multi-language Columns y luego recompón los archivos mediante scripts. Una vez que el flujo de trabajo está listo, añadir un nuevo idioma es una operación de un solo CSV.
Este es exactamente el flujo de trabajo que usamos para mantener ai-glot.com en seis idiomas (inglés, francés, alemán, español, italiano y portugués) sin reescribir ni un solo post a mano. Lo recorreremos de principio a fin, incluyendo los prompts que usamos para estructurar cada paso con un asistente de IA como Claude Code o Cursor.
El objetivo
Al final de esta guía, tendrás:
- Una estructura limpia de enrutamiento i18n en tu proyecto Astro, con una carpeta por idioma.
- Un script reutilizable que extrae cada cadena traducible de un archivo markdown (o una exportación de CMS) a un único CSV.
- Un CSV traducido generado en AI Glot usando el modo Multi-language Columns.
- Un segundo script que vuelve a montar los archivos markdown traducidos, corrigiendo las rutas de imagen y los enlaces internos para los subdirectorios localizados.
- Un archivo de instrucciones (skill file) que puedes dar a tu asistente de IA para que cada nuevo artículo se publique listo para traducir por defecto.
Si ya usas Weglot, Crowdin o un CMS headless que exporta CSV, puedes saltarte el script de extracción de markdown y subir esas exportaciones directamente a AI Glot. La lógica de traducción y recomposición es la misma.
Requisitos previos
Una breve lista antes de empezar.
- Un proyecto Astro (v4 o v5) ejecutándose localmente, con colecciones de contenido configuradas para tu blog.
- Node 20 o superior, para que las APIs modernas de CSV y
fs/promisesfuncionen correctamente. - Un espacio de trabajo en AI Glot (el plan gratuito es suficiente para el primer lote).
- Un asistente de IA en tu editor para generar el código base (Claude Code, Cursor, Copilot o Codeium, el que prefieras).
Por qué Astro es ideal para el multilingüismo a gran escala
Astro renderiza HTML estático por defecto, lo que significa que cada página localizada es simplemente un archivo en el disco. No hay una capa de traducción en tiempo de ejecución, ni consultas a bases de datos para cambiar de idioma, ni paquetes de JavaScript por descargar para cada idioma. Google indexa cada versión de idioma como una URL distinta con sus propias metaetiquetas, y el resultado del build es, en esencia, un espejo traducido de tu estructura en inglés.
Esto es exactamente lo que buscas para el SEO. El SEO multilingüe funciona mejor cuando cada idioma tiene su propia página estática rastreable, con las etiquetas hreflang adecuadas y una estructura de URL limpia. Astro te ofrece eso de serie.
La contrapartida: eres responsable de mantener sincronizados los archivos de contenido en todos los idiomas. Ese es precisamente el problema que resuelve el flujo de trabajo con CSV que detallamos a continuación.
Parte 1: Configurar la estructura de enrutamiento i18n
Astro 4 introdujo una configuración i18n de primer nivel. El patrón más limpio consiste en declarar tus idiomas, establecer el valor predeterminado sin prefijo (para que el inglés viva en /blog/mi-post y el francés en /fr/blog/mi-post) y replicar tus colecciones de contenido en una carpeta [lang]/ por cada idioma.
Aquí tienes la estructura objetivo para un blog con seis idiomas:
src/
content/
blog/
live/ # English (default locale)
my-first-post.md
fr/live/ # French
my-first-post.md
de/live/ # German
my-first-post.md
es/live/ # Spanish
my-first-post.md
it/live/ # Italian
my-first-post.md
pt/live/ # Portuguese
my-first-post.md
pages/
blog/[slug].astro # English routes
[lang]/blog/[slug].astro # Localized routes
i18n/
ui.ts # UI string dictionary per locale
Observa que los archivos markdown localizados se encuentran un nivel más profundo que los de inglés. Esa profundidad es importante: las rutas relativas de las imágenes en el markdown localizado necesitan un ../ adicional para llegar a src/assets/. El script de recomposición de la Parte 4 gestiona esto automáticamente.
Si prefieres no escribir este andamiaje a mano, entrega el siguiente prompt a tu asistente de IA. Es genérico a propósito para que funcione en cualquier proyecto Astro y hace las preguntas de aclaración necesarias antes de generar código.
You are helping me scaffold internationalization (i18n) in an existing Astro
project. I want to translate my entire site into multiple languages while
keeping clean URLs, proper hreflang annotations, and per-locale static pages.
Objetivos:
1. Declarar los locales en astro.config.mjs usando la opción nativa `i18n`.
El idioma por defecto NO debe tener prefijo (ej. inglés vive en `/blog/...`,
francés en `/fr/blog/...`).
2. Crear una estructura de carpetas por idioma para mis colecciones de contenido,
de modo que cada artículo del blog tenga un archivo 1:1 por idioma. Los
archivos en inglés se quedan en su ubicación actual; los localizados van
un nivel más profundo (ej. `src/content/blog/fr/live/`).
3. Añadir un diccionario de cadenas de UI tipado en `src/i18n/ui.ts` que exporte
un objeto indexado por idioma, además de un helper `useTranslations(lang)`.
4. Actualizar el esquema de la colección de contenido para que la misma definición
de Zod se aplique a cada carpeta de idioma.
5. Generar el archivo de ruta dinámica `src/pages/[lang]/blog/[slug].astro` que
lea de la colección de contenido localizada y use el inglés como fallback
cuando falte la versión traducida.
6. Añadir un componente `<LanguageSwitcher />` que renderice un enlace por idioma,
preservando la ruta (pathname) actual.
7. Inyectar etiquetas `<link rel="alternate" hreflang="..." />` en el layout para cada
idioma en el que la página esté disponible.
Antes de generar código, pregúntame:
- La lista de idiomas objetivo (códigos BCP 47) y cuál es el predeterminado.
- La ruta de mis colecciones de contenido actuales y archivos de ruta actuales.
- Si quiero el selector de idioma en el encabezado, en el pie de página o en ambos.
- Si guardo las cadenas de UI en JSON, TS o en otro lugar actualmente.
Luego realiza los cambios en commits pequeños y precisos. No refactorices
código no relacionado. Muéstrame el diff y explica cualquier decisión donde
haya dos patrones válidos (por ejemplo, idioma predeterminado con o sin prefijo).
Este patrón es intencionado: aclarar, luego construir. Al principio intentamos el enfoque de “genera todo de golpe” y terminamos con tres componentes de selección de idioma diferentes y un esquema de enrutamiento que entraba en conflicto con el esquema de las colecciones. Pedirle al asistente que te pregunte primero te ahorra una hora de limpieza posterior.
Parte 2: Extraer el contenido a un CSV de traducción

Aquí es donde la mayoría de los equipos se quedan atascados.
Aquí es donde la mayoría de los equipos se quedan atascados. La traducción en sí es la parte fácil. Extraer el contenido y volver a insertarlo en una herramienta de traducción sin romper la estructura es lo difícil.
El truco que hace brillar al modo Multi-language Columns de AI Glot es la extracción fragmentada. Divides cada archivo markdown en las unidades traducibles con sentido más pequeñas posibles (un campo del frontmatter, un par de pregunta-respuesta de FAQ o un solo párrafo), escribes cada fragmento como una fila en un CSV y añades una columna por cada idioma de destino. El resultado se ve así:
| path | English string | fr | de | es | it | pt |
|---|---|---|---|---|---|---|
| live/my-first-post.md | Cómo traducir un sitio web de Astro a gran escala en muchos idiomas | |||||
| live/my-first-post.md | Un tutorial práctico de copiar y pegar para lanzar un sitio Astro multilingüe. | |||||
| live/my-first-post.md | Astro renderiza HTML estático por defecto, lo que significa que cada página localizada es simplemente un archivo en el disco. |

¿Por qué fragmentado?
¿Por qué fragmentado? Porque la traducción con IA funciona mucho mejor en unidades coherentes del tamaño de un párrafo que en documentos completos. Las reglas del glosario se aplican de forma consistente. Los presupuestos de tokens se mantienen predecibles. Y si un fragmento necesita un ajuste, editas una celda, no un archivo de 2000 palabras.
Opción A: Guardas el contenido como archivos markdown (blog, documentación, páginas de aterrizaje)
Usa este prompt para generar un script de extracción adaptado a tu repositorio. Utilizamos una versión casi idéntica para el sitio web de AI Glot.
Write a Node.js script at `scripts/extract-translations.mjs` that prepares a
CSV for bulk translation in AI Glot.
Entradas:
- Un directorio de origen que contenga archivos markdown en inglés
(p. ej., `src/content/blog/live/`).
- Una lista de códigos de configuración regional de destino (p. ej., `fr de es it pt`).
- Una ruta CSV de salida (por defecto `multilang-translation.csv`).
Para cada archivo markdown:
1. Analiza el frontmatter utilizando `gray-matter`.
2. Extrae estas cadenas traducibles, una por fila de CSV:
- `title` (frontmatter)
- `metaDescription` (frontmatter)
- Para cada entrada en `faqs`: la `question` y la `answer` como filas separadas.
- Cada párrafo del cuerpo, dividiendo el cuerpo del markdown en `\n\n` para que los párrafos,
listas de viñetas, bloques de citas y encabezados se conviertan cada uno en una fila.
3. OMITE estos fragmentos (no los incluyas en el CSV):
- Líneas de imagen puras que comiencen con `
Un blog de 30 publicaciones con cinco idiomas de destino se procesa habitualmente en pocos minutos en el modo Estándar, y puedes cambiar al modo Pro para obtener una salida de mayor calidad en las filas más importantes (títulos, metadescripciones, párrafos principales).
Consejo: una vez subido el archivo a AI Glot, puedes eliminar la versión local con las columnas vacías. Tu espacio de trabajo es la fuente de verdad a partir de ese momento y siempre puedes volver a descargarlo.

Parte 4: Reensamblar el markdown traducido en Astro
Ahora tienes un archivo multilang-translation_translated.csv con todas las columnas de destino completas. La tarea consiste en tomar cada fragmento traducido y volver a escribirlo en el archivo markdown localizado correspondiente, preservando exactamente la estructura original.
Aquí es donde la extracción fragmentada vuelve a dar sus frutos. Dado que cada fila está identificada por el fragmento original en inglés, puedes simplemente buscar y reemplazar los fragmentos en inglés con su contraparte localizada dentro del archivo de origen original y luego guardar el resultado en la carpeta localizada. Sin análisis de AST, sin idas y vueltas de markdown, sin riesgo de romper el formato.
En la reconstrucción deben realizarse dos ajustes estructurales:
- Rutas de imagen. Los archivos en inglés hacen referencia a recursos con
../../../../assets/.... Los archivos localizados están un nivel de carpeta más profundo, por lo que la ruta relativa se convierte en../../../../../assets/.... - Enlaces internos. Un enlace como
/blog/glossary-website-translationsen inglés debe convertirse en/es/blog/glossary-website-translationsen español (y así para cada idioma).
Aquí tienes el prompt que usamos para generar el script de reensamblaje. Es lo suficientemente genérico como para integrarse en cualquier proyecto de Astro que siga la estructura de la Parte 1.
Use the unified assembly script at `scripts/assemble-blog-translations.mjs` that rebuilds
localized markdown files from an AI Glot Multi-language Columns CSV.
Entradas (argumentos de CLI):
- Ruta al CSV traducido (p. ej., `multilang-translation_translated.csv`)
con las columnas `path, English string, fr, de, es, it, pt`.
- El directorio de origen que contiene los archivos markdown originales en inglés
(por defecto `src/content/blog/live/`).
- El patrón del directorio de destino para los archivos localizados
(por defecto `src/content/blog/{lang}/live/`).
- El origen del sitio utilizado para los enlaces internos (por defecto `https://ai-glot.com`).
Para cada valor de `path` único en el CSV:
1. Lee el archivo original en inglés de `<sourceDir>/<path>`.
2. Para cada columna de locale de destino (todo lo que está después de `English string`):
a. Empieza con el texto completo del archivo en inglés.
b. Para cada fila que coincida con esta `path`, busca el `English string`
literalmente en el archivo y reemplázalo con el valor de la columna del
locale de destino. Usa reemplazo de cadena literal, no regex. Lanza un error si el
fragmento en inglés no se encuentra (eso significa que el origen cambió respecto al CSV;
esto debería fallar de forma explícita en lugar de omitirse silenciosamente).
c. Tras todos los reemplazos, ejecuta dos ajustes estructurales en el texto resultante:
- Rutas de imagen: reemplaza cada aparición de `../../../../assets/` por
`../../../../../assets/` (un `../` adicional porque los archivos localizados están
un nivel más profundo).
- Enlaces internos: reemplaza cada URL interna absoluta de este sitio
(p. ej., `https://ai-glot.com/blog/...`) y cada ruta relativa a la raíz
(p. ej., `/blog/...`, `/sign-up`) por el equivalente con prefijo de locale
(`/es/blog/...`, `/es/sign-up`). Omite anclas (`#...`), URLs externas,
y enlaces `mailto:` / `tel:`.
d. Escribe el archivo en `<destDir resuelto con este lang>/<path>`. Crea
los directorios según sea necesario.
3. Después de procesar todas las rutas, imprime un resumen: archivos escritos por locale,
total de reemplazos y cualquier fragmento que no se haya podido encontrar.
Robustez:
- Usa `papaparse` para leer el CSV. Elimina el BOM si está presente.
- Preserva el formato exacto del frontmatter (delimitadores, orden de las claves, comillas).
La forma más sencilla es realizar reemplazos en la cadena de texto base del archivo, no en un
AST analizado.
- Sé idempotente: ejecutar el script dos veces con las mismas entradas produce las
mismas salidas.
Haz que sea un único archivo independiente. Uso:
`node scripts/assemble-blog-translations.mjs translated.csv`
Ejecuta el script y verás aparecer una oleada de nuevos archivos en src/content/blog/fr/live/, src/content/blog/de/live/, y así sucesivamente. Haz una comprobación aleatoria en uno, ejecuta astro dev y tus rutas localizadas deberían renderizarse al instante.

Bonus 1: Un archivo de habilidades para que cada artículo sea “traducible por defecto”
Una vez que el flujo de trabajo funciona, querrás que cada artículo futuro pase por él de la misma manera. El truco: guarda la convención como un archivo de habilidades (skill file) que tu asistente de IA lea antes de escribir cualquier post nuevo.
Si usas Claude Code, Cursor o cualquier editor de IA que cargue instrucciones a nivel de proyecto, añade este archivo a tu repositorio como skills/blog_translation_workflow.md. Usamos exactamente este patrón en AI Glot.
---
name: blog_translation_workflow
description: How to ship a new blog post so it can be translated in bulk later.
---
# Flujo de trabajo para la traducción del blog
Al escribir una nueva entrada de blog o un elemento del CMS, sigue estas convenciones para que fluya sin problemas a través de la canalización de extracción multilingüe.
## 1. Ubicación y nomenclatura de archivos
- Los borradores se guardan en `src/content/blog/draft/`.
- Slug = nombre de archivo = la misma cadena utilizada en el frontmatter `slug:`.
- Mover a `src/content/blog/live/` solo después de la revisión.
## 2. Contrato del Frontmatter
Cada post DEBE tener:
- `title`: tipo oración (mayúscula inicial), sin punto final.
- `metaDescription`: de 140 a 160 caracteres, oración completa.
- `coverImage`: ruta relativa desde la ubicación de este archivo.
- `publishedDate`: fecha en formato ISO.
- `slug`: coincide con el nombre del archivo.
- `faqs`: array de `{ question, answer }`. Mínimo 3 elementos.
## 3. Estructura del cuerpo que facilite la traducción
- Usa encabezados en formato oración (no Title Case con cada palabra en mayúscula).
- Mantén los párrafos entre 1 y 4 oraciones. Cada párrafo se convierte en una fila del CSV, por lo que los párrafos más cortos se traducen de forma más fiable.
- Nunca pongas dos imágenes seguidas; sepáralas siempre con al menos un párrafo de texto explicativo.
- Los enlaces internos usan rutas relativas a la raíz (`/blog/...`, `/sign-up`).
- Las rutas de imagen usan `../../../../assets/...` (profundidad de la versión en inglés).
## 4. Después de publicar
Ejecuta:
```bash
node scripts/extract-translations.mjs src/content/blog/live/<slug>.md \
multilang-translation.csv fr de es it pt
```
para añadir los fragmentos traducibles de este artículo al CSV maestro. Sube el CSV a AI Glot en el modo de Columnas Multilingües y después ejecuta:
```bash
node scripts/assemble-blog-translations.mjs multilang-translation_translated.csv
```
para generar los archivos markdown localizados.
## 5. Antipatrones
- NO uses guiones largos (em-dashes); usa comas o dos puntos.
- NO pongas párrafos enteros en negrita. Usa negrita solo para frases clave.
- NO omitas la sección de preguntas frecuentes (FAQs); son los bloques que más potencian el SEO.
- NO incluyas HTML puro dentro del markdown a menos que sea estrictamente necesario; complica el reensamblaje basado en fragmentos.
La próxima vez que tú (o alguien de tu equipo) escribáis un artículo nuevo, el asistente leerá este archivo primero y producirá un post que se ajuste a la canalización sin necesidad de limpieza manual.
Bonus 2: Añadir un nuevo idioma a todo tu blog en un solo lote
Esta es la parte que más sorprende a la gente. Una vez que el sistema existe, añadir un nuevo idioma es una operación de un solo CSV para todo el archivo de tu blog.
Supongamos que tienes 80 artículos traducidos al francés, alemán, español, italiano y portugués, y decides añadir el neerlandés.
El flujo de trabajo:
- Vuelve a ejecutar tu script de extracción añadiendo
nla la lista de locales. Como el script lee de la carpeta de origen en inglés, se incluyen todos los artículos (antiguos y nuevos). - Abre el CSV. La columna
English stringes idéntica a la anterior. Las columnasfr, de, es, it, ptsiguen vacías (el script no mira las traducciones existentes; solo construye la matriz vacía). La columnanles nueva y está vacía. - Elimina las columnas que no necesites retraducir. Borra
fr, de, es, it, ptde la hoja de cálculo y manténpath, English string, nl. - Súbelo a AI Glot y ejecuta el modo de Columnas Multilingües con
nlcomo único objetivo. - Ejecuta el script de reensamblaje con el nuevo CSV. Escribirá cada artículo en
src/content/blog/nl/live/.
Pasaste de “necesitamos añadir neerlandés” a “neerlanés publicado” en una sola carga. Para 80 artículos. Así es como se ve cuando el flujo de trabajo hace el trabajo, no el equipo.
El mismo patrón sirve para cambios puntuales: edita un solo párrafo en inglés, vuelve a exportar solo los fragmentos afectados, tradúcelos y reconstruye. Las actualizaciones siguen siendo económicas porque el proceso es estructural, no basado en documentos.
Lista de verificación
Antes de subir a producción, verifica cada idioma:
npm run build(oastro build) se completa sin errores deImageNotFound.- Pasa el ratón por el selector de idiomas en un post localizado y confirma que la URL es correcta.
- Abre un post en francés y revisa: título, meta descripción, los tres primeros párrafos y una respuesta de FAQ. Compara con el original.
- Haz clic en un enlace interno dentro del post en francés. Debería llevarte a otra página en francés, no volver al inglés.
- Inspecciona el
<head>para ver las anotacioneshreflangcorrectas en todos los idiomas. - Realiza una auditoría Lighthouse en una URL localizada; la puntuación SEO debería ser la misma que la de su equivalente en inglés.
Si alguno de estos falla, los culpables más comunes son: profundidad incorrecta de la ruta de la imagen, un enlace interno que no detectó el regex o un fragmento que varió entre la extracción y el reensamblaje. Las advertencias de “could not find chunk” del script de reensamblaje te indicarán exactamente dónde mirar.
Conclusión
Un sitio de Astro multilingüe a gran escala no es un proyecto de traducción. Es una canalización de contenido. Configura bien el sistema (enrutamiento de locales, extracción de fragmentos en CSV, traducción con AI Glot, reensamblaje determinista) y traducir un nuevo artículo, corregir un párrafo o añadir un nuevo idioma se convertirá en una operación rutinaria en lugar de una iniciativa trimestral.
Las piezas que lo hacen posible:
- El sistema i18n nativo de Astro para páginas estáticas limpias por idioma.
- Un pequeño script de extracción que convierte el markdown en un CSV traducible.
- El modo Columnas Multilingües de AI Glot para completar todos los idiomas de una sola vez, con control de glosario e instrucciones.
- Un script de reensamblaje que gestiona la profundidad de las imágenes y la localización de enlaces internos.
- Un archivo de habilidades para que cada artículo nuevo encaje en el sistema por defecto.
¿Listo para lanzar en varios idiomas? Crea tu espacio de trabajo en AI Glot, sube tu primer CSV de extracción y mira cómo tu blog se publica en seis idiomas antes de que acabe la tarde.