Migrationsleitfaden

Migrieren Sie vom alten Compiler (lingo.dev/compiler) zum neuen @lingo.dev/compiler.

Warum migrieren?

Der neue Compiler bietet:

  • Bessere DX — Standardmäßig automatisch (kein 'use i18n' erforderlich)
  • Bessere Performance — Schnellere Builds, besseres HMR
  • Build-Modi — Separate Dev/CI/Prod-Bereiche
  • Manuelle Überschreibungendata-lingo-override-Attribut
  • Benutzerdefinierte Locale-Resolver — Flexible Locale-Erkennung
  • Entwicklungstools — Pseudotranslator, Dev-Widget (demnächst verfügbar)
  • Sauberere Architektur — Bessere Trennung der Zuständigkeiten

Breaking Changes

1. Paketname

Alt:

npm install lingo.dev

Neu:

npm install @lingo.dev/compiler

2. Import-Pfade

Alt:

import lingoCompiler from "lingo.dev/compiler";
import { LingoProvider } from "lingo.dev/react/rsc";

Neu:

import { withLingo } from "@lingo.dev/compiler/next";
import { LingoProvider } from "@lingo.dev/compiler/react";

3. Konfigurations-API

Next.js

Alt:

// next.config.js
import lingoCompiler from "lingo.dev/compiler";

export default lingoCompiler.next({
  sourceLocale: "en",
  targetLocales: ["es", "de"],
  models: "lingo.dev",
})(nextConfig);

Neu:

// 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",
  });
}

Änderungen:

  • Konfiguration muss asynchrone Funktion sein
  • Neue sourceRoot-Option
  • withLingo-Wrapper anstelle von lingoCompiler.next

Vite

Alt:

import lingoCompiler from "lingo.dev/compiler";

export default defineConfig(() =>
  lingoCompiler.vite({
    sourceRoot: "src",
    targetLocales: ["es", "de"],
    models: "lingo.dev",
  })(viteConfig)
);

Neu:

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(),
  ],
});

Änderungen:

  • Plugin-basiert statt Config-Wrapper
  • sourceLocale ist jetzt erforderlich
  • Vor dem react()-Plugin platzieren

4. Provider-Setup

Alt:

import { LingoProvider, loadDictionary } from "lingo.dev/react/rsc";

export default function Layout({ children }) {
  return (
    <LingoProvider loadDictionary={(locale) => loadDictionary(locale)}>
      {children}
    </LingoProvider>
  );
}

Neu:

import { LingoProvider } from "@lingo.dev/compiler/react";

export default function Layout({ children }) {
  return (
    <LingoProvider>
      {children}
    </LingoProvider>
  );
}

Änderungen:

  • Kein loadDictionary-Prop – wird intern verarbeitet
  • Einfachere API

5. Dateistruktur

Alt:

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

Neu:

.lingo/
└── metadata.json

Änderungen:

  • Verzeichnis umbenannt (.lingo vs. lingo)
  • Einzelne Metadaten-Datei statt mehrerer Dateien
  • Andere JSON-Struktur

6. "use i18n"-Direktive

Alt: Standardmäßig erforderlich. Zu jeder Datei hinzufügen, die übersetzt werden soll:

'use i18n';

export function Component() { ... }

Neu: Optional. Standardmäßig werden alle Dateien automatisch übersetzt. Für Opt-in:

{
  useDirective: true, // Enable opt-in behavior
}

Dann Direktive hinzufügen:

'use i18n';

export function Component() { ... }

Migrationsschritte

Schritt 1: Paket aktualisieren

# Uninstall old package
npm uninstall lingo.dev

# Install new package
npm install @lingo.dev/compiler

Schritt 2: Konfiguration aktualisieren

Next.js

Vorher:

// next.config.js
import lingoCompiler from "lingo.dev/compiler";

export default lingoCompiler.next({
  sourceLocale: "en",
  targetLocales: ["es", "de"],
  models: "lingo.dev",
})(nextConfig);

Nachher:

// 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

Vorher:

import lingoCompiler from "lingo.dev/compiler";

export default defineConfig(() =>
  lingoCompiler.vite({
    sourceRoot: "src",
    targetLocales: ["es", "de"],
    models: "lingo.dev",
  })(viteConfig)
);

Nachher:

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(),
  ],
});

Schritt 3: Provider aktualisieren

Vorher:

import { LingoProvider, loadDictionary } from "lingo.dev/react/rsc";

export default function Layout({ children }) {
  return (
    <LingoProvider loadDictionary={(locale) => loadDictionary(locale)}>
      {children}
    </LingoProvider>
  );
}

Nachher:

import { LingoProvider } from "@lingo.dev/compiler/react";

export default function Layout({ children }) {
  return (
    <LingoProvider>
      {children}
    </LingoProvider>
  );
}

Schritt 4: Alte Dateien bereinigen

# Backup old translations (optional)
mv lingo lingo.backup

# Remove old directory
rm -rf lingo

# New directory will be created automatically
# on first build

Schritt 5: Mit Pseudotranslator testen

npm run dev

Mit usePseudotranslator: true werden sofort Pseudo-Übersetzungen angezeigt. Überprüfen Sie:

  • Alle erwarteten Texte sind übersetzt
  • Keine Kompilierungsfehler
  • Layout verarbeitet unterschiedliche Textlängen

Schritt 6: Echte Übersetzungen generieren

Konfiguration aktualisieren, um Pseudotranslator zu deaktivieren:

{
  dev: {
    usePseudotranslator: false,
  }
}

Dev-Server neu starten. Der Compiler generiert echte Übersetzungen für alle neuen oder geänderten Texte.

Schritt 7: Neue Übersetzungen committen

git add .lingo/
git commit -m "chore: migrate to @lingo.dev/compiler"
git push

Feature-Mapping

Alte Features → Neue Entsprechungen

Alte FunktionNeues ÄquivalentHinweise
dictionary.js.lingo/metadata.jsonAnderes Format
meta.json.lingo/metadata.jsonIn einzelne Datei zusammengeführt
"use i18n" (erforderlich)"use i18n" (optional)Jetzt opt-in, nicht erforderlich
Benutzerdefinierte Promptsprompt KonfigurationsoptionGleiche Funktionalität
Übersetzungen bearbeitendata-lingo-overrideAttributbasierte Überschreibungen
Übersetzungen überspringendata-lingo-override + leerOder useDirective verwenden
Übersetzungen überschreibendata-lingo-overrideAttributbasiert
Locales wechselnuseLingoContext()Gibt { locale, setLocale } zurück
LLM-Anbietermodels KonfigurationGleiche Anbieter unterstützt

Neue Features (nicht im alten Compiler)

  • Build-Moditranslate vs. cache-only
  • Pseudotranslator — Sofortige Fake-Übersetzungen
  • Development-Widget — In-Browser-Bearbeitung (demnächst verfügbar)
  • Custom Locale Resolver — Flexible Locale-Erkennung
  • Automatische Pluralisierung — ICU MessageFormat-Unterstützung
  • Translation-Server — On-Demand-Übersetzungen in der Entwicklung

Bestehende Übersetzungen übersetzen

Der neue Compiler verwendet ein anderes Dateiformat. Bestehende Übersetzungen werden nicht automatisch migriert.

Optionen:

Option 1: Alle Übersetzungen neu generieren

Lassen Sie den Compiler neue Übersetzungen generieren:

  1. Altes lingo/ Verzeichnis löschen
  2. Neuen Compiler ausführen
  3. Übersetzungen mit AI generieren

Vorteile: Sauberer Neustart, neueste AI-Modelle Nachteile: API-Kosten, Nuancen können verloren gehen

Option 2: Manuelles Migrationsskript

Erstellen Sie ein Skript zur Konvertierung vom alten ins neue Format:

// 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));

Dies ist manuelle Arbeit und formatspezifisch.

Option 3: Hybrider Ansatz

  1. Generieren Sie neue Übersetzungen für den Großteil des Textes
  2. Verwenden Sie data-lingo-override für kritische Übersetzungen, die exakte Formulierungen benötigen

Häufige Probleme

"Cannot find module '@lingo.dev/compiler'" Führen Sie npm install @lingo.dev/compiler aus

"Config must be async function" (Next.js) Umschließen Sie Ihre Konfiguration mit async function:

export default async function () {
  return await withLingo(...);
}

"sourceLocale is required" Fügen Sie sourceLocale: "en" zu Ihrer Konfiguration hinzu.

Übersetzungen werden nicht angezeigt Überprüfen Sie:

  1. LingoProvider befindet sich im Root-Layout
  2. .lingo/metadata.json existiert
  3. Keine Konsolenfehler vorhanden

FAQ

Kann ich beide Compiler gleichzeitig ausführen? Nein. Deinstallieren Sie den alten Compiler, bevor Sie den neuen installieren.

Verliere ich meine Übersetzungen? Nicht, wenn Sie sie manuell migrieren. Andernfalls regenerieren Sie sie mit KI (verursacht API-Kosten).

Was ist, wenn mein Framework noch nicht unterstützt wird? Der neue Compiler unterstützt derzeit Next.js und Vite. Weitere Frameworks folgen in Kürze. Verwenden Sie weiterhin den alten Compiler oder tragen Sie zur Unterstützung Ihres Frameworks bei.

Wie lange dauert die Migration?

  • Einfaches Projekt: 15-30 Minuten
  • Komplexes Projekt: 1-2 Stunden
  • Die meiste Zeit wird für Tests und Überprüfung der Übersetzungen benötigt

Sollte ich jetzt migrieren oder warten? Migrieren Sie, wenn:

  • Sie neue Features benötigen (Build-Modi, Overrides, Custom Resolver)
  • Sie ein neues Projekt starten
  • Sie eine bessere Developer Experience wünschen

Warten Sie, wenn:

  • Ihr Projekt mit dem alten Compiler einwandfrei funktioniert
  • Sie Frameworks benötigen, die vom neuen Compiler noch nicht unterstützt werden

Nächste Schritte