Extracción de claves i18n con IA

Convertir una aplicación React existente para admitir múltiples idiomas es a veces un proceso tedioso de encontrar cadenas de texto codificadas y reemplazarlas con claves de traducción.

Lingo.dev CLI funciona perfectamente con IDEs potenciados por IA como Cursor, GitHub Copilot y herramientas similares para automatizar la extracción de contenido traducible de tus componentes React.

El concepto explicado a continuación puede usarse para cualquier stack tecnológico, pero por simplicidad y para demostrar la idea, usaremos una aplicación React de hello world como ejemplo.

Requisitos previos

Antes de extraer claves, configura la internacionalización básica en tu aplicación React. Para instrucciones completas de configuración, consulta la documentación de react-intl.

Después de seguir la configuración de internacionalización para tu stack tecnológico, tu proyecto debería tener:

  • Capacidad de cambiar entre idiomas dinámicamente en la aplicación
  • Estructura básica del proyecto para organizar archivos de traducción

Proceso de configuración

Instala y configura Lingo.dev CLI:

npx lingo.dev@latest init

Crea un archivo fuente vacío:

mkdir -p src/locales
echo '{}' > src/locales/en.json

Configura i18n.json:

{
  "locale": {
    "source": "en",
    "targets": ["es", "fr", "de"]
  },
  "buckets": {
    "json": {
      "include": ["src/locales/[locale].json"]
    }
  }
}

Extracción de claves con IA

Selecciona tu componente React y usa tu IDE con IA para extraer cadenas de texto codificadas:

Antes de la extracción:

function WelcomeCard() {
  return (
    <div className="card">
      <h2>Welcome to our platform</h2>
      <p>Start your journey with us today</p>
      <button>Get started</button>
    </div>
  );
}

Requisitos para la extracción:

  1. Reemplazar cadenas de texto codificadas con hooks y componentes de react-intl
  2. Usar formato ICU para variables y plurales
  3. Estructurar claves jerárquicamente según la organización de componentes
  4. Agregar todas las claves al archivo JSON fuente
  5. Mantener convenciones de nomenclatura consistentes

Prompt de IA:

Extract all hardcoded strings from React components and:

1. Replace with react-intl:
   - Use useIntl hook for dynamic strings
   - Use FormattedMessage for static text
   - Add ICU formatting for variables ({name}) and plurals ({count})

2. Structure translation keys:
   - Group by component hierarchy (components.*, pages.*)
   - Use descriptive, nested keys (header.nav.home)
   - Match component structure in JSON

3. Update locales:
   - Add all keys to src/locales/en.json
   - Maintain consistent naming across app

Después de la extracción con IA:

import { useIntl } from "react-intl";

function WelcomeCard() {
  const intl = useIntl();

  return (
    <div className="card">
      <h2>{intl.formatMessage({ id: "welcome.title" })}</h2>
      <p>{intl.formatMessage({ id: "welcome.description" })}</p>
      <button>{intl.formatMessage({ id: "welcome.getStarted" })}</button>
    </div>
  );
}

en.json generado:

{
  "welcome.title": "Welcome to our platform",
  "welcome.description": "Start your journey with us today",
  "welcome.getStarted": "Get started"
}

Procesamiento por lotes

Para múltiples componentes, selecciona todos los archivos y utiliza el mismo prompt completo. Los IDEs de IA como Cursor, GitHub Copilot y otros pueden procesar múltiples archivos simultáneamente, manteniendo una nomenclatura de claves consistente en toda tu aplicación.

Generación de traducciones

Una vez que tu IDE de IA extraiga las claves, genera las traducciones:

npx lingo.dev@latest run

Esto crea versiones traducidas de tu archivo fuente:

src/locales/
  en.json    (source with extracted keys)
  es.json    (Spanish translations)
  fr.json    (French translations)
  de.json    (German translations)

Validación

Después de la extracción, verifica tu configuración:

Comprueba la cobertura de traducción:

npx lingo.dev@latest run --frozen

Este comando falla si falta alguna traducción, asegurando una cobertura completa.

Prueba con diferentes locales:

// Switch locale in your app to verify translations work
<IntlProvider locale="es" messages={spanishMessages}>
  <WelcomeCard />
</IntlProvider>