Inicio rápido

Vas a mostrar «Hola» en /es/ y «Hello» en /en/, con enlaces para cambiar de idioma. Parte de un proyecto Astro estático que ya funciona. Solo necesitas dos archivos JSON, la integración y una página.

1. Instala astro-intl

Ejecuta el comando en la carpeta de tu proyecto, donde está package.json. Selecciona el gestor de paquetes de tu proyecto. El asistente de Astro te pedirá confirmar la instalación y la incorporación de la integración en astro.config.mjs.

npx astro add astro-intl

2. Crea los mensajes

Crea estas carpetas y archivos. greeting es la clave que usarás desde el código; su valor cambia según el idioma. Ambos archivos deben tener las mismas claves.

src/i18n/messages/en.json
{
  "greeting": "Hello"
}
src/i18n/messages/es.json
{
  "greeting": "Hola"
}

3. Conecta los mensajes

Completa la integración que añadió el asistente con las opciones de este ejemplo y añade los imports de mensajes. Conserva las demás integraciones y no añadas astroIntl(...) una segunda vez. locales enumera los idiomas y messages relaciona cada uno con su JSON. defaultLocale define el idioma predeterminado; no crea rutas ni redirige la raíz. El atributo with permite a Node cargar JSON desde este archivo. Este ejemplo se comprueba con Astro 7 y Node 22.12 o posterior.

astro.config.mjs
import { defineConfig } from "astro/config";
import astroIntl from "astro-intl";
import en from "./src/i18n/messages/en.json" with { type: "json" };
import es from "./src/i18n/messages/es.json" with { type: "json" };

export default defineConfig({
  integrations: [
    astroIntl({
      defaultLocale: "en",
      locales: ["en", "es"],
      messages: { en, es },
    }),
  ],
});

4. Crea la página traducida

Crea literalmente la carpeta [lang]. getStaticPaths genera /en/ y /es/ al compilar. setRequestLocale lee el idioma de la URL y carga sus mensajes; espera a que termine antes de llamar a getTranslations. t('greeting') obtiene el texto. No necesitas un layout ni middleware para este ejemplo.

src/pages/[lang]/index.astro
---
import { setRequestLocale, getTranslations } from "astro-intl";

export function getStaticPaths() {
  return [{ params: { lang: "en" } }, { params: { lang: "es" } }];
}

await setRequestLocale(Astro.url);
const t = getTranslations();
---

<!doctype html>
<html lang={Astro.params.lang}>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>{t("greeting")}</title>
  </head>
  <body>
    <h1>{t("greeting")}</h1>
    <nav aria-label="Language">
      <a href="/es/" lang="es">Español</a>
      <a href="/en/" lang="en">English</a>
    </nav>
  </body>
</html>

5. Abre los dos idiomas

Inicia el servidor y abre la dirección que muestra la terminal, añadiendo /es/ o /en/. Debes ver Hola y Hello, respectivamente. Prueba los enlaces de idioma. La página que ya tengas en / no cambia. Si cambias astro.config.mjs, reinicia el servidor.

npm run dev

6. Añade otra traducción

Añade farewell a ambos JSON y úsala en la misma página, debajo del h1. Cada texto nuevo sigue esta secuencia: misma clave en todos los idiomas, valores traducidos y una llamada a t().

src/i18n/messages/en.json
{
  "greeting": "Hello",
  "farewell": "Goodbye"
}
src/i18n/messages/es.json
{
  "greeting": "Hola",
  "farewell": "Adiós"
}
src/pages/[lang]/index.astro — <body>
<p>{t("farewell")}</p>

Si algo no aparece

Un 404 en /es/ suele indicar que falta [lang]/index.astro o su getStaticPaths. Si aparece una clave en vez del texto, revisa que exista en ambos JSON. Si falta el contexto del idioma, comprueba el await setRequestLocale antes de getTranslations. No es necesario configurar el i18n nativo de Astro para este recorrido.