Lingui.js es un framework de internacionalización (i18n) ligero pero potente para aplicaciones JavaScript y React. Utiliza archivos PO (Portable Object) estándar de la industria para catálogos de traducción, potentes macros en tiempo de compilación para una experiencia de desarrollador limpia y produce paquetes optimizados de menos de 2 kB. Esta guía cubre todo, desde la configuración del proyecto hasta flujos de trabajo de archivos PO, pluralización y automatización de traducciones con l10n.dev.
Lingui.js destaca entre las bibliotecas i18n de JavaScript por su combinación de experiencia de desarrollador, rendimiento y flujos de trabajo de traducción profesional:
Instala los paquetes principales y las herramientas de desarrollo de Lingui. Los paquetes de tiempo de ejecución (@lingui/core y @lingui/react) son necesarios en producción, mientras que la CLI, el plugin de Vite y la macro de Babel son solo para desarrollo:
npm install @lingui/core @lingui/react
npm install --save-dev @lingui/cli @lingui/vite-plugin @lingui/babel-plugin-lingui-macroLingui requiere dos archivos de configuración: la configuración de Lingui (que define las configuraciones regionales y las rutas del catálogo) y la configuración de tu herramienta de compilación (para habilitar macros en tiempo de compilación).
Crea un archivo lingui.config.js en la raíz de tu proyecto. Esto define tu configuración regional de origen, las configuraciones regionales de destino, dónde almacenar los catálogos PO y el formato del catálogo. El formato PO es la opción predeterminada y recomendada:
// lingui.config.js
import { defineConfig } from "@lingui/cli";
import { formatter } from "@lingui/format-po";
export default defineConfig({
sourceLocale: "en",
locales: ["en", "fr", "de", "ja", "es", "zh-CN"],
catalogs: [
{
path: "<rootDir>/src/locales/{locale}/messages",
include: ["src"],
},
],
format: formatter({ lineNumbers: false }),
});Si usas Vite, añade el plugin de Lingui junto con el plugin de React con la macro de Babel. Esto permite la transformación de mensajes en tiempo de compilación y la compilación de catálogos sobre la marcha:
// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { lingui } from "@lingui/vite-plugin";
export default defineConfig({
plugins: [
react({
babel: {
plugins: ["@lingui/babel-plugin-lingui-macro"],
},
}),
lingui(),
],
});PO (Portable Object) es el formato de archivo de traducción estándar de la industria, originado en el sistema GNU gettext. Lingui utiliza PO como su formato de catálogo predeterminado porque es ampliamente compatible con herramientas de traducción, plataformas TMS y traductores profesionales de todo el mundo.
#: src/components/WelcomeBanner.js:6
msgid "Welcome to our platform"
msgstr ""
#: src/components/WelcomeBanner.js:8
msgid "Hello {userName}, check out your <0>dashboard</0> to get started."
msgstr ""
#: src/components/CartSummary.js:5
msgid "{itemCount, plural, =0 {Your cart is empty} one {You have # item in your cart} other {You have # items in your cart}}"
msgstr ""Después de la traducción, cada msgstr se completa con la versión localizada. Lingui conserva la sintaxis de ICU MessageFormat, etiquetas indexadas para componentes de React y variables de marcador de posición en todas las traducciones.
#: src/components/WelcomeBanner.js:6
msgid "Welcome to our platform"
msgstr "Bienvenue sur notre plateforme"
#: src/components/WelcomeBanner.js:8
msgid "Hello {userName}, check out your <0>dashboard</0> to get started."
msgstr "Bonjour {userName}, consultez votre <0>tableau de bord</0> pour commencer."
#: src/components/CartSummary.js:5
msgid "{itemCount, plural, =0 {Your cart is empty} one {You have # item in your cart} other {You have # items in your cart}}"
msgstr "{itemCount, plural, =0 {Votre panier est vide} one {Vous avez # article dans votre panier} other {Vous avez # articles dans votre panier}}"Organiza tus catálogos PO dentro de un directorio locales con una subcarpeta por configuración regional. La CLI de Lingui crea y actualiza automáticamente estos archivos durante la extracción. Los módulos JS compilados se generan en tiempo de compilación y no deben editarse manualmente.
src/
├── locales/
│ ├── en/
│ │ └── messages.po ← Source (English)
│ ├── fr/
│ │ └── messages.po ← French
│ ├── de/
│ │ └── messages.po ← German
│ ├── ja/
│ │ └── messages.po ← Japanese
│ ├── es/
│ │ └── messages.po ← Spanish
│ └── zh-CN/
│ └── messages.po ← Chinese Simplified
├── components/
├── i18n.ts
├── App.tsx
└── ...Lingui proporciona dos enfoques principales para marcar mensajes: macros JSX para el contenido de los componentes y el hook useLingui para cadenas imperativas. Ambos son macros de tiempo de compilación que producen una salida optimizada.
Envuelve cualquier contenido JSX en la macro Trans para hacerlo traducible. Las variables, los elementos HTML y los componentes de React son totalmente compatibles; la macro los transforma automáticamente en ICU MessageFormat con etiquetas indexadas.
import { Trans } from "@lingui/react/macro";
function WelcomeBanner({ userName }) {
return (
<div>
<h1>
<Trans>Welcome to our platform</Trans>
</h1>
<p>
<Trans>
Hello {userName}, check out your <a href="/dashboard">dashboard</a> to
get started.
</Trans>
</p>
</div>
);
}Para cadenas fuera de JSX (mensajes de alerta, etiquetas aria, valores de atributos o cualquier código imperativo), usa el hook de macro useLingui con literales de plantilla etiquetados:
import { useLingui } from "@lingui/react/macro";
function NotificationButton() {
const { t } = useLingui();
const showAlert = () => {
alert(t`Your changes have been saved.`);
};
return (
<button onClick={showAlert} aria-label={t`Save changes`}>
<Trans>Save</Trans>
</button>
);
}Lingui admite dos enfoques para la identificación de mensajes: IDs generados automáticamente (derivados del contenido del mensaje de origen) y IDs explícitos (claves definidas por el desarrollador). Ambos enfoques funcionan con archivos PO.
import { Trans } from "@lingui/react/macro";
// Auto-generated ID (from message content)
<Trans>Welcome to our platform</Trans>
// Explicit ID (developer-defined key)
<Trans id="nav.welcome">Welcome to our platform</Trans>Usa la propiedad comment en cualquier macro para añadir una descripción. Este comentario se extrae en el archivo PO como una nota del traductor, proporcionando un contexto crítico sobre dónde y cómo aparece el mensaje.
import { Trans } from "@lingui/react/macro";
<Trans comment="Shown on the homepage hero section above the fold">
Start building with confidence
</Trans>Lingui utiliza ICU MessageFormat para la pluralización, que admite todas las categorías de plurales CLDR. La macro Plural facilita el manejo de diferentes formas plurales directamente en JSX:
import { Plural } from "@lingui/react/macro";
function CartSummary({ itemCount }) {
return (
<p>
<Plural
value={itemCount}
_0="Your cart is empty"
one="You have # item in your cart"
other="You have # items in your cart"
/>
</p>
);
}Después de extraer y compilar tus mensajes, configura la instancia de i18n y envuelve tu aplicación en el I18nProvider.
Crea un módulo i18n que cargue catálogos de mensajes compilados dinámicamente. El plugin de Lingui Vite permite importaciones directas de archivos PO, que se compilan sobre la marcha durante el desarrollo:
// src/i18n.ts
import { i18n } from "@lingui/core";
export async function loadCatalog(locale: string) {
const { messages } = await import(`./locales/${locale}/messages.po`);
i18n.load(locale, messages);
i18n.activate(locale);
}
// Initialize with default locale
loadCatalog("en");
export default i18n;Envuelve toda tu aplicación con I18nProvider para que las traducciones estén disponibles para todos los componentes a través del contexto de React:
// src/App.tsx
import { I18nProvider } from "@lingui/react";
import { i18n } from "./i18n";
function App() {
return (
<I18nProvider i18n={i18n}>
<YourAppContent />
</I18nProvider>
);
}Cambiar de idioma es sencillo: carga el nuevo catálogo, activa la configuración regional y React vuelve a renderizar automáticamente todo el contenido traducido. Aquí tienes un componente de cambio de idioma completo:
import { useState } from "react";
import { loadCatalog } from "./i18n";
import { Trans } from "@lingui/react/macro";
const LANGUAGES = {
en: "English",
fr: "Français",
de: "Deutsch",
ja: "日本語",
es: "Español",
};
function LanguageSwitcher() {
const [currentLocale, setCurrentLocale] = useState("en");
const handleChange = async (locale: string) => {
await loadCatalog(locale);
setCurrentLocale(locale);
};
return (
<select
value={currentLocale}
onChange={(e) => handleChange(e.target.value)}
>
{Object.entries(LANGUAGES).map(([code, name]) => (
<option key={code} value={code}>
{name}
</option>
))}
</select>
);
}La CLI de Lingui proporciona dos comandos clave que forman el núcleo de tu flujo de trabajo de traducción: extract para extraer mensajes del código fuente a catálogos PO, y compile para convertir archivos PO en módulos JavaScript optimizados para producción.
# Extract messages from source code into PO catalogs
npx lingui extract
# Translate your PO files (manually, with a TMS, or with AI)
# Compile PO catalogs into optimized JS modules for production
npx lingui compilel10n.dev proporciona soporte nativo para archivos PO, lo que lo convierte en el compañero perfecto para proyectos de Lingui.js. Sube tu catálogo PO de origen y recibe archivos traducidos con precisión:
Usa el paquete npm ai-l10n para traducir tus catálogos PO de Lingui desde la línea de comandos o como parte de una canalización CI/CD. Instálalo una vez y luego traduce a cualquier número de idiomas con un solo comando.
# Install the CLI
npm install ai-l10n
# Translate your source PO file to multiple languages
npx ai-l10n translate src/locales/en/messages.po \
--languages fr,de,ja,zh-CN,es,koConecta ai-l10n directamente en tu proceso de compilación de Lingui para que las traducciones estén siempre actualizadas. Combina la extracción, la traducción y la compilación en un solo flujo de trabajo.
Añade extract, translate y compile como scripts y encadénalos. El script i18n ejecuta la canalización completa; úsalo en prebuild para asegurar que las traducciones estén siempre actualizadas antes de enviar.
{
"scripts": {
"extract": "lingui extract",
"compile": "lingui compile",
"translate": "ai-l10n translate src/locales/en/messages.po --languages fr,de,ja,zh-CN,es,ko --update",
"i18n": "npm run extract && npm run translate && npm run compile",
"prebuild": "npm run i18n",
"build": "vite build",
"dev": "vite"
}
}Si tu equipo usa Make, declara la extracción, la traducción y la compilación como objetivos separados con las dependencias adecuadas:
LANGUAGES = fr,de,ja,zh-CN,es,ko
extract:
npx lingui extract
translate:
npx ai-l10n translate src/locales/en/messages.po --languages $(LANGUAGES) --update
compile:
npx lingui compile
i18n: extract translate compile
dev: i18n
npx vite
build: i18n
npx vite buildPara obtener información sobre la integración CI/CD, actualizaciones incrementales, traducción por lotes en varios archivos y ejemplos de flujo de trabajo de GitHub Actions, consulta la Guía de automatización de localización.
La extensión de VS Code de l10n.dev lleva la traducción de archivos PO directamente a tu editor. Traduce tus catálogos de Lingui sin salir de VS Code.
¿Listo para llegar a usuarios globales? Traduce tus archivos PO de Lingui directamente en el espacio de trabajo de l10n.dev, automatiza con la CLI de npm o traduce directamente dentro de VS Code:
Descubre por qué la traducción impulsada por IA es mejor para archivos i18n que los métodos tradicionales
Integra la localización impulsada por IA directamente en tu pipeline de CI/CD
Lleva la localización con IA a tu flujo de trabajo con nuestras extensiones y plugins
¡Gracias por usar l10n.dev para localizar tu proyecto Lingui.js! 🚀
Si esta guía te ha ayudado, compártela con otros desarrolladores de React que necesiten internacionalizar sus aplicaciones con archivos PO.
Juntos, podemos hacer que las aplicaciones JavaScript sean más accesibles y estén listas para una audiencia global.