Configuración
1. Crear archivos de mensajes
Crea un archivo JSON por locale dentro de src/i18n/messages/. Puedes organizar las claves en namespaces (objetos anidados).
{
"nav": {
"home": "Home",
"docs": "Documentation"
},
"hero": {
"title": "Hello, World!",
"description": "Welcome to <bold>astro-intl</bold>"
}
}2. Elige tu enfoque
astro-intl ofrece tres formas de cargar mensajes. Elige la que mejor se adapte a tu proyecto.
createIntlMiddleware, debes pasar defaultLocale y locales directamente en astro.config.mjs para que funciones como getLocales(), getDefaultLocale() e isValidLocale() funcionen correctamente. Opción A — Messages en config (recomendado)
Pasa tus imports de mensajes junto con defaultLocale y locales directamente en astro.config.mjs. No se necesitan archivos extra.
import { defineConfig } from "astro/config";
import astroIntl from "astro-intl";
export default defineConfig({
integrations: [
astroIntl({
defaultLocale: "en",
locales: ["en", "es"],
messages: {
en: () => import("./src/i18n/messages/en.json"),
es: () => import("./src/i18n/messages/es.json"),
},
}),
],
});Opción B — Custom request.ts (avanzado)
Para control total, usa defineRequestConfig para crear un archivo de request — similar a next-intl. Esto te permite agregar lógica personalizada como obtener mensajes desde un CMS. Todavía necesitas pasar defaultLocale y locales en astro.config.mjs.
import { defineRequestConfig } from "astro-intl";
export default defineRequestConfig(async (locale) => {
return {
locale,
messages: (await import(`./messages/${locale}.json`)).default,
};
});astro.config.mjs con locales:
import { defineConfig } from "astro/config";
import astroIntl from "astro-intl";
export default defineConfig({
integrations: [
astroIntl({
defaultLocale: "en",
locales: ["en", "es"],
}),
],
});Opción C — messagesDir (JSON simplificado)
Configura messagesDir con una ruta de directorio y la integración cargará automáticamente los archivos {locale}.json. No necesitas imports manuales — perfecto para flujos de trabajo basados en JSON.
import { defineConfig } from "astro/config";
import astroIntl from "astro-intl";
export default defineConfig({
integrations: [
astroIntl({
defaultLocale: "en",
locales: ["en", "es"],
messagesDir: "./src/i18n/messages",
}),
],
});3. Configurar tu Layout
Mejor práctica: Llama a setRequestLocale una sola vez en un layout compartido (ej: src/layouts/Layout.astro) en lugar de repetirlo en cada página. Esto inicializa el contexto global de i18n antes de que cualquier componente lea traducciones.
Con Opción A (messages en config):
---
import { setRequestLocale } from "astro-intl";
// No need to import anything — messages come from astro.config
await setRequestLocale(Astro.url);
---
<!DOCTYPE html>
<html>
<head>
<title>My Site</title>
</head>
<body>
<slot />
</body>
</html>Con Opción B (defineRequestConfig):
---
import { setRequestLocale } from "astro-intl";
import "../i18n/request"; // registers defineRequestConfig
await setRequestLocale(Astro.url);
---
<!DOCTYPE html>
<html>
<head>
<title>My Site</title>
</head>
<body>
<slot />
</body>
</html>3b. Enfoque con Middleware (alternativa)
En lugar de llamar a setRequestLocale en cada layout, puedes usar createIntlMiddleware para manejarlo automáticamente en todas las rutas. Esto también establece locales y defaultLocale en el store, por lo que no necesitas pasarlos en astro.config.mjs.
Crea un archivo de routing:
export const routing = {
locales: ["en", "es"],
defaultLocale: "en",
} as const;Crea el middleware:
import "@/i18n/request";
import { createIntlMiddleware } from "astro-intl/middleware";
import { routing } from "@/i18n/routing";
export const onRequest = createIntlMiddleware(routing);Tu astro.config.mjs se mantiene simple:
import { defineConfig } from "astro/config";
import astroIntl from "astro-intl";
export default defineConfig({
integrations: [astroIntl()],
});4. Exportar getStaticPaths
En cada página [lang], exporta getStaticPaths retornando todos los locales soportados para que Astro pueda pre-renderizarlos.
export function getStaticPaths() {
return [
{ params: { lang: "en" } },
{ params: { lang: "es" } },
];
}