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?
- Control de versiones — Rastrea los cambios en las traducciones junto con el código
- Colaboración en equipo — Comparte traducciones entre el equipo
- CI/CD — Las compilaciones de producción utilizan las traducciones confirmadas
- 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:
- Busca el hash en tu código base
- 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
- Resolvedores de configuración regional personalizados — Personaliza la persistencia
- Herramientas de desarrollo — Trabaja con el pseudotraductor
- Modos de compilación — Comprende el comportamiento del caché