Zurück

Sie machen Next.js-i18n falsch

General Translation avatarGeneral Translation
Ernest McCarter avatarErnest McCarter
guideinternationalizationnextjsi18ngt-nextapp-routertutorial

Internationalisierung in JavaScript hat sich auf eine fehlerhafte Konvention eingependelt: Jede benutzerseitige Textzeichenkette wird in eine JSON-Datei ausgelagert, erhält einen Schlüssel und wird in den Komponenten über diesen Schlüssel referenziert. t('home.hero.title') statt des eigentlichen Textes. Ihr UI lebt an einem Ort, Ihre Inhalte an einem anderen.

Das funktioniert. Tausende Apps werden so ausgeliefert. Aber es ist keine besonders gute Developer Experience.

t('checkout.summary.total') in einem Code-Review zu lesen, sagt Ihnen nichts – Sie müssen eine JSON-Datei öffnen, um zu sehen, was sich geändert hat. Schlüssel müssen erfunden, mit Namespaces versehen und synchron gehalten werden. Veraltete Übersetzungen sammeln sich an, weil niemand weiß, welche Schlüssel noch in Verwendung sind. Das Problem ist so weit verbreitet, dass ganze Tool-Kategorien nur dafür existieren, es zu verwalten: IDE-Erweiterungen, die Schlüssel automatisch vorschlagen, Type-Generatoren, die sie validieren, Linter, die ungenutzte markieren. Diese Tools lösen ein Problem, das ein schlecht entworfenes Paradigma geschaffen hat.

Die Komponente <T>

Inhalte sollten nicht von der Stelle getrennt werden, an der sie verwendet werden. Eine Komponente, die eine Überschrift, einen Absatz und einen Button rendert, sollte die einzige maßgebliche Quelle dafür sein, was diese Elemente anzeigen – nicht ein Proxy, der auf irgendwo anders gespeicherte Strings verweist. Wenn Ihr Code und Ihre Übersetzungen zwei parallele Systeme sind, driften sie auseinander. Unweigerlich.

Was wäre, wenn die Bibliothek andersherum funktionieren würde – sich an Ihren Code anpasst, statt von Ihnen zu verlangen, ihn umzustrukturieren? So sollte i18n aussehen.

import { T } from 'gt-next';

function Hero() {
  return (
    <T>
      <h1>Ship your product worldwide</h1>
      <p>Erreichen Sie jeden Markt, ohne Ihre App neu schreiben zu müssen.</p>
    </T>
  );
}

Umschließen Sie Ihr JSX mit <T>. Der englische Text bleibt genau dort, wo Sie ihn geschrieben haben. Wenn ein Nutzer die Seite auf Spanisch oder Japanisch besucht, wird der Inhalt innerhalb von <T> übersetzt – inklusive Struktur und Formatierung.

Keine Keys. Keine JSON-Dateien. Keine Querverweise. Die maßgebliche Quelle ist Ihr Code.

Einrichtung

Die oben gezeigte Syntax stammt aus gt-next, einer Open-Source-i18n-Bibliothek für den Next.js App Router. Für den Einstieg benötigen Sie nur einen einzigen Befehl:

npx gtx-cli@latest init

Der Setup-Assistent installiert Abhängigkeiten, wrappt Ihre Next.js-Konfiguration mit withGTConfig, fügt GTProvider zu Ihrem Root-Layout hinzu, erstellt eine gt.config.json mit Ihren Locales, richtet Dev-API-Schlüssel für Hot-Reloading der Übersetzungen ein und konfiguriert die Übersetzungsspeicherung über ein CDN (Content Delivery Network) – alles interaktiv.

Sobald das erledigt ist, umschließen Sie Inhalte mit <T>, starten Sie Ihren Dev-Server und verwenden Sie die <LocaleSelector>-Komponente, um zwischen Sprachen zu wechseln:

import { LocaleSelector } from 'gt-next';

function Header() {
  return (
    <header>
      <nav>{/* ... */}</nav>
      <LocaleSelector />
    </header>
  );
}

Übersetzungen werden während der Entwicklung bei Bedarf ausgeführt, sodass Sie Ihre App sofort in jeder gewünschten Sprache sehen können.

Deployment

In der Produktionsumgebung werden Übersetzungen vorab generiert.

  1. Holen Sie sich einen Produktions-API-Schlüssel von dash.generaltranslation.com. Produktionsschlüssel beginnen mit gtx-api- (im Unterschied zu den lokal verwendeten gtx-dev--Schlüsseln).

  2. Fügen Sie den Übersetzungsschritt zu Ihrem Build hinzu:

{
  "scripts": {
    "build": "npx gtx-cli translate --publish && next build"
  }
}

Der translate-Befehl scannt Ihre Codebasis nach sämtlichen <T>-Verwendungen, generiert Übersetzungen und stellt sie in einem CDN (Content Delivery Network) bereit. Beim Build Ihrer App ist jede Locale einsatzbereit.

Nächste Schritte