Centro de Ayuda

Localización con Lingui.js: archivos PO, i18n en React y automatización

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.

¿Por qué Lingui.js para i18n?

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:

  • Limpio y legible: Escriba traducciones de forma natural usando macros JSX; la librería los compila a ICU MessageFormat internamente.
  • Universal: @lingui/core funciona en cualquier proyecto JavaScript, mientras que @lingui/react añade componentes específicos de React, incluyendo soporte para React Server Components (RSC).
  • Soporte completo de texto enriquecido: Utilice componentes de React dentro de mensajes traducibles sin problemas: enlaces, texto en negrita, iconos y cualquier JSX son totalmente compatibles.
  • Formato de archivo PO: Utiliza el formato PO estándar de la industria, compatible con prácticamente todas las herramientas de traducción, TMS y flujos de trabajo de traductores profesionales.
  • Ligero y optimizado: La librería principal pesa menos de 2 kB comprimida con gzip, los componentes de React añaden solo 1,3 kB. Los datos no esenciales se eliminan en tiempo de compilación.
  • Listo para traducciones con IA: Las descripciones de mensajes y los comentarios de contexto de Lingui proporcionan a los traductores de IA la información necesaria para producir traducciones precisas y conscientes del contexto.

Instalación

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-macro

Configuración

Lingui 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).

Configuración de Lingui

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 }),
});

Configuración de Vite

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(),
  ],
});

El formato de archivo PO

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.

  • Legible: Incluso los archivos de traducción grandes siguen siendo legibles para humanos con pares msgid/msgstr claros.
  • Comentarios del traductor: Admite comentarios #. que llevan descripciones de contexto directamente a los traductores.
  • Referencias de origen: Cada mensaje incluye comentarios #: archivo:línea que muestran exactamente dónde se utiliza en su código fuente.
  • Soporte de contexto: Utilice msgctxt para desambiguar cadenas idénticas que tienen significados diferentes en contextos distintos.
  • Soporte universal de herramientas: Compatible con prácticamente todos los sistemas de gestión de traducción (TMS), herramientas CAT y plataformas de localización.

Archivo PO extraído (mensajes de origen)

#: 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 ""

Archivo PO traducido (francés)

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}}"

Estructura del proyecto

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
└── ...

Traducción de componentes de React

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.

La macro Trans

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>
  );
}

El hook useLingui

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>
  );
}

IDs de mensaje y descripciones

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>

Añadir contexto para traductores e IA

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>
Las descripciones de los mensajes son especialmente valiosas para la traducción impulsada por IA. Proporcionan el contexto que la IA necesita para desambiguar cadenas de interfaz de usuario cortas, convirtiendo traducciones genéricas en precisas y conscientes del contexto.

Pluralización

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:

  • Utilice el componente Plural con valor, one, other y formas exactas opcionales (_0, _2, etc.).
  • El marcador de posición # se reemplaza automáticamente por el valor plural.
  • l10n.dev genera todas las formas plurales requeridas para cada idioma de destino (incluyendo idiomas complejos como el árabe (6 formas), ruso y polaco) sin intervención manual.
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>
  );
}

Inicialización en tiempo de ejecución

Después de extraer y compilar sus mensajes, configure la instancia de i18n y envuelva su aplicación en el I18nProvider.

Configuración del módulo i18n

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;

Configuración de I18nProvider

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>
  );
}

Cambio de idioma en tiempo de ejecución

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>
  );
}

Flujo de trabajo de extracción y compilación

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 compile
  1. Extraer: Escanea sus archivos fuente y crea o actualiza catálogos PO con todos los mensajes traducibles.
  2. Traducir: Rellene los campos msgstr en sus archivos PO, ya sea manualmente, con un TMS o automáticamente con traducción impulsada por IA.
  3. Compilar: Convierte catálogos PO en módulos JS ligeros que se cargan en tiempo de ejecución. Solo se incluyen los mensajes traducidos.

Soporte completo de PO en l10n.dev

l10n.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:

  • Formato PO nativo: Suba archivos PO directamente: l10n.dev lee las entradas msgid, las traduce y devuelve archivos PO correctamente formateados con los valores msgstr correctos.
  • Conocimiento de ICU MessageFormat: Los marcadores de posición ({name}), etiquetas indexadas (<0>), formas plurales y expresiones select se conservan correctamente en todas las traducciones.
  • Traducción por IA consciente del contexto: Los comentarios del traductor (#.) y el contexto del mensaje (msgctxt) son utilizados por nuestra IA para producir traducciones más precisas y conscientes del contexto.
  • Generación de plurales: Se generan todas las formas plurales CLDR requeridas para cada idioma de destino. Los idiomas con reglas plurales complejas (árabe, ruso, polaco) se manejan automáticamente.
  • Actualizaciones por lotes e incrementales: Traduzca catálogos completos a la vez o utilice la bandera --update para traducir solo mensajes nuevos y modificados, preservando las traducciones existentes.

Automatice traducciones con npm

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,ko

Integración en su proceso de construcción

Conecte 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.

Vía scripts en package.json

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"
  }
}

Vía Makefile

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 build

Para 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.

Extensión de VS Code

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.

Cómo funciona en VS Code:

  1. Abra su archivo PO de origen (p. ej., src/locales/en/messages.po) en el editor.
  2. Haga clic derecho en el editor y seleccione "Translate..." (también funciona con archivos PO).
  3. Elija uno o más idiomas de destino (p. ej., francés, japonés, alemán).
  4. La extensión crea archivos PO traducidos en las carpetas locales correspondientes, listos para compilar.

Empiece a localizar su aplicación React con Lingui

¿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: