CGChristoph Griehl
ENLebenslauf
ArbeitenExpertiseBlogÜber michKontaktRead in English
← Alle Beiträge
Webentwicklung · Technik

Ein ganzheitlicher Ansatz zur Internationalisierung von Anwendungen

i18n über Client, Backend und Team-Workflow hinweg richtig machen — ohne die Codebasis in einen String-Friedhof zu verwandeln.

CG
Christoph Griehl
Senior Full-Stack Engineer
15. Sept. 20233 Min. Lesezeit
Ein Smartphone auf Weltreise
Ein Smartphone auf Weltreise

Internationalisierung kommt meist spät und laut: ein Deal in einem neuen Markt oder ein Partner, der das Produkt bis Freitag in seiner Sprache braucht. Bis dahin ist die Codebasis voller fest verdrahteter Strings, dreifach unterschiedlich formatierter Daten und eines Backends, das sich immer nur eine Locale vorgestellt hat. So gehe ich i18n an, damit es wartbar bleibt, statt zur Steuer auf jedes künftige Feature zu werden.

Beginne an der Grenze, nicht bei den Strings

Der Instinkt ist, sichtbaren Text durch Übersetzungs-Keys zu ersetzen. Das ist der einfache Teil. Der schwierigere Teil ist überall dort, wo eine Locale still einsickert: Zahlen- und Währungsformatierung, Datum und Zeitzonen, Pluralisierung, Sortierreihenfolge und Textrichtung. Entscheide früh, wo in deinem System die Locale-Grenze liegt, und behandle alles, was sie überquert, standardmäßig als locale-bewusst.

In der Praxis heißt das: ein einziger aufgelöster Locale-Wert, der von der Anfrage bis zum Rendering durchgereicht wird — niemals auf halbem Weg im Stack aus einer Vermutung neu hergeleitet.

Auf dem Client: eine Bibliothek und eine einzige Quelle der Wahrheit

Wähle eine etablierte Bibliothek, statt eine eigene zu bauen. Ich greife zu i18next: framework-unabhängig, kampferprobt, und du erbst die hart erarbeiteten Sonderfälle der Community. Halte das Setup dann langweilig. Eine einzige JSON-Datei mit Übersetzungen reicht meist; greife erst zu Namespaces, verschachtelten Keys oder Backend-geladenen Bundles, wenn eine echte Einschränkung — etwa die Bundle-Größe — es erzwingt. Jede davon fügt eine Möglichkeit hinzu, einen Key aus den Augen zu verlieren.

Gib Keys Struktur mit einer selbsterklärenden, BEM-inspirierten Konvention wie userSettingsPage.languageSwitch, und lass Tooling sie ehrlich halten. Der i18next-parser scannt die Codebasis, entfernt tote Keys und ergänzt neue; in TypeScript-Projekten verwandelt das Generieren eines Key-Typs eine fehlende Übersetzung in einen Compile-Fehler statt in eine Überraschung in der Produktion.

{
  "userSettingsPage.languageSwitch": "Language",
  "checkout.items": "{count, plural, one {# item} other {# items}}",
  "checkout.total": "Total: {amount, number, ::currency/EUR}"
}

Das ICU-Message-Format für Plurale und Interpolation zu nutzen, hält grammatische Logik aus deinen Komponenten heraus und an dem einen Ort, den Übersetzer tatsächlich erreichen können.

Eine fehlende Übersetzung sollte elegant auf einen lesbaren Standard zurückfallen — niemals auf einen rohen Key, der deinen Nutzer anstarrt.

Auch das Backend spricht Locale

E-Mails, PDFs, Validierungsfehler und Benachrichtigungen entstehen alle serverseitig, und sie brauchen dieselbe Locale-Maschinerie wie der Client. Eine Sprachpräferenz in der Datenbank zu speichern, ist in Ordnung, aber sie bei jeder Anfrage abzufragen, skaliert in einem zustandslosen Dienst nicht. Eine sauberere Auflösungsreihenfolge:

  1. Lies die Locale aus einem eigenen Header der Anfrage.
  2. Falle zurück auf die gespeicherte Präferenz des Nutzers in der Datenbank.
  3. Für öffentliche Endpunkte: falle zurück auf den Accept-Language-Header des Browsers.
  4. Falle für alles Übrige auf eine Standard-Locale zurück.

Reiche diesen einen aufgelösten Wert dann in jeden Background-Job durch. Der häufigste Produktionsbug hier ist eine perfekt lokalisierte UI, die ihre Bestätigungs-E-Mail in der falschen Sprache verschickt.

Mach Übersetzung zu einem Team-Workflow

Engineers sollten nicht der Flaschenhals für Texte in einem Dutzend Sprachen sein. Eine Plattform wie locize lässt nicht-technische Kolleginnen Übersetzungen direkt bearbeiten, und ein Webhook kann automatisch einen Pull Request öffnen — das Team muss nur noch reviewen und mergen. Extrahiere Keys in CI, halte die Standard-Locale vollständig und geprüft, und lass den Build bei fehlenden Keys für ausgelieferte Locales fehlschlagen.

Was ich anders machen würde

Wenn ich meinem früheren Ich eine Sache sagen könnte: Zieh die Locale-Grenze am ersten Tag ein, selbst mit einer einzigen Sprache. i18n nachzurüsten ist größtenteils Archäologie — jeden Ort zu finden, an dem ein String, ein Datum oder eine Zahl durchgerutscht ist. Die Naht von vornherein zu bauen, kostet fast nichts und erspart später ein brutales Refactoring. Langweilige Infrastruktur, früh angewandt, gewinnt wieder einmal.

UIUXFreelance
CG
Christoph Griehl

Senior Full-Stack Engineer in Deutschland — tätig an KI-/RAG-Systemen, Geodaten-Software, Dokumentenintelligenz und datenintensiven Web-Plattformen.

Weiterlesen
23. Mai 2023 · Persönlich

Remote-Engineering unterwegs

Beitrag lesen →
16. Apr. 2023 · Technik

Eine produktionsreife Web-Component-Library bauen

Beitrag lesen →