Estructura del proyecto

Comprender el directorio .lingo/ y su contenido.

Descripción general del directorio

Cuando ejecutas el compilador por primera vez, crea un directorio .lingo/ en la raíz de tu proyecto:

your-project/
├── .lingo/
│   ├── metadata.json
│   ├── locale-resolver.server.ts (optional)
│   └── locale-resolver.client.ts (optional)
├── src/
├── package.json
└── ...

metadata.json

El archivo principal que contiene todos los datos de traducción.

Estructura

{
  "version": "1",
  "sourceLocale": "en",
  "targetLocales": ["es", "de", "fr"],
  "translations": {
    "abc123def456": {
      "source": "Welcome to our app",
      "context": {
        "file": "app/page.tsx",
        "line": 12,
        "component": "HomePage"
      },
      "locales": {
        "es": "Bienvenido a nuestra aplicación",
        "de": "Willkommen in unserer App",
        "fr": "Bienvenue dans notre application"
      },
      "metadata": {
        "createdAt": "2024-01-15T10:30:00Z",
        "updatedAt": "2024-01-15T10:30:00Z"
      }
    }
  }
}

Campos clave

Version: Versión del formato de metadatos. Actual: "1"

Source/Target Locales: Tus locales configurados

Translations: Mapeo basado en hash de todas las cadenas traducibles:

  • Hash (abc123def456): Identificador estable basado en el texto fuente + contexto
  • source: Texto original en inglés
  • context: Dónde aparece este texto (archivo, línea, componente)
  • locales: Traducciones para cada locale de destino
  • metadata: Cuándo se creó/actualizó la traducción

Generación de hash

Los hashes son deterministas:

  • Basados en el texto fuente + contexto del componente
  • El mismo texto en diferentes ubicaciones = hashes diferentes
  • Permite traducciones conscientes del contexto

Ejemplo:

// app/home/page.tsx
<button>Submit</button> // Hash: abc123

// app/checkout/page.tsx
<button>Submit</button> // Hash: def456 (different context)

Resolvers de locale personalizados

Archivos opcionales para personalizar la detección y persistencia de locales.

locale-resolver.server.ts

Detección de locale del lado del servidor (solo Next.js):

// .lingo/locale-resolver.server.ts
export async function getServerLocale(): Promise<string> {
  // Your custom logic
  return "en";
}

locale-resolver.client.ts

Detección y persistencia de locale del lado del cliente:

// .lingo/locale-resolver.client.ts
export function getClientLocale(): string {
  // Detect locale
  return "en";
}

export function persistLocale(locale: string): void {
  // Save locale preference
}

Si estos archivos no existen, el compilador utiliza el comportamiento predeterminado basado en cookies.

Consulta Resolvedores de locale personalizados para más detalles.

Control de versiones

¿Deberías hacer commit de .lingo/?

Sí. El directorio .lingo/ debe estar bajo control de versiones:

Hacer commit:

  • metadata.json — Contiene todas las traducciones
  • Resolvedores de locale personalizados (si se crearon)

No hacer commit:

  • Nada—todos los archivos en .lingo/ deben incluirse en el commit

¿Por qué hacer commit de las traducciones?

  1. Control de versiones — Rastrea los cambios en las traducciones junto con el código
  2. Colaboración en equipo — Comparte traducciones entre el equipo
  3. CI/CD — Las compilaciones de producción utilizan las traducciones confirmadas
  4. Registro de auditoría — Consulta cuándo cambiaron las traducciones y por qué

Integración con Git

Añade .lingo/ a tu repositorio:

git add .lingo/
git commit -m "chore: update translations"
git push

El compilador actualiza automáticamente .lingo/metadata.json cuando:

  • Se añade nuevo texto traducible
  • Se modifica texto existente
  • Se generan traducciones

Haz commit de estas actualizaciones regularmente.

Tamaño del archivo

metadata.json crece con tu aplicación:

  • Aplicación pequeña (50 cadenas): ~10 KB
  • Aplicación mediana (500 cadenas): ~100 KB
  • Aplicación grande (5000 cadenas): ~1 MB

Esto es normal y aceptable para el control de versiones.

Limpieza

Eliminar traducciones no utilizadas

Con el tiempo, puedes acumular traducciones no utilizadas (de componentes eliminados).

Limpieza manual:

  1. Busca el hash en tu código base
  2. Si no se encuentra, elimínalo de metadata.json

Limpieza automatizada (próximamente):

npx @lingo.dev/compiler clean

Esto eliminará las traducciones no utilizadas automáticamente.

Restablecer traducciones

Para regenerar todas las traducciones desde cero:

# Backup current translations
cp .lingo/metadata.json .lingo/metadata.backup.json

# Delete metadata
rm .lingo/metadata.json

# Regenerate
npm run dev # or npm run build

Migración

Desde el compilador antiguo

El compilador antiguo utilizaba una estructura de archivos diferente:

Antiguo:

lingo/
├── dictionary.js
├── meta.json
└── [locale]/
    └── *.json

Nuevo:

.lingo/
└── metadata.json

La migración no está automatizada. Consulta la guía de migración para más detalles.

Inspeccionar traducciones

Ver en el editor

Abre .lingo/metadata.json en tu editor:

{
  "translations": {
    "abc123": {
      "source": "Welcome",
      "locales": {
        "es": "Bienvenido"
      }
    }
  }
}

Buscar traducción

Encuentra una traducción por el texto de origen:

grep -r "Welcome" .lingo/metadata.json

Buscar por hash

grep -r "abc123" .lingo/metadata.json

Formato legible

cat .lingo/metadata.json | jq '.'

Preguntas frecuentes

¿Puedo editar metadata.json manualmente? Sí, pero no se recomienda. Usa data-lingo-override en su lugar: es más seguro y está controlado por versiones en el código fuente.

¿Qué pasa si elimino metadata.json? El compilador lo regenera en la siguiente compilación. Todas las traducciones se generarán de nuevo (consume créditos de API).

¿Puedo mover .lingo/ a un directorio diferente? Sí. Configúralo mediante la opción lingoDir:

{
  lingoDir: "translations"
}

¿metadata.json contiene datos sensibles? No. Solo contiene texto fuente y traducciones, sin claves de API ni secretos.

¿Puedo fusionar metadata.json de múltiples ramas? Sí. Git gestiona las fusiones automáticamente. Los conflictos son raros (los hashes son únicos).

¿Qué pasa si dos ramas añaden la misma traducción? Git las fusiona automáticamente. Si los hashes difieren (contexto diferente), se conservan ambas.

Próximos pasos