Guía de migración
Migra del antiguo compilador (lingo.dev/compiler) al nuevo @lingo.dev/compiler.
¿Por qué migrar?
El nuevo compilador ofrece:
- Mejor DX — Automático por defecto (no requiere
'use i18n') - Mejor rendimiento — Compilaciones más rápidas, mejor HMR
- Modos de compilación — Separación de preocupaciones dev/CI/prod
- Anulaciones manuales — Atributo
data-lingo-override - Resolvedores de locale personalizados — Detección de locale flexible
- Herramientas de desarrollo — Pseudotraductor, widget de desarrollo (próximamente)
- Arquitectura más limpia — Mejor separación de responsabilidades
Cambios incompatibles
1. Nombre del paquete
Antiguo:
npm install lingo.dev
Nuevo:
npm install @lingo.dev/compiler
2. Rutas de importación
Antiguo:
import lingoCompiler from "lingo.dev/compiler";
import { LingoProvider } from "lingo.dev/react/rsc";
Nuevo:
import { withLingo } from "@lingo.dev/compiler/next";
import { LingoProvider } from "@lingo.dev/compiler/react";
3. API de configuración
Next.js
Antiguo:
// next.config.js
import lingoCompiler from "lingo.dev/compiler";
export default lingoCompiler.next({
sourceLocale: "en",
targetLocales: ["es", "de"],
models: "lingo.dev",
})(nextConfig);
Nuevo:
// next.config.ts
import { withLingo } from "@lingo.dev/compiler/next";
export default async function (): Promise<NextConfig> {
return await withLingo(nextConfig, {
sourceRoot: "./app", // New: specify source directory
sourceLocale: "en",
targetLocales: ["es", "de"],
models: "lingo.dev",
});
}
Cambios:
- La configuración debe ser una función asíncrona
- Nueva opción
sourceRoot - Wrapper
withLingoen lugar delingoCompiler.next
Vite
Antiguo:
import lingoCompiler from "lingo.dev/compiler";
export default defineConfig(() =>
lingoCompiler.vite({
sourceRoot: "src",
targetLocales: ["es", "de"],
models: "lingo.dev",
})(viteConfig)
);
Nuevo:
import { lingoCompilerPlugin } from "@lingo.dev/compiler/vite";
export default defineConfig({
plugins: [
lingoCompilerPlugin({
sourceRoot: "src",
sourceLocale: "en", // New: required
targetLocales: ["es", "de"],
models: "lingo.dev",
}),
react(),
],
});
Cambios:
- Basado en plugins en lugar de wrapper de configuración
sourceLocaleahora es obligatorio- Colocar antes del plugin
react()
4. Configuración del proveedor
Antiguo:
import { LingoProvider, loadDictionary } from "lingo.dev/react/rsc";
export default function Layout({ children }) {
return (
<LingoProvider loadDictionary={(locale) => loadDictionary(locale)}>
{children}
</LingoProvider>
);
}
Nuevo:
import { LingoProvider } from "@lingo.dev/compiler/react";
export default function Layout({ children }) {
return (
<LingoProvider>
{children}
</LingoProvider>
);
}
Cambios:
- Sin prop
loadDictionary—se gestiona internamente - API más simple
5. Estructura de archivos
Antiguo:
lingo/
├── dictionary.js
├── meta.json
└── [locale]/
└── *.json
Nuevo:
.lingo/
└── metadata.json
Cambios:
- Directorio renombrado (
.lingovslingo) - Un único archivo de metadatos en lugar de múltiples archivos
- Estructura JSON diferente
6. Directiva "use i18n"
Antiguo: Obligatoria por defecto. Añadir a cada archivo que quieras traducir:
'use i18n';
export function Component() { ... }
Nuevo: Opcional. Por defecto, todos los archivos se traducen automáticamente. Para activar el modo opt-in:
{
useDirective: true, // Enable opt-in behavior
}
Luego añadir la directiva:
'use i18n';
export function Component() { ... }
Pasos de migración
Paso 1: Actualizar el paquete
# Uninstall old package
npm uninstall lingo.dev
# Install new package
npm install @lingo.dev/compiler
Paso 2: actualizar configuración
Next.js
Antes:
// next.config.js
import lingoCompiler from "lingo.dev/compiler";
export default lingoCompiler.next({
sourceLocale: "en",
targetLocales: ["es", "de"],
models: "lingo.dev",
})(nextConfig);
Después:
// next.config.ts
import type { NextConfig } from "next";
import { withLingo } from "@lingo.dev/compiler/next";
const nextConfig: NextConfig = {};
export default async function (): Promise<NextConfig> {
return await withLingo(nextConfig, {
sourceRoot: "./app",
sourceLocale: "en",
targetLocales: ["es", "de"],
models: "lingo.dev",
dev: {
usePseudotranslator: true, // Recommended for development
},
});
}
Vite
Antes:
import lingoCompiler from "lingo.dev/compiler";
export default defineConfig(() =>
lingoCompiler.vite({
sourceRoot: "src",
targetLocales: ["es", "de"],
models: "lingo.dev",
})(viteConfig)
);
Después:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { lingoCompilerPlugin } from "@lingo.dev/compiler/vite";
export default defineConfig({
plugins: [
lingoCompilerPlugin({
sourceRoot: "src",
sourceLocale: "en",
targetLocales: ["es", "de"],
models: "lingo.dev",
dev: {
usePseudotranslator: true,
},
}),
react(),
],
});
Paso 3: actualizar proveedor
Antes:
import { LingoProvider, loadDictionary } from "lingo.dev/react/rsc";
export default function Layout({ children }) {
return (
<LingoProvider loadDictionary={(locale) => loadDictionary(locale)}>
{children}
</LingoProvider>
);
}
Después:
import { LingoProvider } from "@lingo.dev/compiler/react";
export default function Layout({ children }) {
return (
<LingoProvider>
{children}
</LingoProvider>
);
}
Paso 4: limpiar archivos antiguos
# Backup old translations (optional)
mv lingo lingo.backup
# Remove old directory
rm -rf lingo
# New directory will be created automatically
# on first build
Paso 5: probar con Pseudotranslator
npm run dev
Con usePseudotranslator: true, verás traducciones falsas instantáneas. Verifica:
- Todo el texto esperado está traducido
- No hay errores de compilación
- El diseño maneja longitudes de texto variables
Paso 6: generar traducciones reales
Actualiza la configuración para desactivar el pseudotranslator:
{
dev: {
usePseudotranslator: false,
}
}
Reinicia el servidor de desarrollo. El compilador generará traducciones reales para cualquier texto nuevo o modificado.
Paso 7: Confirmar nuevas traducciones
git add .lingo/
git commit -m "chore: migrate to @lingo.dev/compiler"
git push
Mapeo de funcionalidades
Funcionalidades antiguas → Nuevos equivalentes
| Función antigua | Equivalente nuevo | Notas |
|---|---|---|
dictionary.js | .lingo/metadata.json | Formato diferente |
meta.json | .lingo/metadata.json | Fusionado en un solo archivo |
| "use i18n" (obligatorio) | "use i18n" (opcional) | Ahora es opcional, no obligatorio |
| Prompts personalizados | Opción de configuración prompt | Misma funcionalidad |
| Editar traducciones | data-lingo-override | Sobrescrituras basadas en atributos |
| Omitir traducciones | data-lingo-override + vacío | O usar useDirective |
| Sobrescribir traducciones | data-lingo-override | Basado en atributos |
| Cambiar idiomas | useLingoContext() | Devuelve { locale, setLocale } |
| Proveedores LLM | Configuración models | Mismos proveedores compatibles |
Nuevas funcionalidades (no disponibles en el compilador antiguo)
- Modos de compilación —
translatevscache-only - Pseudotraductor — Traducciones falsas instantáneas
- Widget de desarrollo — Edición en el navegador (próximamente)
- Resolvedores de locale personalizados — Detección flexible de locale
- Pluralización automática — Soporte para ICU MessageFormat
- Servidor de traducción — Traducciones bajo demanda en desarrollo
Traducir traducciones existentes
El nuevo compilador utiliza un formato de archivo diferente. Las traducciones existentes no se migran automáticamente.
Opciones:
Opción 1: Regenerar todas las traducciones
Permitir que el compilador genere traducciones nuevas:
- Eliminar el directorio antiguo
lingo/ - Ejecutar el nuevo compilador
- Generar traducciones usando IA
Ventajas: Comienzo limpio, modelos de IA más recientes Desventajas: Costos de API, posible pérdida de matices
Opción 2: Script de migración manual
Crear un script para convertir el formato antiguo al nuevo:
// migrate-translations.ts
import * as fs from "fs";
const oldDir = "./lingo";
const newFile = "./.lingo/metadata.json";
// Read old translations
const oldTranslations = {}; // Parse old files
// Convert to new format
const newMetadata = {
version: "1",
sourceLocale: "en",
targetLocales: ["es", "de"],
translations: {}, // Convert old translations
};
// Write new metadata
fs.writeFileSync(newFile, JSON.stringify(newMetadata, null, 2));
Esto requiere trabajo manual y es específico del formato.
Opción 3: Enfoque híbrido
- Generar nuevas traducciones para la mayoría del texto
- Usar
data-lingo-overridepara traducciones críticas que necesiten redacción exacta
Problemas comunes
"Cannot find module '@lingo.dev/compiler'"
Ejecutar npm install @lingo.dev/compiler
"Config must be async function" (Next.js)
Envolver tu configuración en async function:
export default async function () {
return await withLingo(...);
}
"sourceLocale is required"
Añadir sourceLocale: "en" a tu configuración.
Las traducciones no se muestran Verificar:
LingoProviderestá en el layout raíz.lingo/metadata.jsonexiste- No hay errores en la consola
Preguntas frecuentes
¿Puedo ejecutar ambos compiladores simultáneamente? No. Desinstalar el compilador antiguo antes de instalar el nuevo.
¿Pierdo mis traducciones? No si las migras manualmente. De lo contrario, regenerar usando IA (cuesta créditos de API).
¿Qué pasa si mi framework aún no es compatible? El nuevo compilador actualmente soporta Next.js y Vite. Otros frameworks próximamente. Continuar usando el compilador antiguo o contribuir con soporte para tu framework.
¿Cuánto tiempo tarda la migración?
- Proyecto simple: 15-30 minutos
- Proyecto complejo: 1-2 horas
- La mayor parte del tiempo es probar y verificar las traducciones
¿Debo migrar ahora o esperar? Migrar cuando:
- Necesites nuevas funcionalidades (modos de compilación, sobrescrituras, resolvers personalizados)
- Estés iniciando un nuevo proyecto
- Quieras mejor experiencia de desarrollo
Esperar si:
- Tu proyecto funciona bien con el compilador antiguo
- Necesitas frameworks aún no soportados por el nuevo compilador
Próximos pasos
- Inicio rápido — Configurar el nuevo compilador
- Referencia de configuración — Explorar todas las opciones
- Mejores prácticas — Flujos de trabajo recomendados
- Solución de problemas — Problemas comunes