localize.dev

Dokumentation

localize.dev wandelt fest codierte Texte in Übersetzungsaufrufe in React-, Next.js-, React Native-, Vue-, Nuxt-, Svelte-, Angular-, Astro-, Solid-, Qwik-, Lit-, Ember-, Flutter-, Rails-, Django-, Laravel-, Android-, iOS- und statischen HTML-Codebasen um, schreibt die Sprachdateien, richtet die i18n-Bibliothek ein, falls noch keine vorhanden ist, und kann den Pull Request für Sie öffnen. Die Übersetzung läuft auf dem gehosteten localize.dev-Modell, sodass über einen API-Schlüssel hinaus nichts eingerichtet werden muss.

Schnellstart

Sie benötigen Node.js 22 oder neuer. Ihre App benötigt noch keine i18n-Bibliothek; der erste Durchlauf richtet eine ein. Erstellen Sie einen kostenlosen API-Schlüssel im Dashboard, wählen Sie dann Ihr Framework:

React

Jede UI, die über eine Komponente gerendert wird, die aufrufen kann useTranslation(): React mit Vite, Remix oder Gatsby, Electron- und Tauri-Renderer sowie Designsysteme oder gemeinsam genutzte UI-Pakete. Klassenkomponenten erhalten t durch withTranslation(), oder <Translation> wenn sie nicht der Standardexport der Datei sind. Sätze um Links bleiben mit ganz <Trans> (eigenen Link title eingeschlossen), Kopien in Konstanten, Toasts und Zod-Nachrichten sind vorhanden, und Daten, Zahlen und Preise folgen der Sprache der App.

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

# Only if the run added packages to package.json
npm install

React Anleitung: welche Änderungen, mit einem echten Vorher und Nachher.

Next.js

App Router-Server-Komponenten erhalten const { t } = await getTranslation() und Client-Komponenten useTranslation(), beide in der vom Server gewählten Sprache; der Pages Router funktioniert wie React. Ein proxy.ts gibt jeder Seite eine URL pro Sprache mit hreflang Links.

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

# Only if the run added packages to package.json
npm install

Next.js Anleitung: welche Änderungen, mit einem echten Vorher und Nachher.

React Native and Expo

React Native und Expo. accessibilityLabel und accessibilityHint werden ebenfalls übersetzt, und die i18n-Einrichtung vermeidet browser-only APIs.

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

# Only if the run added packages to package.json
npm install

React Native and Expo Anleitung: welche Änderungen, mit einem echten Vorher und Nachher.

Vue

Text und {{ }} in <template> werden zu {{ $t('key') }} und Attribute werden zu :placeholder="$t('key')", mit vue-i18n eingerichtet in src/i18n.ts und installiert in main.ts. Nachrichten angezeigt von <script setup> (alert, Toasts, document.title) verwenden t() von useI18n, und n === 1 ? … : … wird zu einem vue-i18n Plural. Ein bestehendes createI18n Setup bleibt unverändert. Ein Satz um einen Link oder Fettdruck bleibt eine Nachricht über <i18n-t>, mit den Elementen als Slots. Konstanten in <script setup> die durch die Vorlage angezeigt werden ({{ title }}, v-for="tab in tabs") werden zu Schlüsseln, die gelesen werden über $t(). Vorlagen, die in Pug geschrieben sind (<template lang="pug">) erhalten dasselbe: h1 {{ $t('key') }}, gepipter und Blocktext, und input(:placeholder="$t('key')").

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

# Only if the run added packages to package.json
npm install

Vue Anleitung: welche Änderungen, mit einem echten Vorher und Nachher.

Nuxt

Seiten und Komponenten werden wie jede Vue-Komponente neu geschrieben, und @nuxtjs/i18n wird zu nuxt.config, mit einer URL pro Sprache (/es/about) und hreflang Links von useLocaleHead().

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

# Only if the run added packages to package.json
npm install

Nuxt Anleitung: welche Änderungen, mit einem echten Vorher und Nachher.

Svelte and SvelteKit

Markup wird zu {$_('key')} mit svelte-i18n, initialisiert von src/lib/i18n und importiert in +layout (oder main.ts ohne SvelteKit). Attribute wie title="Hello {name}" werden zu einer Nachricht. In SvelteKit wird ein generiertes hooks.server rendert jede Seite in der Sprache des Besuchers (seine gespeicherte Wahl, dann Accept-Language), sodass kein Flackern der Quellsprache auftritt.

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

# Only if the run added packages to package.json
npm install

Svelte and SvelteKit Anleitung: welche Änderungen, mit einem echten Vorher und Nachher.

Angular

Vorlagen (.html und inline template:) werden zu {{ 'key' | translate }} mit ngx-translate, Attribute [placeholder]="'key' | translate" ([attr.aria-label] für aria), und Zeichenketten in Bindings ('key' | translate). Kontrollfluss (@if, @for), *ngIf und Inline-Vorlagen werden verstanden; Elemente, die mit Angulars eigenen gekennzeichnet sind i18n werden ihm überlassen. Das Setup fügt hinzu provideI18n() zu app.config.ts (jedes Locale gebündelt, kein HTTP-Loader) und TranslatePipe zu jeder eigenständigen Komponente, die es benötigt.

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

# Only if the run added packages to package.json
npm install

Angular Anleitung: welche Änderungen, mit einem echten Vorher und Nachher.

Astro

Text und {expressions} in .astro Dateien werden zu {t('key')}, Attribute title={t('key')}, mit t von einem generierten src/i18n Modul, das die Sprache aus der URL liest. Jede statische Seite erhält eine Kopie pro Sprache (src/pages/es/about.astro), sodass jede Sprache eine echte, indexierbare Seite ist und Layouts festlegen <html lang dir>. localizePath(path, lang) erstellt Links zwischen Sprachen. React-, Vue- und Svelte-Inseln (von @astrojs/react, /vue, /svelte) werden im selben Durchlauf lokalisiert, jede mit ihrer eigenen eingerichteten Bibliothek und der Seitensprache folgend.

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

Astro Anleitung: welche Änderungen, mit einem echten Vorher und Nachher.

Solid

JSX wie React, mit useTranslation() von einem generierten src/i18n.ts: i18next hinter einem Sprachsignal, sodass sich der Text an Ort und Stelle aktualisiert, wenn sich die Sprache ändert. Sätze um Links herum bleiben eine Nachricht, gerendert von rich(t('key'), { a: (c) => <a href="/terms">{c}</a> }) aus demselben Modul.

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

# Only if the run added packages to package.json
npm install

Solid Anleitung: welche Änderungen, mit einem echten Vorher und Nachher.

Qwik

JSX in component$ erhält const { t } = useTranslation() von einem generierten src/i18n.ts das die Sprache aus der URL liest (Qwik Citys useLocation), und jede Route, auch dynamische, erhält eine Kopie pro Sprache unter src/routes/es/. Sätze um Links herum bleiben eine Nachricht durch rich() aus demselben Modul.

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

Qwik Anleitung: welche Änderungen, mit einem echten Vorher und Nachher.

Lit

Text und ${expressions} in html`…` Vorlagen werden zu ${t('key')}, Attribute placeholder=${t('key')}. Komponenten erhalten ein I18nController damit sie neu gerendert werden, wenn setLanguage() die Sprache wechselt; verschachtelte Vorlagen, Stile und Kommentare bleiben unberührt.

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

Lit Anleitung: welche Änderungen, mit einem echten Vorher und Nachher.

Ember

Glimmer-Vorlagen (.hbs, und <template> in .gjs/.gts) werden zu {{t "key" name=this.name}} mit ember-intl werden Attribute placeholder={{t "key"}}, Zeichenketten in {{if}} (t "key"), und {{if (eq n 1) "item" "items"}} in einem Satz ein Plural. Nachrichten gehen an translations/<locale>.json; eine generierte Anwendungsroute wählt die Sprache aus.

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

# Only if the run added packages to package.json
npm install

Ember Anleitung: welche Änderungen, mit einem echten Vorher und Nachher.

Flutter

Text('Hi $name') und Argumente wie hintText: werden zu AppLocalizations.of(context)!.hiName(name), mit Nachrichten in lib/l10n/app_en.arb (camelCase-Schlüssel, ICU-Plurale, Platzhalter-Metadaten). const wird aus Widgets entfernt, die jetzt eine Nachschlagefunktion enthalten; Zeichenfolgen ohne BuildContext im Gültigkeitsbereich werden gemeldet. Die Einrichtung fügt hinzu flutter_localizations, generate: true, l10n.yaml, die MaterialApp Delegierten und die iOS-Sprachliste.

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

Nein package.json benötigt: npx führt die CLI aus. Flutter Anleitung: welche Änderungen, mit einem echten Vorher und Nachher.

Static HTML

Der Text bleibt auf der Seite und erhält ein data-i18n="key" Markierung (Attribute erhalten data-i18n-placeholder und ähnliche). Ein generiertes i18n.js lädt die Locale-Dateien und tauscht den Text aus; füge <select data-i18n-switcher></select> für ein Sprachmenü. Ein Satz mit Inline-Elementen (<strong>, Links) ist eine Nachricht, die aus den eigenen Elementen der Seite neu aufgebaut wird. Übersetzungen werden auch gebündelt in i18n.js, sodass auch von der Festplatte geöffnete Seiten funktionieren. Text aus einer Template-Engine ({{ }}, {% %}, PHP) wird unverändert gelassen.

Suchmaschinen sehen nur den Text auf der Seite, also setzen Sie "htmlPages": true und "siteUrl" in localize.config.json um jede Seite auch in jede Sprache übersetzt zu schreiben (es/index.html), verknüpft mit hreflang.

npm install --save-dev localize-dev

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

Static HTML Anleitung: welche Änderungen, mit einem echten Vorher und Nachher.

Ruby on Rails

Text in ERB-Ansichten wird zu <%= t('key', name: @user.name) %>, mit %{name} Platzhalter in config/locales/<locale>.yml und Pluralformen, die mit aufgerufen werden count:. available_locales und ein switch_locale um die Aktion herum hinzugefügt.

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

Nein package.json benötigt: npx führt die CLI aus. Ruby on Rails Anleitung: welche Änderungen, mit einem echten Vorher und Nachher.

Django

Vorlagen erhalten {% translate '…' %} und {% blocktranslate %}, Übersetzungen gehen in locale/<lang>/LC_MESSAGES/django.po, und Einstellungen erhalten LANGUAGES, LOCALE_PATHS und LocaleMiddleware.

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

Nein package.json benötigt: npx führt die CLI aus. Django Anleitung: welche Änderungen, mit einem echten Vorher und Nachher.

Laravel

Blade-Text wird zu {{ __('Hi :name', ['name' => $user->name]) }} mit lang/<locale>.json indiziert nach dem Text, und ein SetLocale Middleware wählt die Sprache aus (?locale=, ein lang Cookie, dann Accept-Language).

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

Nein package.json benötigt: npx führt die CLI aus. Laravel Anleitung: welche Änderungen, mit einem echten Vorher und Nachher.

Android

android:text, hint und contentDescription in Layouts und Menüs werden zu @string/…, und Compose Text("Hi $name") in @Composable Funktionen wird zu stringResource(R.string.…, name). Code in Kotlin oder Java anzeigen (label.setText("Hi"), label.text = "Hi") wird zu setText(R.string.…). Strings gehen zu res/values-<lang>/strings.xml mit nummerierten %1$s Platzhaltern, und locales_config.xml listet die Sprachen für Android 13+ auf.

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

Nein package.json benötigt: npx führt die CLI aus. Android Anleitung: welche Änderungen, mit einem echten Vorher und Nachher.

iOS

SwiftUI-Text (Text("Hi \(name)"), Button, .navigationTitle) bleibt wie geschrieben, da SwiftUI es selbst im String Catalog nachschlägt; UIKit-Strings (label.text = "Hi") werden zu String(localized: "Hi"). Alles kommt in Localizable.xcstrings mit jeder Sprache in der einen Datei. Fügen Sie den Katalog einmal zu Ihrem App-Ziel in Xcode hinzu.

# Save your API key on this machine
npx localize-dev login

# See what would change, without writing anything
npx localize-dev run --dry-run -l es,fr

# Rewrite the code and write the locale files
npx localize-dev run -l es,fr

Nein package.json benötigt: npx führt die CLI aus. iOS Anleitung: welche Änderungen, mit einem echten Vorher und Nachher.

Möchten Sie sich umsehen, bevor Sie sich anmelden? npx localize-dev scan listet jede Zeichenkette auf, die extrahiert würde, und --offline generiert Schlüssel, ohne zu übersetzen. Keiner benötigt einen Schlüssel und keiner verbraucht Ihr Kontingent. Ein späterer Online-Lauf füllt die fehlenden Übersetzungen auf, ohne vorhandene Schlüssel zu berühren.

Unterstützte Codebasen

Jedes Framework erhält seinen eigenen Scanner und seine eigene i18n-Bibliothek. Was sich in jedem ändert, steht unter seinem Namen in der Schnellstart, und in seiner Anleitung.

Monorepos: von der Root aus ausführen mit --workspaces (oder das der Action workspaces: true) um jede App mit eigenen Sprachdateien zu lokalisieren. Gemeinsam genutzte Komponentenbibliotheken (Pakete ohne dev oder start script) werden ebenfalls in den Sprachen der Apps übersetzt, von denen sie abhängen, und ihre Nachrichten werden zu den Sprachdateien dieser Apps hinzugefügt, sodass die t() Aufrufe über das eigene Setup jeder App aufgelöst werden. Um nur eine App zu lokalisieren, geben Sie der Action stattdessen working_directory: apps/web an: Sie liest die localize.config.json, den Code und die Locale-Dateien dieser App, und der Pull Request ändert sie an Ort und Stelle.

Das Framework wird erkannt aus package.json (oder pubspec.yaml, oder die Dateien, wenn beides nicht vorhanden ist); setzen Sie "framework" in localize.config.json um es zu überschreiben. React-Wörterbücher verwenden i18next- oder ICU-Platzhalter; Vue, Svelte und HTML verwenden ICU-Style {name}.

Vorhandene Sprachdateien

Haben Sie i18n bereits eingerichtet, in jedem Stack? localize-dev translate überspringt den Code und füllt das aus, was in Ihren Lokalisierungsdateien fehlt: Schlüssel ohne Übersetzung, in jeder Sprache, die Sie bereits haben, oder in neuen, die Sie benennen. Bestehende Übersetzungen werden nie geändert und es wird kein Framework erkannt, sodass es für jeden Stack funktioniert, native iOS und Android, Rails und Django inklusive.

# Fill in what's missing in the languages already there
npx localize-dev translate --dry-run
npx localize-dev translate

# Add languages (creates the files)
npx localize-dev translate -l de,ja,pt-BR

# Or as a pull request
npx localize-dev pr --translate
FormatDateienNotizen
JSONlocales/en.json, public/locales/en/*.jsoni18next (mit _one/_other-Pluralformen), ICU (react-intl, next-intl, inkl. =0-Matches und select), vue-i18n, ngx-translate, Transloco
YAMLconfig/locales/en.yml, devise.en.ymlRails, unter dem Sprachschlüssel; Abbildung der Pluralformen (ein/andere)
gettextlocale/fr/LC_MESSAGES/django.poDjango, WordPress, PHP, Python. Leere und unklare Einträge werden ausgefüllt; Pluralformen folgen den Pluralregeln. Neue Sprachen werden neben einer bestehenden erstellt, mit eigenen Pluralregeln.
Flutterlib/l10n/app_en.arbICU-Nachrichten; @key-Beschreibungen werden zum Kontext. gen-l10n erkennt die neuen Dateien.
Androidres/values/strings.xml<string> und <plurals>; translatable="false", <xliff:g> und Escape-Sequenzen werden respektiert. Schreibt values-es/, values-pt-rBR/.
AppleLocalizable.xcstrings, en.lproj/*.stringsString-Catalogs erhalten jede Sprache inklusive Pluralformen; .strings-Dateien erhalten neue .lproj-Ordner (Sprachen in Xcode hinzufügen).
Browser-Erweiterungen_locales/en/messages.jsonPlaceholders werden in jede Sprache kopiert.

Platzhalter in der eigenen Syntax jedes Formats ({{name}}, %{name}, %1$s, %@, %(name)s, $NAME$) sind geschützt: Eine Übersetzung, die einen verliert oder hinzufügt oder unbenannte wie folgt neu anordnet %s, wird verworfen und gemeldet. Plurale erhalten jede Form, die die Zielsprache benötigt (Russisch erhält one, few und many). Kommentare und Beschreibungen in den Dateien werden dem Modell als Kontext übergeben.

Bearbeitete Kopie: localize.lock.json behält einen Fingerabdruck jeder Quellnachricht bei, wenn sie übersetzt wird. Ändern Sie das Englische und das nächste run, translate oder die Ausführung einer Aktion übersetzt sie erneut in jeder Sprache; check schlägt bei veralteten Übersetzungen fehl. Committen Sie die Datei.

Legen Sie in der GitHub Action fest mode: translate. Jeder Lauf öffnet oder aktualisiert einen Pull Request mit allem, was fehlt, sodass neue Schlüssel, die auf Englisch hinzugefügt wurden, übersetzt werden, sobald sie eintreffen.

Crowdin, Phrase, Lokalise, Transifex

Arbeiten Sie mit Übersetzern in einem TMS? Pushen Sie Ihre Quellgebietsschema-Dateien dorthin und ziehen Sie deren Übersetzungen zurück. Fügen Sie das Projekt zu localize.config.json (provider: crowdin, phrase, lokalise oder transifex) und fügen Sie das API-Token in CROWDIN_TOKEN, PHRASE_TOKEN, LOKALISE_TOKEN oder TRANSIFEX_TOKEN (niemals in der Konfigurationsdatei):

localize.config.json
{
  "tms": { "provider": "crowdin", "projectId": "123456" }
}
# Upload source files (and, the first time, your existing translations)
npx localize-dev sync push --translations

# Download translations into your locale files
npx localize-dev sync pull

JSON, YAML, ARB, Android, .strings und Erweiterungsdateien werden synchronisiert. Crowdin behält Ihre Ordner bei, Phrase hält jede Datei mit einem Tag getrennt, Lokalise speichert jede unter ihrem Pfad mit der Sprache als %LANG_ISO%, und Transifex erhält eine Ressource pro Datei (projectId wie o:acme:p:web). Sprachen werden mit den eigenen Codes des Projekts abgeglichen (es → es-ES, pt-BR → pt_BR). Für Crowdin Enterprise oder das US-Rechenzentrum von Phrase setzen Sie "url" auf seine API-Adresse. gettext- und String Catalog-Dateien werden besser von den eigenen Integrationen des TMS bedient. Eine gängige Schleife: führen Sie localize-dev run oder translate für maschinelle Übersetzungen, pushen, Rezensenten bearbeiten lassen, ziehen.

CLI-Befehle

localize-dev init
Schreibt eine localize.config.json mit allen ausgeschriebenen Standardwerten.
localize-dev init --agent [--pre-commit]
Richtet Coding-Agenten ein, um Text beim Schreiben des Codes zu übersetzen: den MCP-Server für Claude Code und Cursor, einen After-Edit-Hook für Claude Code und Anweisungen in AGENTS.md sowie eine Cursor-Regel. --pre-commit prüft auch gestagte Dateien vor jedem Commit. So funktioniert's.
localize-dev login [--api-key ldv_live_…]
Speichert Ihren API-Schlüssel für diese Maschine. Ohne --api-key fordert es auf oder liest den Schlüssel von stdin.
localize-dev whoami
Zeigt den Arbeitsbereich, den Plan und die Nutzung für den aktuellen Schlüssel an.
localize-dev logout
Entfernt den gespeicherten Schlüssel von dieser Maschine.
localize-dev scan [-d src] [-o extracted_strings.json]
Listet alle Zeichenfolgen auf, die extrahiert würden, sowie die übersprungenen und warum. Ändert nichts; kein Schlüssel erforderlich.
localize-dev run [--dry-run] [--offline] [--workspaces] [--files a.tsx… | --changed | --staged] [-l es,fr] [-d src] [--api-key …]
Der vollständige Durchlauf: extrahieren, Schlüssel benennen, übersetzen, Dateien umschreiben, Wörterbücher aktualisieren und die i18n-Bibliothek einrichten wenn die App keine hat. Mit --workspaces, jede App in einem Monorepo nacheinander.
localize-dev translate [--dry-run] [-l de,ja] [-s en] [--api-key …]
Füllt fehlende Übersetzungen in vorhandenen Lokalisierungsdateien für jeden Stack auf. Der Code wird nicht berührt. Formate.
localize-dev check [--only strings|translations] [--files a.tsx… | --changed | --staged] [--json]
Schlägt CI bei hartcodierten Kopien, fehlenden Übersetzungen und veralteten Übersetzungen im Vergleich zur Quelle fehl; meldet ungenutzte Schlüssel und, bei einer Rechts-nach-links-Sprache, Links-/Rechtsstile. Details.
localize-dev prune [--dry-run]
Entfernt Schlüssel, auf die kein Code verweist, aus der Sprachdatei jeder Sprache.
localize-dev rtl [--fix]
Listet Stile auf, die links oder rechts angeheftet sind; --fix tauscht die sicheren gegen logische aus. Rechts nach links.
localize-dev content [--dry-run] [-l de,ja]
Übersetzt Markdown- und MDX-Dokumente in eine Kopie pro Sprache. Dokumentation und Inhalte.
localize-dev sync push|pull [--translations] [-l de,ja]
Pusht Quellsprachdateien zu Crowdin, Phrase, Lokalise oder Transifex oder zieht deren Übersetzungen zurück. Einrichtung.
localize-dev seo <url> [--limit 500] [--json]
Prüft, was Suchmaschinen von jeder Sprache auf einer Website sehen, live oder in einem lokalen Build: die Sitemap, hreflang-Links, <html lang>, die kanonische Adresse und og:locale. Beendet mit 1, wenn ein Problem gefunden wird, damit es nach einem Deploy in CI ausgeführt werden kann Details.
localize-dev pr [--translate] [--base main] [--repo owner/name] [--branch name] [--token …]
Führt den Pass aus und öffnet (oder aktualisiert) einen Pull-Request auf localize-dev/<base> anstatt lokal zu schreiben. Verwendet GITHUB_TOKEN wenn --token wird weggelassen. Mit --translate, der Pull-Request füllt nur fehlende Übersetzungen aus.

Programmier-Agenten

localize-dev mcp führt einen MCP-Server aus, damit ein Coding-Agent (Claude Code, Cursor, Codex, GitHub Copilot und andere) das Repository, an dem er arbeitet, überprüfen und lokalisieren kann. Lovable, Bolt, v0 und andere Builder, die im Browser laufen, verbinden sich mit dem gehosteten Server unter https://uselocalize.dev/api/mcp mit einem API-Schlüssel. Die Einrichtung für jeden Agenten befindet sich auf der MCP-Seite. Damit der Agent Text übersetzt, während er ihn schreibt, führen Sie dies im Ordner der App aus:

npx localize-dev init --agent               # MCP server, Claude Code hook, AGENTS.md, Cursor rule
npx localize-dev init --agent --pre-commit  # also check staged files before each commit

Es schreibt diese Dateien:

  • .mcp.json und .cursor/mcp.json: der MCP-Server, für Claude Code und Cursor.
  • .claude/settings.json: ein After-Edit-Hook, der npx -y localize-dev hook ausführt. Wenn eine von Claude Code bearbeitete Datei Text enthält, der nicht übersetzt ist, listet der Hook die Zeilen auf und der Agent ruft localize für diese Datei auf, bevor er fortfährt.
  • AGENTS.md und eine CLAUDE.md, die sie importiert, wenn keine vorhanden ist: wann localize und check aufgerufen werden sollen. Eine Cursor-Regel in .cursor/rules/localize.mdc besagt dasselbe für Ihre UI-Dateien.
  • Mit --pre-commit: check --staged im Pre-Commit-Hook von husky oder dem eigenen von git.

In einem Monorepo benennen die Anweisungen die App. Ihre vorhandenen Einstellungen, Server und Texte bleiben erhalten, und ein zweiter Durchlauf ändert nichts. Committen Sie die Dateien, damit das Team und seine Agenten sie teilen. Der Hook liest nur die Datei, ohne Schlüssel oder Modell, und dauert etwa eine Sekunde; LOCALIZE_DEV_HOOK=off pausiert ihn. Zeichenfolgen, die ein Agent über den MCP-Server übersetzt, werden auf der Nutzungsseite als „Während des Schreibens“ angezeigt.

i18n-Einrichtung

Vue, Nuxt, Svelte und statisches HTML sind wie beschrieben eingerichtet in Unterstützte Codebasen. In React rufen neu geschriebene Komponenten useTranslation(), die App benötigt also i18next im laufenden Betrieb. Wenn dies nicht der Fall ist, fügt die Ausführung (und der Pull Request der Aktion) das Fehlende hinzu:

  • i18next und react-i18next in package.json. Die Aktion aktualisiert auch Ihre Lockfile (npm, pnpm, Yarn oder Bun); führen Sie nach einem lokalen Lauf Ihre Installation aus.
  • src/i18n.ts (oder .js), lädt die Locale-Dateien und wählt die Sprache aus einer gespeicherten Auswahl, dann dem Browser, dann Ihrer Quellsprache. Bei mehr als drei Zielsprachen wird nur die Quelle gebündelt und der Rest wird beim ersten Gebrauch geladen ("lazyLocales" zu wählen). In Remix-Apps ohne v3_routeConfig werden Seiten in ihrem <html lang> und wechseln nach dem Laden.
  • Ein import './i18n' in Ihrer Eintragsdatei: das Skript in index.html, sonst src/main.* oder src/index.*.
  • resolveJsonModule in tsconfig.json, damit die Sprachdateien importiert werden können.
  • Ein Import davon in Ihrer Test-Setup-Datei (Vitest setupFiles, Jest setupFilesAfterEnv, src/setupTests), damit Tests, die nach Text suchen, ihn weiterhin finden. Vue installiert vue-i18n für @vue/test-utils.
  • Eine Zeile in .gitattributes die die Sprachdateien Zeile für Zeile zusammenführt, damit beim Hinzufügen von Schlüsseln in zwei Branches keine Konflikte entstehen. Aktiviere es einmal pro Klon mit git config merge.localize-dev.driver "npx localize-dev merge-locales %O %A %B %P" (Merge auf GitHub selbst führen Sie es nicht aus).
  • src/language-switcher.tsx, Exportieren <LanguageSwitcher /> und useLanguage() mit den Standardwerten dieser App, und localize-dev als Abhängigkeit. Rendern Sie den Schalter, wo Leute eine Sprache auswählen, z.B. in Ihrer Kopfzeile; er ist nicht für Sie platziert. Optionen.

Wenn eine Datei i18next bereits initialisiert, wird nichts davon hinzugefügt und deine Einrichtung wird unverändert verwendet. Der Schalter speichert die Wahl in localStorage und stellt es beim nächsten Besuch wieder her; um von deinem eigenen Code zu wechseln, rufe i18n.changeLanguage('es') und speichert lang auf die gleiche Weise. Projekte, die mit einer früheren Version eingerichtet wurden, erhalten den Schalter bei ihrem nächsten Lauf. Im Next.js Pages Router kommt der Import in pages/_app.

Next.js App Router

Dateien unter app/ ohne 'use client' sind Server-Komponenten, die keine Hooks verwenden können. Sie erhalten const { t } = await getTranslation() stattdessen (die Komponente wird async wenn es nicht so wäre), von einem generierten i18n.server Modul, das die Sprache aus einem lang Cookie, dann die des Browsers Accept-Language. Client-Komponenten behalten useTranslation(). Die Wurzel-Layout wird in ein generiertes <I18nProvider> das Client-Komponenten dieselbe Sprache übergibt und <html lang> folgt ihm. Der generierte Schalter setzt lang Cookie und aktualisiert, sodass Server-Komponenten im neuen Sprachmodus neu gerendert werden.

Sprachumschalter

<LanguageSwitcher /> ist ein Menü der Sprachen, die Ihre App bündelt (Ihre Quellsprache und die von Ihnen konfigurierten Zielsprachen), jeweils mit seiner Flagge und seinem eigenen Namen. Es funktioniert mit der Tastatur (Pfeile, Pos1/Ende, Eingabetaste, Escape, Eingabe eines Namens) und Bildschirmlesegeräten, merkt sich die Auswahl und setzt <html lang> und dir für Sprachen von rechts nach links.

Header.tsx
import { LanguageSwitcher, useLanguage } from './language-switcher';

<LanguageSwitcher />                                   // flag + native name
<LanguageSwitcher compact />                           // just the flag
<LanguageSwitcher nameStyle="native-english" />        // Español · Spanish
<LanguageSwitcher languages={['en', 'es']} />          // choose and order the list
<LanguageSwitcher regions={{ en: 'GB', pt: 'BR' }} />  // which country's flag
<LanguageSwitcher renderFlag={(l) => <img src={`/flags/${l.code}.svg`} alt="" />} />
<LanguageSwitcher unstyled className="…" buttonClassName="…" menuClassName="…" optionClassName="…" />

// Anywhere else: the current language and the list
const { language, info, languages, setLanguage, isRTL } = useLanguage();
info.flag        // "🇪🇸"
info.nativeName  // "Español"

Andere Props: showFlag, align (start/end), side (top/bottom), label, disabled, renderButton, renderOption, persist (localStorage, cookie oder none), storageKey und onChange. Eingebaute Stile lesen CSS-Variablen, sodass ein Thema oder ein Dark Mode nur wenige Zeilen entfernt ist: --ldv-bg, --ldv-fg, --ldv-border, --ldv-hover, --ldv-muted, --ldv-accent, --ldv-radius, --ldv-shadow. Ausgewählte und hervorgehobene Optionen tragen data-selected und data-active für Ihr eigenes CSS. Außerhalb von React, getLanguageInfo('pt-BR') gibt dieselben Namen, Flaggen und Richtungen zurück.

Im Next.js App Router speichert die generierte Datei die Auswahl in der lang Cookie und aktualisiert, sodass Serverkomponenten folgen. Emoji-Flaggen werden unter Windows als zwei Buchstaben angezeigt; übergeben Sie renderFlag für Bilder dort.

Alle anderen Frameworks erhalten dasselbe Menü, erzeugt für ihre eigenen Komponenten und ihren Zustand, auf Basis von <localize-language-switcher> (Custom Element aus localize-dev/switcher): Es nimmt dieselben Optionen als Attribute an, sendet language-change und lässt sich mit denselben --ldv-*-Variablen gestalten oder mit ::part(button|menu|option|flag).

Was die Einrichtung schreibt
Vue          src/language-switcher.ts           <LanguageSwitcher />, useLanguage()
Nuxt         components/LanguageSwitcher.ts     auto-imported, with composables/useLanguage.ts
Svelte       LanguageSwitcher.svelte            the $language store from language.ts
Solid, Qwik  src/language-switcher.tsx          <LanguageSwitcher />, useLanguage()
Angular      language-switcher.component.ts     <app-language-switcher />, languageOf(translate)
Astro        components/LanguageSwitcher.astro  useLanguage(Astro.url) from i18n/language.ts
Lit          src/language-switcher.ts           <app-language-switcher>, useLanguage()
Ember        components/language-switcher       <LanguageSwitcher />, the language service
React Native language-switcher.tsx              a native picker, useLanguage()
HTML         <localize-language-switcher>       from the CDN; i18n.js switches on language-change
Rails        shared/_language_switcher.html.erb render "shared/language_switcher", current_language
Django       language_switcher.html             {% include %}, {{ language }} in every template
Laravel      <x-language-switcher />            App\Support\Language::current()
Flutter      lib/language_switcher.dart         LanguageSwitcher(), language.of(context)
iOS          LanguageSwitcher.swift             LanguageSwitcher(), LanguageStore.shared, .appLanguage()
Android      LanguageSwitcher.kt                LanguageSwitcher(), showLanguagePicker(context)

API-Schlüssel

Schlüssel sehen aus wie ldv_live_… und gehören zu einem Arbeitsbereich; jeder Schlüssel in einem Arbeitsbereich teilt sich sein monatliches Kontingent. Die CLI sucht in dieser Reihenfolge nach einem Schlüssel:

  1. der --api-key Flag
  2. der LOCALIZE_API_KEY Umgebungsvariable (verwenden Sie dies in CI)
  3. der Schlüssel, gespeichert von localize-dev login, in ~/.config/localize-dev/credentials.json (nur für Sie lesbar)

Nur ein Hash jeder Schlüssel wird auf unserer Seite gespeichert, sodass ein Geheimnis nur einmal angezeigt wird, wenn Sie es erstellen. Widerrufen Sie einen Schlüssel im Dashboard, und er funktioniert sofort nicht mehr.

Konfiguration

Alles ist optional. Überstreichungen einfügen in localize.config.json im Projektstamm; CLI-Flags haben Vorrang vor der Datei.

FeldStandardBeschreibung
srcDir"src"Verzeichnis zum Scannen.
frameworkdetectedreact, react-native, vue, svelte oder html. Wird aus package.json erkannt, dann aus den Dateien.
include / ignoreby framework / tests, stories, .d.tsGlob-Patterns relativ zu srcDir: *.{tsx,jsx}, *.vue, *.svelte oder *.html.
sourceLocale"en"Sprache des fest codierten Textes.
targetLocales["es", "fr"]Zu übersetzende Sprachen.
localesPath"locales/{locale}.json"Wörterbuchort, z.B. public/locales/{locale}/common.json.
attributesplaceholder, alt, title, aria-label, label, tooltipAttribute, die als UI-Text behandelt werden. React Native fügt accessibilityLabel und accessibilityHint hinzu.
importSource"react-i18next"React: Wo useTranslation importiert wird, z.B. next-i18next.
interpolationby frameworki18next schreibt {{name}} (React); ICU schreibt {name} (Svelte, HTML); Vue schreibt {name} mit vue-i18n's speziellen Zeichen.
htmlPagesfalseStatisches HTML: Schreibe auch jede Seite übersetzt pro Sprache (es/index.html), für Suchmaschinen.
siteUrlnoneDie Adresse der Website, z.B. https://example.com. Benötigt für hreflang-Links zwischen Sprachversionen.
localizeFormatstrueStelle Daten, Zahlen und Preise so ein, dass sie einer Sprache folgen.
currency"USD"Was ein reines $ vor einem Betrag bedeutet, wenn Preise lokalisiert sind, z.B. "CAD".
lazyLocalesmehr als 3 SprachenReact: Bündeln Sie nur die Quellsprache und laden Sie die anderen, wenn sie zum ersten Mal verwendet werden.
contentnoneMarkdown- und MDX-Dokumente für localize-dev-Inhalte: { "include": ["docs/**/*.md"], "output": "{dir}/{name}.{locale}{ext}" }.

GitHub-Aktion

Die Aktion läuft im CI gleich ab und öffnet einen Pull-Request gegen den Branch, der sie ausgelöst hat. Wiederholungen aktualisieren denselben Branch und PR. Speichern Sie vor dem ersten Lauf Ihren API-Schlüssel im Repository:

  1. 1

    Kopieren Sie Ihren API-Schlüssel

    Es beginnt mit ldv_live_ und wird nur einmal angezeigt. Verloren? Erstellen Sie eine neue auf der API-Schlüssel Seite.
  2. 2

    Öffnen Sie die Actions-Geheimnisse des Repositorys

    Auf GitHub öffnen Ihr Repository und gehe zu Einstellungen → Secrets und Variablen → Aktionen, dann klicken Neues Repository-Geheimnis. Sie benötigen Admin-Zugriff auf das Repository, um Einstellungen zu sehen.
  3. 3

    Fügen Sie das Geheimnis hinzu

    Name: LOCALIZEDEV_API_KEYGeheimnis: fügen Sie Ihren Schlüssel ein, ohne Leerzeichen oder Zeilenumbrüche. Klicken Sie dann auf Geheimnis hinzufügen. GitHub verdeckt den Wert ab diesem Zeitpunkt; zum Ändern aktualisieren Sie das Geheimnis.
  4. 4

    Ohne die localize.dev GitHub App: Erlauben Sie der Action, Pull Requests zu öffnen

    In Einstellungen → Aktionen → Allgemein, unter Workflow-Berechtigungen, markieren Erlaube GitHub Actions, Pull Requests zu erstellen und zu genehmigen und klicken Speichern. Ohne diese Option übersetzt der Lauf alles, scheitert aber beim Öffnen des Pull Requests. Ist die Option grau, muss ein Organisationsbesitzer sie zuerst unter Einstellungen → Actions → Allgemein freigeben.

Dann committen Sie den Workflow:

.github/workflows/localize.yml
name: Localize

on:
  push:
    branches: [main]
  pull_request:
    types: [opened, synchronize]
  workflow_dispatch: # "Run workflow" button in the Actions tab

permissions:
  contents: write # push the localize-dev/<branch> branch
  pull-requests: write # open or update the localization PR

# One run per branch at a time; a newer push supersedes the running one.
concurrency:
  group: localize-${{ github.head_ref || github.ref_name }}
  cancel-in-progress: true

jobs:
  localize:
    runs-on: ubuntu-latest
    timeout-minutes: 60
    # Skip localize.dev's own branches, and fork PRs (their token is read-only).
    if: >-
      !startsWith(github.head_ref || github.ref_name, 'localize-dev/') &&
      (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository)
    steps:
      - name: Checkout
        uses: actions/checkout@v5
        with:
          # On PRs, scan the branch itself rather than the merge commit.
          ref: ${{ github.head_ref || github.ref_name }}

      - name: Localize
        uses: ufortstephen/autolocalize-action@v1
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          api_key: ${{ secrets.LOCALIZEDEV_API_KEY }}
          target_locales: 'es,fr,de'
          # src_dir: 'src' # default: your framework's (src, app/views, resources/views, lib…)
          # locales_path: 'public/locales/{locale}/common.json' # default: your framework's
          # working_directory: 'apps/web' # monorepo: localize just this app

Andere Eingaben: src_dir, locales_path, base_branch, api_url, offline (keine Schlüssel erforderlich), workspaces (jede App in einem Monorepo), working_directory (eine App eines Monorepos), tms_pull / tms_push (mit tms_token: überprüfte Übersetzungen in den Pull-Request bringen, Quelldateien vom Standard-Branch hochladen), mode: translate (nur ausfüllen bestehende Sprachdateien). Ausgaben: pr_url, strings_count.

Jeder Lauf meldet sich zurück, wenn er fertig ist: Die Projektseite im Dashboard listet kürzliche Läufe mit Pull Request, ersetzten Strings, Übersetzungen pro Sprache und Fehler auf, falls einer auftrat.

Pull-Request-Vorschau

Möchten Sie es in Ihrem eigenen Code sehen, bevor Sie etwas einrichten? Verbinden Sie das Repository im Dashboard und wählen Sie Vorschau-Pull-Request öffnen auf seiner Seite. localize.dev liest den Standard-Branch, lokalisiert bis zu 200 Strings in die erste Sprache des Projekts auf dem Server und öffnet einen Pull-Request von localize-dev/preview. Es ist kein Workflow, API-Schlüssel oder Checkout erforderlich; die Strings zählen zu Ihrem Plan, und die Übersetzungen erscheinen im Reiter Überprüfung wie bei jedem Lauf. Es erneut auszuführen aktualisiert denselben Pull-Request.

In einem Monorepo wird jede App nacheinander lokalisiert, bis die 200 Strings erreicht sind. Dateien in Git LFS und Submodulen sind nicht im von GitHub bereitgestellten Archiv, daher werden sie ausgelassen, und ein sehr großes Repository wird nur teilweise gelesen; der Pull Request weist darauf hin. Die GitHub-Aktion hat kein Limit.

CI-Prüfung

localize-dev check Fehler (Exit-Code 1), wenn der Text noch fest codiert ist, eine Sprache keine Übersetzungen hat oder die Übersetzungen veraltet sind, weil sich ihr Englisch seitdem geändert hat (von localize.lock.json), und listet jede auf. Es meldet auch Schlüssel, die vom Code nicht verwendet werden (entfernen Sie sie mit localize-dev prune), Text in Stylesheets (content: "New"), Meldungen, die einen gespeicherten Wert unverändert anzeigen (Status: {{status}} zeigt „paid“) und, wenn eine Zielsprache von rechts nach links verläuft, links oder rechts angeheftete Stile, und next/font Schriftarten, denen die Buchstaben einer Zielsprache fehlen; diese führen nicht zum Fehlschlag der Prüfung. Ein Schlüssel, den der Code verwendet und der in der Quelldatei fehlt, führt zum Fehlschlag, da die Leute den Schlüssel selbst sehen würden. Er liest nur Dateien: kein API-Schlüssel, nichts wird gesendet. Auf GitHub Actions ist jedes Problem auch eine Anmerkung im Diff der Pull Request.

npx localize-dev check                      # both
npx localize-dev check --only strings       # hardcoded copy only
npx localize-dev check --only translations  # missing translations only
npx localize-dev check --json
npx localize-dev check --staged             # files staged for the next commit (pre-commit hook)
npx localize-dev check --changed            # files changed since the last commit, and new ones

Mit --files, --changed oder --staged prüft check nur diese Dateien: hartcodierte Texte und Schlüssel, die in der Quell-Locale-Datei fehlen. Es überspringt die projektweiten Prüfungen, sodass es in etwa einer Sekunde läuft, schnell genug für einen Pre-Commit-Hook oder einen After-Edit-Hook eines Agenten. run übernimmt dieselben Optionen.

Oder in einem Workflow, der bei Pull Requests ausgeführt wird, mit der Action:

.github/workflows/i18n-check.yml
on: pull_request
jobs:
  i18n:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: ufortstephen/autolocalize-action@v1
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          mode: check

Pseudo-Lokalisierung

Bevor Sie für eine einzelne Übersetzung bezahlen, sehen Sie, wo Ihr Layout bricht. --pseudo schreibt eine en-XA Sprache: Jede Nachricht ist akzentuiert, etwa 35 % länger (wie Deutsch oder Finnisch) und in Klammern, wobei Platzhalter und Tags exakt beibehalten werden, sodass die App wie mit einer echten Übersetzung läuft. Wechseln Sie dazu und suchen Sie nach abgeschnittenen Schaltflächen, überlaufenden Karten und allem ohne Klammern: Diese Texte sind immer noch fest codiert.

npx localize-dev run --pseudo         # en-XA: [Šáṽé çĥáñĝéš one two]
npx localize-dev run --pseudo rtl     # ar-XB: right to left
npx localize-dev translate --pseudo   # from existing locale files, code untouched

Kein Modell und kein Schlüssel: Es wird Ihr Kontingent nicht verwendet. Ihre echten Sprachen bleiben unverändert. Die Playground-Umgebung hat es auch, als das en-XA Sprache.

Daten, Zahlen & Geld

In React, React Native, Electron, Tauri, Solid, Vue und Svelte Apps werden auch hartcodierte Datumsangaben, Zahlen und Preise, die an ein bestimmtes Gebietsschema gebunden sind, neu geschrieben, sodass sie der Sprache der App folgen:

  • date.toLocaleDateString('en-US', …) und new Intl.NumberFormat('en-US') verwenden stattdessen die Sprache der App (ebenso wie Aufrufe ohne Locale, die die des Browsers verwenden).
  • `$${price}` und <span>${price}</span> werden zu einem Währungsformat, so dass $1,234.50 liest 1.234,50 $ auf Deutsch. €, £, ¥, ₹, ₦, CA$, A$ und andere Symbole werden ihrer Währung zugeordnet; ein bloßer $ ist USD, es sei denn "currency" in localize.config.json etwas anderes angibt.
  • In Vue-Vorlagen und Skripten stammt die Sprache von vue-i18n ($i18n.locale); in Svelte, von svelte-i18n $locale.

Daten von date-fns (format(d, 'MMM d, yyyy')), dayjs und moment werden zu Intl.DateTimeFormat mit denselben Teilen; relative Zeiten (formatDistance, fromNow) sind aufgelistet, damit Sie wechseln können zu Intl.RelativeTimeFormat. localeCompare und Groß- oder Kleinschreibung in JSX verwenden die Sprache der App (türkisches i). Listen folgen ebenfalls der Sprache: {tags.join(', ')} in JSX und ein `${xs.slice(0, -1).join(', ')} and ${xs[xs.length - 1]}` werden zu Intl.ListFormat, so erhält Japanisch 、 und Spanisch sein eigenes „y“. Pull Requests listen jede Änderung auf. Schalten Sie es aus mit "localizeFormats": false in localize.config.json. Next.js App Router-Apps bleiben vorerst unverändert, da ihre Client-Komponenten die Sprache über einen Provider erhalten.

Eine URL pro Sprache

Suchmaschinen indizieren jede Sprache, wenn sie eine eigene URL hat. In Next.js App Router-Apps wird das generierte proxy.ts (middleware.ts vor Next 16) dient /es/about mit dem /about Seite auf Spanisch, ohne Ihre Dateien zu verschieben, und <LanguageAlternates /> im Root-Layout fügt hinzu hreflang Links zwischen den Versionen. Unpräfixierte URLs folgen weiterhin dem lang Cookie und den Browser, und das Sprachmenü wechselt zwischen URL mit Präfix.

Nuxt-Apps erhalten @nuxtjs/i18n's prefix_except_default URLs mit useLocaleHead() in app.vue; setzen "siteUrl" für absolute Links. Statische Websites erhalten dasselbe von htmlPages. Eine App mit eigenem Proxy oder Middleware behält sie: Die Ausführung erklärt die beiden Header (x-localize-lang, x-localize-path) dort zu setzen.

Seitentitel und -beschreibungen folgen ebenfalls. Next.js export const metadata wird zu einem generateMetadata das den Übersetzer der Anfrage verwendet (eines Titels-Templates %s behalten), und ein bestehendes generateMetadata erhält t. In Single-Page-Apps (Vite React, Vue, Svelte, Angular, Solid), index.html's <title> und Beschreibung werden vom generierten Modul übersetzt und gesetzt, wenn sich die Sprache ändert; die Datei behält sie für den ersten Anstrich bei, wie sie geschrieben wurden.

Für Suchmaschinen erhält das Root-Layout auch eine kanonische Adresse und og:locale für die URL jeder Sprache, aus dem generierten i18n-seo.ts. app/sitemap.ts listet jede Seite mit einer festen Adresse (keine [slug]-Routen, Anmeldebereiche oder private Ordner) in jeder Sprache mit hreflang-Alternativen auf. Eine robots.ts-Datei verweist darauf. Beide werden nur geschrieben, wenn die App keines von beiden hat, und Sie können sie bearbeiten. Setzen Sie "siteUrl" damit die Sitemap vollständige Adressen hat. Wenn sie nicht gesetzt ist, kommt die Adresse von einer CNAME-Datei oder der Homepage in package.json, und auf Vercel, Netlify, Render oder Railway von der Adresse, die der Host dem Build gibt.

Astro-Layouts erhalten eine I18nHead-Komponente in ihrem Head, mit denselben Links und og:locale. SvelteKit 2.3 und neuer bedient jede Sprache unter ihrer eigenen Adresse über einen Reroute-Hook in src/hooks.ts, Routen benötigen also keinen [lang]-Ordner, und hooks.server fügt die Links zu jeder Seite hinzu. Beide erhalten eine sitemap.xml, die aus den Seiten- oder Routenordnern erstellt wird, sodass neue Seiten aufgelistet werden, ohne localize erneut auszuführen, und eine robots.txt, wenn die App keine davon hat.

Qwik City-Apps erhalten eine LanguageHead-Komponente in root.tsx mit denselben Links und denselben sitemap- und robots-Routen.

React Router-Apps (Framework-Modus) erhalten jede Route erneut unter jeder Sprache, sodass /es/about die About-Seite auf Spanisch ist. Die Routendatei übergibt ihre Routen über withLanguageRoutes von app/i18n-routes.ts, und das Root rendert jede Seite in der Sprache ihrer Adresse, mit denselben Links. Links ohne Sprache behalten die Sprache der Seite bei, und die Routen sitemap.xml und robots.txt werden hinzugefügt, wenn die App keine davon hat. Bei mehr als drei Sprachen werden die nicht im Bundle enthaltenen in der Route geladen, sodass der Server sie ebenfalls rendert.

Remix 2 Apps erhalten dasselbe, wenn v3_routeConfig in vite.config aktiviert ist und die Routen in app/routes.ts (Remix's Routenkonfiguration). Ohne sie sagt der Lauf, was geändert werden muss.

Statische Websites mit htmlPages und siteUrl erhalten auch eine sitemap.xml, die jede Seite in jeder Sprache auflistet, und eine robots.txt, wenn keine vorhanden ist.

Die Sprache des Besuchers wird exakt, nach Sprache oder nach einer regionalen Variante, die die App anbietet, abgeglichen: ein Browser, der auf pt-PT erhält das pt-BR.

Um zu sehen, was Suchmaschinen sehen, richten Sie localize-dev seo auf die Website. Es funktioniert auf jeder Website, egal ob von localize.dev eingerichtet oder nicht.

npx localize-dev seo https://example.com     # the live site
npx localize-dev seo http://localhost:3000   # a local build, before you deploy

Es liest robots.txt und die Sitemap, lädt dann jede Seite und die Seiten, die seine hreflang-Links benennen. Es meldet Seiten, die nicht laden oder weiterleiten, hreflang-Links ohne die vollständige Adresse oder ohne x-default, eine Sprache, deren Seite nicht zurückverlinkt, ein <html lang> oder og:locale, das nicht mit der Sprache der Seite übereinstimmt, und ein kanonischer Link, der woanders hinzeigt. Adressen auf einem anderen Ursprung (siteUrl, wenn Sie einen lokalen Build überprüfen) werden von der von Ihnen angegebenen Adresse geladen.

Übersetzungen überprüfen

Maschinelle Übersetzungen von GitHub Action-Läufen und CLI-Pull-Requests (pr, pr --translate) erscheinen auf dem Überprüfen Registerkarte, Quelle und Übersetzung nebeneinander, nach Sprache filterbar. Genehmigen Sie sie einzeln oder alle auf einmal, oder bearbeiten Sie eine: Eine Bearbeitung muss die Platzhalter der Quelle beibehalten und ersetzt den Eintrag im Translation Memory des Arbeitsbereichs, sodass jede spätere Ausführung die Korrektur verwendet. Pluralnachrichten zeigen jede Form an, die die Sprache benötigt (das russische one, few, many…) und werden Form für Form bearbeitet.

Änderungen an Pull Request anwenden committet Ihre Änderungen an die offene Lokalisierungs-Pull-Request des Laufs, aus dem sie stammen, in ihren JSON-Locale-Dateien über die GitHub App. Änderungen, die nicht platziert werden können (andere Dateiformate oder eine zusammengeführte Pull-Request), erreichen den nächsten Lauf über das Translation Memory.

Jede Übersetzung behält einen Thread von Notizen für den nächsten Prüfer und zeigt an, wer ihn wann genehmigt oder bearbeitet hat. Wenn dieselbe Korrektur immer wieder vorkommt, schlägt die Registerkarte einen Glossarbegriff: ein Quellwort, das immer auf eine bestimmte Weise übersetzt werden sollte (checkout → pago), oder ein Name, den Prüfer immer wiederherstellen und der unverändert bleiben soll. Ein Klick fügt ihn dem Projektglossar hinzu, dem jeder Lauf folgt.

Weisen Sie ein Prüfer pro Sprache von den Mitgliedern des Arbeitsbereichs. Wenn ein Lauf neue Übersetzungen in ihrer Sprache bringt, erhalten sie eine E-Mail für den Lauf mit einem Link zur Registerkarte. Jede Zeile verknüpft mit der Quelldatei, aus der sie stammt, auf GitHub. Das Modell kennzeichnet Übersetzungen, bei denen es sich nicht sicher ist (ein mehrdeutiges Wort, eine Redewendung, eine formelle oder informelle Vermutung) mit seinem Grund, und die Registerkarte öffnet sich bei diesen, unter Muss geprüft werden; Die restlichen genehmigen überlässt sie einer Person. Im Code zeigt die Zeilen um die Stelle, an der sie verwendet wird, aus dem Pull Request des Laufs gelesen, damit der Text dort überprüft werden kann, wo er angezeigt wird.

Glossar

Jedes Projekt hat ein Glossar auf seiner Dashboard-Seite: Begriffe, die niemals übersetzt werden dürfen (Marken- und Produktnamen), bevorzugte Übersetzungen für Ihren Wortschatz und ein Stilhinweis wie „informell; verwenden Sie du auf Deutsch“. Es gilt für jede Anfrage von den GitHub Action- und CLI-Läufen des Projekts. Übersetzungen, die einen niemals zu übersetzenden Begriff ändern, werden abgelehnt; bevorzugte Übersetzungen und der Stilhinweis leiten das Modell.

Pläne & Limits

PlanZeichenketten / MonatSprachen
Free1.0003
ProUnbegrenzt5
TeamUnbegrenztUnbegrenzt

Ein String zählt einmal, egal in wie viele Sprachen er übersetzt wird. Kontingente laufen in 30-Tage-Perioden: ab dem Tag, an dem Ihr Arbeitsbereich erstellt wurde, oder ab Ihrem Abrechnungsdatum bei einem bezahlten Plan. Das Dashboard zeigt an, wann Ihres zurückgesetzt wird. Das Sprachlimit zählt jede Sprache, in die in den letzten 30 Tagen übersetzt wurde, über alle Arbeitsbereiche und Projekte hinweg. Wenn ein Lauf das Kontingent oder das Sprachlimit überschreiten würde, stoppt er, bevor etwas geschrieben wird, erklärt warum und beendet sich mit dem Code 2, damit die CI fehlschlägt, anstatt eine halbe Übersetzung zu committen.

Sprachen

localize.dev übersetzt in jede Sprache, die das Unicode-CLDR kennt, mehr als 600, geschrieben als BCP-47-Code: eine Sprache (es, ja, sw), mit Schrift oder Region, wo es darauf ankommt (zh-Hant, sr-Latn, pt-BR, es-419). Es gibt keine Liste zur Auswahl: Legen Sie sourceLocale und targetLocales in localize.config.json fest oder übergeben Sie --locales.

Ein Code, der keine Sprache bezeichnet, wird abgelehnt, bevor etwas übersetzt wird, mit dem, was vermutlich gemeint war: jp → ja, cn → zh. Jeder gültige Code wird angenommen, auch Aliase wie en-UK (gelesen als en-GB) und Codes zur privaten Nutzung. CLI, GitHub Action, Dashboard und API prüfen gleich.

  • In wie viele Sprachen ein Lauf übersetzen kann, hängt von Ihrem Tarif ab. Ein Text zählt einmal, egal in wie viele Sprachen er geht.
  • Übersetzungen sind in weit verbreiteten Sprachen am stärksten. Lassen Sie bei Sprachen mit wenig Text im Netz den Pull Request von Muttersprachlern prüfen und legen Sie ein Glossar mit den Begriffen Ihres Produkts an.
  • Jede Sprache, deren Schrift von rechts nach links läuft (Arabisch, Hebräisch, Persisch, Urdu, Kurdisch, Paschtu, Syrisch, N’Ko und weitere), bekommt dir="rtl" und die Prüfung von Links/Rechts-Stilen. Auch ein Code, der seine Schrift nennt, zählt: pa-Arab.
  • Pluralformen folgen den eigenen Formen jeder Sprache (one, few, many…) aus dem CLDR, sodass Polnisch, Arabisch oder Walisisch alle bekommen, die sie brauchen.
  • Die Pseudo-Sprachen en-XA (mit Akzenten und länger) und ar-XB (von rechts nach links) brauchen weder Modell noch Schlüssel.

Pluralformen & Rich Text

Eine mengenabhängige Auswahl wie {n} {n === 1 ? 'file' : 'files'} left wird zu einer Nachricht (auch n > 1 ? …, rules.select(n) === 'one' ? … und Helfer wie plural(n, 'file', 'files')), umgeschrieben zu t('files.left', { count: n }). Jede Sprache erhält genau die Formen, die sie benötigt (Spanisch drei, Polnisch vier, Arabisch sechs), geschrieben als files.left_one, files.left_few... für i18next oder eine ICU-Pluralnachricht, und i18next wählt zur Laufzeit die richtige aus.

Ein Satz mit zwei Zählungen, {files} {files === 1 ? 'file' : 'files'} in {folders} {folders === 1 ? 'folder' : 'folders'}, wird zu einer Nachricht pro gezählter Phrase ({{count}} file / {{count}} files) in einem Satz platziert, {{files}} in {{folders}}, sodass jede Zählung ihre eigenen Formen erhält und Übersetzer sie immer noch neu anordnen können. Ordnungszahlen von Helfern wie ordinal(place) oder {n}{ordinalSuffix(n)} werden zu i18next Ordnungspluralen (t('rank.place', { count: place, ordinal: true })), mit den eigenen Ordnungsformen jeder Sprache: Englisch 1st/2nd/3rd/4th, Französisch 1re/2e, Spanisch 1.º.

Dasselbe funktioniert auch außerhalb von React: ICU-Nachrichten (Svelte, Ember) erhalten ein selectordinal, vue-i18n erhält key_ordinal_one, und in Vue, Svelte, Astro, Lit, Ember, Flutter und Rails wird jede gezählte Phrase zu einem eigenen Pluralaufruf innerhalb des Satzes. Intl.PluralRules... Schlüssel, ausgewählt von

Text um einfache Inline-Elemente, wie Read the <a href="/docs">docs</a> first, wird zu einer einzigen Nachricht (Read the <a>docs</a> first) gerendert mit <Trans>, damit Übersetzer den Link verschieben können. Das Element behält seine Props. Übersetzungen, die ein Tag verlieren oder umbenennen, werden abgelehnt.

Frameworks ohne ein <Trans> erhalten dasselbe, wobei der eigene Text des Elements als eigene Nachricht behandelt wird: Vue über <i18n-t> mit Slots, Svelte über ein generiertes <I18nT> (Snippets in Svelte 5, ein Slot in 3 und 4), Angular über ein generiertes <i18n-t> mit ng-template Slots (ein NgModule vor Angular 14), Ember über ein generiertes <I18nT>, Solid und Qwik durch rich(). In Rails ist ein link_to innerhalb eines Satzes wird in eine _html Nachricht, sodass ihre Markup beibehalten wird.

Was übersetzt wird

  • JSX-Text, mit Text und einfachen Ausdrücken zu einer Nachricht zusammengeführt: Hi {user.name}! → Hi {name}!
  • Attribute in der Zulassungsliste (Platzhalter, alt, Titel, aria-label, aria-description, aria-valuetext, aria-roledescription, Label, Tooltip; konfigurierbar), und eine SVG <title> und <desc>
  • Zeichenketten und Template-Literale in JSX gerendert, einschließlich beider Zweige von a ? 'X' : 'Y' und die rechte Seite von &&
  • Kopieren in Konstanten die Komponenten lesen (const NAV = [{ label: 'Home' }] mit NAV.map((n) => n.label)): die Strings werden zu Schlüsseln und jede Lesung wird zu t(n.label)
  • Verbundene Strings ('Hi ' + name + '!') als eine Nachricht, und Nachrichten, die an State-Setter, Toasts übergeben werden, alert und zod oder yup Validierung (z.string().min(1, 'Required'))
  • Komponenten-Props, die Text enthalten (<EmptyState heading="No orders yet" />, von Vue empty-text="…"), Nachschlagetabellen, die nach Schlüssel gelesen werden (STATUS_LABELS[order.status]), Hilfsfunktionen, deren Ergebnisse gerendert werden, und Kopien, die aus einem einfachen Modul importiert werden (nav.ts), deren Strings dort zu Schlüsseln werden, wenn jede Komponente, die sie importiert, verfolgt werden kann
  • Geschlechtsspezifische Sätze (gender === 'female' ? 'She…' : 'He…') als eine Nachricht mit einer Variante pro Geschlecht, sodass jede Sprache sie auf ihre eigene Weise formuliert
  • Vue- und Svelte-Vorlagen (Vue in HTML oder Pug): Text, {{ }} und { } Ausdrücke, Attribute (einschließlich title="Hi {name}"), und die Strings, die eine Expression rendert, wie {{ saving ? 'Saving…' : 'Save' }}
  • Vue- und Svelte-Skripte: Nachrichten, die angezeigt, übergeben werden alert, confirm, Toasts und Benachrichtigungen, oder zugewiesen an document.title, und Konstanten, die die Vorlage zeigt (const tabs = [{ label: 'Home' }] mit {{ tab.label }}): die Strings werden zu Schlüsseln und die Vorlage liest sie durch $t() oder $_()
  • Statisches HTML: Elementtext, Sätze um Inline-Elemente als eine Nachricht, und die gleichen Attribute. Text aus einer Template-Engine oder PHP bleibt unberührt und wird gemeldet.

Nie übersetzt: URLs und Pfade, Farben, UUIDs, CSS-Einheiten, E-Mails, Dateinamen, snake_case oder kebab-case Bezeichner, nur Symbole und alles innerhalb <code>, <pre>, <Trans>, translate="no" oder data-i18n-ignore.

Jede Übersetzung wird vor dem Schreiben überprüft: eine, die hinzufügt, entfernt oder umbenennt {placeholder} wird abgelehnt. Bestehende Übersetzungen in Ihren Wörterbüchern werden niemals überschrieben.

Rechts nach links

Arabisch, Hebräisch, Persisch und Urdu werden von rechts nach links gelesen, daher ml-4 oder margin-left landet auf der falschen Seite. Wenn die Zielsprache rechtsbündig ist, check Listenstile, die links oder rechts fixiert sind, und localize-dev rtl --fix tauscht die mit einem logischen Äquivalent aus, das in Englisch gleich aussieht :

  • Tailwind : ml-/mr- → ms-/me-, pl-/pr- → ps-/pe-, text-left → text-start, abgerundete Ecken und Borden, mit Varianten wie md: bleiben erhalten.
  • CSS : margin-left → margin-inline-start, padding-right → padding-inline-end, text-align: left → start, Borden und Eckradien.

left-/right- Positionen und Floats werden nur gemeldet, da sie oft Zentrierungstricks sind. Überprüfen Sie das Ergebnis in ar-XB mit localize-dev run --pseudo rtl.

Dokumentation und Inhalte

Dokumentation, Blogbeiträge und Rechtstexte werden als ganze Dokumente übersetzt. localize-dev content übersetzt Markdown- und MDX-Dateien in eine Kopie pro Sprache: Fließtext, Überschriften, Listenelemente, Tabellenzellen sowie Front-Matter-Titel und Beschreibungen werden übersetzt; Codeblöcke, Inline-Code, Link-URLs, MDX-Importe, Komponenten und Ausdrücke bleiben genau so, wie sie geschrieben sind. Ein Abschnitt, dessen Übersetzung eines dieser Elemente verliert, wird auf Englisch belassen und gemeldet.

localize.config.json
{
  "targetLocales": ["es", "fr"],
  "content": {
    "include": ["docs/**/*.md", "blog/**/*.mdx"],
    "output": "{dir}/{name}.{locale}{ext}"
  }
}

Der Standardausgang befindet sich neben jeder Datei (intro.es.md) wie Nextra, Fumadocs und Hugo erwarten. Für Docusaurus verwenden Sie "i18n/{locale}/docusaurus-plugin-content-docs/current/{path}". Dokumente, die seit ihrer Erstellung unverändert sind, werden übersprungen (ihre Fingerabdrücke sind in localize.lock.json), sodass nur die bearbeiteten Dokumente erneut übersetzt werden.

Datenschutz & Daten

  • Nur die extrahierten Strings werden an die API gesendet, zusammen mit ihrem Dateipfad und Komponente als Kontext. Ganze Dateien werden niemals gesendet.
  • Scans und Offline-Läufe verlassen Ihre Maschine niemals.
  • Der CLI überschreibt Dateien lokal; der GitHub Action führt Commits mit Ihrem eigenen Runner und Ihrem eigenen Token aus.
  • API-Schlüssel werden als Hashes gespeichert; das Geheimnis wird nur einmal angezeigt.

Einschränkungen

  • Flüssiger Text unterstützt inline-Elemente bis zu drei Ebenen tief (fetter Text innerhalb eines Links wird zu einer verschachtelten Nachricht). Der Link selbst title, handschriftlich geschrieben oder aus dem Code gesetzt, bleibt innerhalb des Satzkomponenten in React.
  • Pluralformen werden aus zwei String-Optionen basierend auf der Anzahl erkannt (===/!== 1, > 1, < 2, Intl.PluralRules) und Plural-Hilfsmittel mit einer Zahl und beiden Formen. Jedes Framework extrahiert Pluralformen nach seiner eigenen Konvention (Djangos pluralize, Laravels Str::plural, Kotlins if … else) und schreibt sein eigenes Format (<plurals>, String-Katalog-Variationen, msgid_plural, trans_choice; Angular, das keine hat, wählt den Schlüssel mit einem generierten pluralForm pipe). Ein Satz mit mehreren Zählungen erhält überall ein Plural pro Zählung außer bei Django (dessen blocktranslate nimmt eine) und iOS; Ordinalzahlen funktionieren in den JavaScript-Frameworks und Angular, nicht in Flutter, Rails, Django, Laravel, Android oder iOS, deren i18n-Bibliotheken keine Ordinalformen haben. Auf iOS benötigt ein Plural seine Zahl im Text ("\(n) items"), wonach sich der String-Katalog unterscheidet.
  • Klassenkomponenten werden übersetzt: über withTranslation() wenn die Klasse der Standardexport der Datei ist, andernfalls mit render() läuft in <Translation>. Konstruktoren, statische Member und Ereignishandler verwenden i18next's t, sodass der vom Konstruktor gespeicherte Text der Sprache beim Mounten folgt.
  • In Vue- und Svelte-Skripten ist die extrahierte Kopie das, was deutlich angezeigt wird: alert, confirm, Toasts und Benachrichtigungen, document.title, und Konstanten, die die Vorlage anzeigt (eine Zeichenkette, ref('…'), die Werte eines Objekts oder einer Liste label/title Felder, an übersetzte Kindkomponenten übergeben), und was computed(), Funktionen, $: und $derived Rückgabe. Eine Zeichenkettenkonstante, die das Skript selbst verwendet, behält ihren Text, da das Skript sie vergleichen oder senden kann. In Svelte 4 wird der Text, den eine Funktion zurückgibt, beim nächsten Rendern der Komponente nach einem Sprachwechsel aktualisiert.
  • Vue-Vorlagen in Pug werden übersetzt, #[…] Inline-Tags (drei tief) und #{} Werte enthalten. Vorlagen in anderen Präprozessoren (selten außerhalb von Pug) werden übersprungen und gemeldet.
  • Kopien außerhalb von Komponenten (E-Mails, SVG-Text, serverseitige Nachrichten) werden nicht extrahiert; Markdown- und MDX-Dokumente werden vollständig übersetzt mit localize-dev content.
  • Der Vorschau-Pull-Request liest die Dateien des Standard-Branches; Git LFS-Dateien und Submodule werden ausgelassen.