Diccionarios

Cómo usar patrones tradicionales de traducción basados en diccionarios

Los diccionarios ofrecen un enfoque tradicional para organizar traducciones en objetos anidados con pares clave-valor. Aunque los componentes <T> son el enfoque recomendado, los diccionarios pueden ser útiles para migrar desde otras bibliotecas de i18n o cuando prefieras un almacenamiento centralizado de traducciones.

Recomendación: Usa componentes <T> en proyectos nuevos. Los diccionarios se admiten principalmente para la migración y la compatibilidad con flujos de trabajo de traducción existentes.

Traducción con diccionario vs. con componentes

Patrón de diccionario

// dictionary.ts
export default {
  greetings: {
    hello: '¡Hola, mundo!',
    welcome: '¡Bienvenido, {name}!'
  }
};

// Component usage
function MyComponent() {
  const d = useTranslations();
  return <div>{d('greetings.hello')}</div>;
}

Patrón de componentes

// Uso directo del componente - recomendado
function MyComponent() {
  return <T><div>¡Hola, mundo!</div></T>;
}

Compromisos

Ventajas del diccionario

  • Almacenamiento centralizado - Todas las traducciones en un solo lugar
  • Estándar del sector - Patrón familiar de otras bibliotecas de i18n
  • Facilita la migración - Fácil portar traducciones existentes

Desventajas del diccionario

  • Complejidad - Requiere más configuración y pasos de instalación
  • Mantenibilidad - Separar el contenido de su uso dificulta las actualizaciones
  • Facilidad de depuración - Es más difícil rastrear las traducciones hasta los componentes
  • Legibilidad - Las claves no reflejan el contenido real

Guía rápida

Paso 1: Crear el diccionario

Crea un archivo de diccionario en la raíz de tu proyecto o en el directorio src:

dictionary.ts
const dictionary = {
  greetings: {
    hello: '¡Hola, mundo!',
    welcome: '¡Bienvenido a nuestra app!'
  },
  navigation: {
    home: 'Inicio',
    about: 'Acerca de',
    contact: 'Contacto'
  }
};

export default dictionary;

O utiliza el formato JSON:

dictionary.json
{
  "greetings": {
    "hello": "¡Hola, mundo!",
    "welcome": "¡Bienvenido a nuestra app!"
  },
  "navigation": {
    "home": "Inicio", 
    "about": "Acerca de",
    "contact": "Contacto"
  }
}

Luego lo pasas a tu componente <GTProvider>:

index.js
import dictionary from "./dictionary.js";
import config from "./gt.config.json";

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <GTProvider {...config} dictionary={dictionary}>
      <App />
    </GTProvider>
  </StrictMode>
);

Paso 2: Uso en componentes

El hook useTranslations te permite acceder a entradas del diccionario:

import { useTranslations } from 'gt-react';

function MyComponent() {
  const d = useTranslations();
  
  return (
    <div>
      <h1>{d('greetings.hello')}</h1>
      <p>{d('greetings.welcome')}</p>
    </div>
  );
}

Uso de variables

Añade variables a las entradas del diccionario usando la sintaxis {variable}:

dictionary.ts
const dictionary = {
  user: {
    greeting: 'Hola, {name}!',
    itemCount: 'Tienes {count} artículos',
    orderTotal: 'Total: ${amount}'
  }
};
function UserDashboard() {
  const d = useTranslations();
  
  return (
    <div>
      <h1>{d('user.greeting', { name: 'Alice' })}</h1>
      <p>{d('user.itemCount', { count: 5 })}</p>
      <p>{d('user.orderTotal', { amount: 99.99 })}</p>
    </div>
  );
}

Uso de prefijos

Restringe el acceso al diccionario a secciones específicas mediante prefijos:

dictionary.ts
const dictionary = {
  dashboard: {
    header: {
      welcome: '¡Bienvenido de nuevo!',
      lastLogin: 'Último acceso: {date}'
    },
    stats: {
      totalUsers: 'Total de usuarios: {count}',
      activeUsers: 'Usuarios activos: {count}'
    }
  }
};
function DashboardHeader() {
  // El prefijo limita el acceso a 'dashboard.header'
  const d = useTranslations('dashboard.header');
  
  return (
    <header>
      <h1>{d('welcome')}</h1> {/* -> dashboard.header.welcome */}
      <p>{d('lastLogin', { date: 'Today' })}</p> {/* -> dashboard.header.lastLogin */}
    </header>
  );
}

function DashboardStats() {
  // Prefijo diferente para la sección de estadísticas
  const d = useTranslations('dashboard.stats');
  
  return (
    <div>
      <p>{d('totalUsers', { count: 1000 })}</p> {/* -> dashboard.stats.totalUsers */}
      <p>{d('activeUsers', { count: 150 })}</p> {/* -> dashboard.stats.activeUsers */}
    </div>
  );
}

Compatibilidad con varios idiomas

Traducción automática (recomendada)

La mayoría de los usuarios deberían usar loadTranslations para generar automáticamente las traducciones a partir de su diccionario base:

dictionary.ts
const dictionary = {
  common: {
    save: 'Guardar',
    cancel: 'Cancelar',
    delete: 'Eliminar'
  },
  forms: {
    required: 'Este campo es obligatorio',
    email: 'Por favor, introduce un correo electrónico válido'
  }
};

export default dictionary;

Luego, crea una función loadTranslations para cargar los archivos de traducción generados:

src/loadTranslations.ts
export default async function loadTranslations(locale: string) {
  const translations = await import(`./_gt/${locale}.json`);
  return translations.default;
}

Pásalo a tu <GTProvider>:

src/index.tsx
import loadTranslations from './loadTranslations';
import dictionary from './dictionary';

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <GTProvider 
      {...config} 
      dictionary={dictionary}
      loadTranslations={loadTranslations}
    >
      <App />
    </GTProvider>
  </StrictMode>
);

GT genera automáticamente traducciones a otros idiomas a partir de tu diccionario base. Ejecuta npx gtx-cli translate para generar traducciones para todos los idiomas configurados.

Archivos de traducción manual (migración)

Para migrar desde otras bibliotecas de i18n o gestionar traducciones manualmente, usa loadDictionary:

src/loadDictionary.ts
export default async function loadDictionary(locale: string) {
  const translations = await import(`../public/locales/${locale}.json`);
  return translations.default;
}

Esto carga archivos de traducción JSON desde tu directorio public/locales/:

es.json
fr.json
de.json

Elige el enfoque adecuado: Usa loadTranslations para proyectos nuevos con generación automática de traducciones, o loadDictionary al migrar archivos de traducción existentes.

Configuración de producción

Proceso de compilación

Añade la traducción a tu pipeline de compilación:

package.json
{
  "scripts": {
    "build": "npx gtx-cli translate && <...TU_COMANDO_DE_BUILD...>"
  }
}

Comportamiento en desarrollo vs. producción

  • Desarrollo: Entradas del diccionario traducidas bajo demanda con una clave de API de desarrollo
  • Producción: Todas las traducciones del diccionario se generan previamente durante la etapa de build

Combinación con componentes

Dictionaries y componentes <T> pueden funcionar juntos:

function MixedApproach() {
  const d = useTranslations();
  
  return (
    <div>
      {/* Diccionario para strings simples */}
      <h1>{d('page.title')}</h1>
      
      {/* Componente T para JSX complejo */}
      <T>
        <p>Este es un <strong>mensaje complejo</strong> con <a href="/link">enlaces</a>.</p>
      </T>
      
      {/* Diccionario para etiquetas de formulario */}
      <label>{d('forms.email')}</label>
    </div>
  );
}

Próximos pasos

¿Qué te ha parecido esta guía?

Diccionarios