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 desarrollo limpia y genera paquetes optimizados de menos de 2 kB. Esta guía cubre todo, desde la configuración del proyecto hasta los flujos de trabajo de archivos PO, pluralización y la automatización de traducciones con l10n.dev.
Lingui.js destaca entre las librerías i18n de JavaScript por su combinación de experiencia de desarrollo, rendimiento y flujos de trabajo de traducción profesional:
Instale 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 de los catálogos) y la configuración de su herramienta de construcción (para habilitar las macros en tiempo de compilación).
Cree un archivo lingui.config.js en la raíz de su proyecto. Esto define su 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 utiliza Vite, añada 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, derivado del 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 en 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 preserva la sintaxis de ICU MessageFormat, las etiquetas indexadas para componentes de React y las 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}}"Organice sus catálogos PO dentro de un directorio de 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 ofrece dos enfoques principales para marcar mensajes: macros JSX para contenido de componentes y el hook useLingui para cadenas imperativas. Ambos son macros en tiempo de compilación que producen una salida optimizada.
Envuelva cualquier contenido JSX en la macro Trans para hacerlo traducible. Las variables, elementos HTML y 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), utilice el hook de macro useLingui con plantillas de cadena etiquetadas:
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>Utilice la propiedad comment en cualquier macro para añadir una descripción. Este comentario se extrae en el archivo PO como una nota para el 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 plural del 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 sus mensajes, configure la instancia de i18n y envuelva su aplicación en el I18nProvider.
Cree un módulo i18n que cargue catálogos de mensajes compilados dinámicamente. El plugin de Lingui para 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;Envuelva toda su 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: cargue el nuevo catálogo, active la configuración regional y React volverá a renderizar automáticamente todo el contenido traducido. Aquí tiene 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 su 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. Suba su catálogo PO de origen y reciba archivos traducidos con precisión:
Utilice el paquete npm ai-l10n para traducir sus catálogos PO de Lingui desde la línea de comandos o como parte de una tubería CI/CD. Instale una vez y traduzca 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,koConecte ai-l10n directamente en su proceso de construcción de Lingui para que las traducciones estén siempre actualizadas. Combine la extracción, traducción y compilación en un solo flujo de trabajo.
Añada extract, translate y compile como scripts y enlácelos. El script i18n ejecuta toda la tubería; úselo en prebuild para asegurarse de que las traducciones estén siempre actualizadas antes de publicar.
{
"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 su equipo utiliza Make, declare la extracción, traducción y 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 la integración CI/CD, actualizaciones incrementales, traducción por lotes en múltiples archivos y ejemplos de flujo de trabajo de GitHub Actions, consulte 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 su editor. Traduzca sus catálogos de Lingui sin salir de VS Code.
¿Listo para llegar a usuarios globales? Traduzca sus archivos PO de Lingui directamente en el espacio de trabajo de l10n.dev, automatice con la CLI de npm o traduzca directamente dentro de VS Code:
Descubre por qué la traducción potenciada por IA es mejor para archivos de i18n que los métodos tradicionales.
Integra la localización potenciada por IA directamente en tu pipeline de CI/CD.
Incorpora la localización de IA en tu flujo de trabajo con nuestras extensiones y complementos.
¡Gracias por usar l10n.dev para localizar su proyecto Lingui.js! 🚀
Si esta guía le ayudó, compártala 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.