Rails-Internationalisierung (i18n): Der vollständige Leitfaden
Konfigurieren Sie Rails I18n, organisieren Sie config/locales/*.yml, automatisieren Sie YAML-Übersetzungen mit KI und lassen Sie PTC (Private Translation Cloud) Ihre laufende Rails-App bei jedem Release prüfen. Am Ende verfügen Sie über eine Rails-App, die auf /es/...-URLs reagiert, übersetzte Views in über 40 Sprachen bereitstellt und durch eine visuelle Prüfung verifiziert ist.
Dieser Leitfaden setzt voraus, dass Sie eine bestehende Rails 7+-App haben. Die Konzepte gelten mit geringfügigen API-Unterschieden auch für ältere Rails-Versionen. Das I18n-Gem selbst ist seit Jahren stabil. Informationen zur umfassenderen CI/CD-Lokalisierung über verschiedene Stacks hinweg finden Sie unter KI-Software-Lokalisierung für CI/CD-Pipelines.
Rails konfigurieren: Locales laden, URLs erkennen und pro Request umschalten
Die Rails-Internationalisierung erfordert drei Konfigurationsschritte. Legen Sie die verfügbaren Locales fest, fügen Sie das Locale zu Ihren URLs hinzu und lassen Sie Rails das korrekte Locale pro Request laden. Zudem installieren Sie das Gem rails-i18n für die Locale-Daten.
Verfügbare Locales in config/application.rb deklarieren
Geben Sie in config/application.rb an, welche Sprachen die App unterstützt, und legen Sie einen Standard fest:
module MyApp
class Application < Rails::Application
config.i18n.available_locales = [:en, :es, :fr, :de, :ja]
config.i18n.default_locale = :en
config.i18n.fallbacks = true
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
end
end
Die Zeile load_path += Dir[...] ist entscheidend. Standardmäßig lädt Rails nur config/locales/*.yml (eine Ebene tief). Durch das Hinzufügen des rekursiven Globs können Sie Übersetzungen nach Namespace, Model oder Feature in Unterverzeichnissen organisieren.
Fügen Sie :locale zu Ihrem URL-Scope hinzu
Fügen Sie einen :locale-Scope hinzu, damit jede Sprache ihren eigenen Pfad hat, wie /en/time oder /de/time:
# config/routes.rb
scope "/:locale" do
get '/time', to: 'home#index', as: :time_display
end
Locale pro Request mit I18n.with_locale umschalten
Laden Sie im ApplicationController das richtige Locale aus der URL und binden Sie es in alle generierten Links ein:
class ApplicationController < ActionController::Base
around_action :switch_locale
def switch_locale(&action)
locale = params[:locale] || I18n.default_locale
I18n.with_locale(locale, &action)
end
def default_url_options
{ locale: I18n.locale }
end
end
I18n.with_locale ist der idiomatische Weg, um ein Locale auf einen Request zu begrenzen. Es setzt das Locale, führt den Block aus, stellt das vorherige Locale wieder her und ist threadsicher. default_url_options stellt sicher, dass jede von Rails generierte URL das aktuelle Locale enthält, damit Benutzer beim Navigieren in der gewählten Sprache bleiben.
Installieren Sie rails-i18n für übersetzte Monatsnamen und Pluralisierungsregeln
Das Gem rails-i18n liefert Locale-Daten für Dutzende von Sprachen. Dieses Gem enthält übersetzte Monatsnamen, Pluralisierungsregeln und Standard-Fehlermeldungen von Rails. So müssen Sie diesen Standardtext nicht selbst übersetzen.
# Gemfile
gem 'rails-i18n'
bundle install
Ihre Rails-App ist nun vollständig für die Internationalisierung konfiguriert.
Einen Sprachumschalter mit url_for(locale: :code) hinzufügen
Da default_url_options das Locale automatisch in jede generierte URL einfügt, muss Ihr Umschalter lediglich den Parameter :locale aktualisieren, während der Benutzer auf derselben Seite bleibt.
<%# app/views/layouts/application.html.erb %>
<nav class="language-switcher">
<%= link_to "English", url_for(locale: :en) %> |
<%= link_to "Español", url_for(locale: :es) %> |
<%= link_to "Deutsch", url_for(locale: :de) %>
</nav>
Jeder Link verwendet url_for(locale: :code), um eine URL mit dem angegebenen Locale zu generieren. Wenn Benutzer klicken, erkennt switch_locale im ApplicationController die Änderung und Rails rendert die Seite in der neuen Sprache.
Hardcodierten Text in Views durch t(:key) ersetzen
Hardcodierter Text erscheint nicht in Ihren YAML-Dateien, was bedeutet, dass er nicht übersetzt werden kann. Verwenden Sie für alle für Benutzer sichtbaren Texte immer Übersetzungsschlüssel.
<%# Correct - uses translation keys %>
<h1><%= t(:hello) %></h1>
<p><%= t(:current_time, time: @time) %></p>
<button id="click-me"><%= t(:refresh) %></button>
<%# Incorrect - hardcoded text %>
<h1>Hello</h1>
<p>Current time: <%= @time %></p>
<button>Refresh</button>
In Controllern (für Flash-Meldungen):
def create
if @post.save
redirect_to @post, notice: t('flash.post.created')
else
flash.now[:alert] = t('flash.post.error')
render :new, status: :unprocessable_entity
end
end
In Models (verwenden Sie für Validierungsmeldungen die Active Model-Konventionen):
# config/locales/en.yml
en:
activerecord:
attributes:
post:
title: "Title"
errors:
models:
post:
attributes:
title:
blank: "is required"
Variablen mit %{name} interpolieren
%{name} im YAML wird durch den Wert ersetzt, den Sie an t() übergeben:
current_time: "Current time: %{time}"
<%= t(:current_time, time: @time) %>
Lazy Lookup (.key) für View-bezogene Übersetzungen verwenden
Wenn Ihre Übersetzungsschlüssel so organisiert sind, dass sie Ihrer View-Ordnerstruktur entsprechen, verwenden Sie einen führenden Punkt. Rails ergänzt das Präfix der aktuellen View:
<%# Instead of this: %>
<%= t('home.index.hello') %>
<%# Use this: %>
<%= t('.hello') %>
Rails erkennt, dass Sie sich in home/index.html.erb befinden, und stellt home.index. voran. Wenn Sie eine View umbenennen oder verschieben, werden die Lazy-Lookup-Pfade automatisch aktualisiert.
config/locales/ nach Features organisieren statt einer riesigen en.yml
In einer echten App wird eine einzige riesige en.yml unübersichtlich. Organisieren Sie diese pro Feature:
config/locales/
en.yml # global / shared keys
models/
post.en.yml
views/
posts.en.yml
home.en.yml
flash.en.yml
Ein Beispiel für config/locales/views/posts.en.yml:
en:
posts:
index:
title: "All Posts"
empty: "No posts yet"
new:
title: "Create a New Post"
show:
published_at: "Published %{date}"
comments_count:
zero: "No comments yet"
one: "1 comment"
other: "%{count} comments"
Konventionen:
- Verschachtelte Schlüssel gruppieren zusammengehörige Strings und ermöglichen Lazy Lookup.
%{name}-Interpolation für Inline-Variablen.zero/one/otherPluralisierungs-Schlüssel für zählbare Substantive. Rails leitet basierend aufcount:zum richtigen Schlüssel weiter:t('posts.show.comments_count', count: 5).
JavaScript-Strings ebenfalls zum YAML hinzufügen
Rails extrahiert Text nicht automatisch aus JavaScript-Dateien. Jeder clientseitige Text (Warnungen, Tooltips, Bestätigungsmeldungen) muss in Ihrem YAML stehen, damit er zusammen mit allem anderen übersetzt wird:
en:
confirm: "Are you sure?"
Wenn Sie im nächsten Abschnitt mit PTC übersetzen, werden diese Strings zusammen mit den restlichen übertragen.
config/locales/*.en.yml mit PTC in 4 Schritten übersetzen
Sobald Ihre Übersetzungsdateien vorhanden sind, benötigen Sie Versionen für jede Zielsprache. PTC übernimmt dies:
- Starten Sie ein PTC-Projekt und wählen Sie Englisch als Ausgangssprache. Die kostenlose Testphase deckt 20.000 Wörter in 2 Sprachen ab, keine Kreditkarte erforderlich.
- Laden Sie Ihre
config/locales/*.en.yml-Dateien hoch. PTC parst das YAML, erkennt Rails-Pluralisierungsschlüssel (zero,one,other,few,many) und bewahrt%{name}-Interpolationen. - Fügen Sie eine kurze Beschreibung Ihrer Rails-App und Zielgruppe hinzu. PTC nutzt diesen Kontext, um mit der richtigen Tonalität und Terminologie zu übersetzen.
- Wählen Sie die Zielsprachen aus und bestätigen Sie. PTC erstellt
posts.es.yml,posts.fr.yml,posts.de.yml, die strukturell identisch mit der Quelle sind, aber übersetzte Werte enthalten. Pluralformen werden pro Sprache generiert. Polnisch erhältone/few/many/other. Japanisch erhält nurother.
Kopieren Sie die Dateien zurück nach config/locales/views/, starten Sie Ihren Rails-Server neu, und die App stellt die neuen Sprachen bereit.
Bei Git-gesteuerten Projekten verknüpfen Sie PTC mit Ihrem Repository. Neue Strings in einer beliebigen *.en.yml lösen eine automatische Übersetzung aus. PTC öffnet einen Pull Request mit den aktualisierten Zielsprachdateien. Den Synchronisations-Flow finden Sie in der PTC API-Referenz.
I18n.with_locale in Background-Jobs, Mailern und Cron-Tasks verwenden
Das Muster I18n.with_locale(locale, &block) ist entscheidend für jeden Code, der außerhalb eines normalen Requests läuft. Dazu gehören Background-Jobs, Cron-Tasks und Mailer.
# Background job: send an email in the user's preferred locale
class WelcomeEmailJob < ApplicationJob
def perform(user_id)
user = User.find(user_id)
I18n.with_locale(user.preferred_locale) do
UserMailer.welcome(user).deliver_now
end
end
end
Ohne with_locale läuft der Job in dem Locale, das beim Start des Workers aktiv war. Meistens ist dies :en, unabhängig von der Präferenz des Benutzers. Mit dieser Methode wird die E-Mail in der Sprache des Benutzers gerendert und das Locale wird nach Abschluss des Blocks zurückgesetzt.
Rails-Übersetzungen mit i18n-js für die clientseitige Nutzung nach JSON exportieren
Von Rails gerenderte Seiten erhalten Übersetzungen über t() in ERB. JavaScript, das im Browser läuft, sieht das I18n von Rails nicht direkt. Das sauberste Muster verwendet das Gem i18n-js, um Übersetzungen als JSON zu exportieren und sie clientseitig zu laden.
# Gemfile
gem 'i18n-js'
bundle install
i18n init
Aktualisieren Sie die generierte Konfiguration, um Übersetzungen nach public/locales.json zu exportieren:
# config/i18n.rb
require "i18n-js"
I18n::JS.config do |config|
config.export_i18n_js = false
config.translations_path = "public/locales.json"
end
Generieren Sie die JSON-Datei:
i18n export
Dies liest alle Ihre YAML-Dateien (en.yml, es.yml, de.yml) und schreibt public/locales.json mit jeder Übersetzung in einem für JS lesbaren Format.
Pinnen Sie i18n-js mit Rails 7+ Importmap:
# config/importmap.rb
pin "i18n-js", to: "https://esm.sh/i18n-js@latest/dist/import/index.js"
pin "load_locale", to: "load_locale.js"
Erstellen Sie einen Loader:
// app/javascript/load_locale.js
export async function loadLocale() {
const response = await fetch('/locales.json');
return await response.json();
}
Übergeben Sie das aktuelle Locale über den <body>-Tag an JavaScript:
<%# app/views/layouts/application.html.erb %>
<body data-locale="<%= I18n.locale %>">
Verwenden Sie dann die Übersetzungen in Ihrem JavaScript:
// app/javascript/application.js
import { I18n } from "i18n-js";
import { loadLocale } from "./load_locale";
document.addEventListener('turbo:load', async () => {
const translations = await loadLocale();
const i18n = new I18n(translations);
i18n.locale = document.body.dataset['locale'];
if (confirm(i18n.t('confirm'))) {
// User clicked OK
}
});
i18n.t() funktioniert wie der t-Helper von Rails. Wenn Benutzer die Sprache wechseln, verwendet JavaScript die korrekten Übersetzungen aus dem Attribut data-locale.
ActiveRecord-Inhalte mit der PTC API übersetzen
Das obige Muster übersetzt statische Strings in Ihren YAML-Dateien. ActiveRecord-Inhalte (Benutzer-Posts, Kommentare, Produktbeschreibungen, die als Benutzereingabe gespeichert sind) erscheinen nicht im YAML und erfordern einen anderen Ansatz. Die PTC REST API übersetzt diese Inhalte bei Bedarf mit Bearer-Token-Authentifizierung und verwendet dabei dasselbe Glossar und dieselbe Markenstimme wie Ihre config/locales/*.yml-Dateien. Senden Sie Ihre Inhalte per POST an PTC und erhalten Sie entweder einen Callback, wenn die Übersetzungen fertig sind, oder fragen Sie den Status über einen Background-Job ab.
Datum, Zahlen und Währung mit Rails-Helpern lokalisieren
Datum und Uhrzeit. Verwenden Sie den l-Helper (kurz für localize):
<%= l Time.now, format: :long %>
Das Gem rails-i18n bietet Standardformate für Datum und Uhrzeit für viele Sprachen, einschließlich übersetzter Monatsnamen und lokaler Formatierung. Sie können in Ihren YAML-Dateien benutzerdefinierte Formate definieren.
Zahlen und Währung. Rails enthält Locales-bewusste Helper:
<%= number_to_currency(100, locale: :es) %> <!-- 100,00 € -->
<%= number_with_delimiter(1000000) %> <!-- 1,000,000 -->
Diese berücksichtigen die Locale-Konventionen für Dezimaltrennzeichen, Tausendertrennzeichen und Währungssymbole.
Lokalisierte Views pro Sprache. Erstellen Sie für Seiten mit deutlich unterschiedlichem Inhalt pro Locale separate View-Dateien. Rails rendert die entsprechende View basierend auf dem aktuellen Locale:
app/views/pages/
about.html.erb <!-- Default -->
about.es.html.erb <!-- Spanish version -->
about.de.html.erb <!-- German version -->
Visuelle Übersetzungsprüfung Ihrer laufenden Rails-App – Release ohne manuelle QA pro Release
Nachdem PTC Ihre config/locales/*.yml übersetzt hat, muss die gerenderte Rails-App noch verifiziert werden. Ein übersetztes Label könnte auf Deutsch über die Grenzen eines Buttons hinausragen (Überlauf). Eine französische Validierungsmeldung könnte die falsche grammatikalische Form verwenden. Ein hardcodierter englischer String in einem ERB-Template (ohne t()-Aufruf) wird unübersetzt gerendert, egal in wie viele Sprachen Sie übersetzen.
Die AI Visual QA von PTC ersetzt den manuellen QA-Durchgang. Installieren Sie für Rails-Apps (browserbasiert) die PTC Browser-Erweiterung und zeichnen Sie einen Rundgang durch die kritischen Bildschirme Ihrer App auf (Anmeldung, Haupt-Flows, Admin-Seiten). Von da an spielt PTC die Aufzeichnung nach jedem Übersetzungs-Update in jeder Zielsprache ab, erfasst jeden Bildschirm und meldet zurück:
- Korrekturen in den YAML-Dateien, wenn PTC diese kontrolliert. PTC korrigiert Fehlübersetzungen, wählt ein kürzeres Synonym oder generiert eine Pluralform neu.
- Cursor / Claude Code Prompts, wenn das Problem in Ihrem Ruby- oder ERB-Code liegt. Ein hardcodierter englischer String außerhalb von
t(), eine Flash-Meldung, die durch Konkatenation statt Interpolation erstellt wurde, oder ein Helper, derI18n.lfür die Datumsformatierung verwenden sollte.
Das Ergebnis: eine verifizierte mehrsprachige Rails-App pro Release. Nicht nur übersetztes YAML.
Release Notes, Devise-Mailer und Marketing-Seiten übersetzen
Ihre Release Notes, kundenorientierte E-Mails, die über Devise oder Action Mailer versendet werden, und Marketing-Seiten befinden sich außerhalb von config/locales. Die Funktion Paste to Translate von PTC verarbeitet diese Texte im selben Projekt. Fügen Sie den Ausgangstext im PTC-Dashboard ein, wählen Sie die Zielsprachen aus und erhalten Sie Übersetzungen zurück, die dasselbe Glossar und dieselbe Markenstimme wie Ihre YAML-Übersetzungen verwenden.
Übersetzen Sie Ihre config/locales/*.yml-Dateien mit PTC
Starten Sie Ihre kostenlose 30-Tage-Testphase – 20.000 Wörter in 2 Sprachen, keine Kreditkarte erforderlich. Laden Sie Ihre YAML-Dateien hoch, erhalten Sie in wenigen Minuten übersetzte Versionen und installieren Sie dann die Browser-Erweiterung, um Ihre laufende Rails-App zu verifizieren.
Verwandte Themen:
- PTC API-Referenz – REST-Endpunkte für die CI-Integration.
- KI-Software-Lokalisierung für CI/CD-Pipelines – Service-Übersicht für Engineering-Teams.
- Offizieller Rails i18n-Leitfaden – die kanonische Referenz.