Guide complet de l'internationalisation (i18n) sur Rails
Configurez l'i18n de Rails, organisez vos fichiers config/locales/*.yml, automatisez les traductions YAML par IA et laissez PTC (Private Translation Cloud) relire votre application Rails en cours d'exécution à chaque version. À la fin de ce guide, vous disposerez d'une application Rails répondant aux URL en /es/..., servant des vues traduites dans plus de 40 langues et vérifiée par une relecture visuelle.
Ce guide suppose que vous possédez une application Rails 7+. Les concepts s'appliquent aux versions plus anciennes de Rails avec des différences mineures d'API. La gem I18n elle-même est stable depuis des années. Pour une approche globale de la localisation en CI/CD sur différentes technologies, consultez la page traduction logicielle par IA conçue pour les pipelines CI/CD.
Configurer Rails pour charger les locales, reconnaître les URL et changer de langue par requête
L'internationalisation de Rails nécessite trois étapes de configuration. Définir les locales disponibles, ajouter la locale à vos URL et faire en sorte que Rails charge la bonne locale par requête. Vous devez également installer la gem rails-i18n pour les données de localisation.
Déclarer les locales disponibles dans config/application.rb
Dans config/application.rb, indiquez à Rails quelles langues l'application prend en charge et définissez une langue par défaut :
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
La ligne load_path += Dir[...] est essentielle. Par défaut, Rails ne charge que config/locales/*.yml (un seul niveau de profondeur). L'ajout du glob récursif vous permet d'organiser les traductions par espace de noms, modèle ou fonctionnalité dans des sous-répertoires.
Ajouter :locale à la portée de vos URL
Ajoutez une portée :locale pour que chaque langue ait son propre chemin, comme /en/time ou /fr/time :
# config/routes.rb
scope "/:locale" do
get '/time', to: 'home#index', as: :time_display
end
Changer de locale par requête avec I18n.with_locale
Dans ApplicationController, chargez la bonne locale à partir de l'URL et incluez-la dans tous les liens générés :
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 est la méthode idiomatique pour limiter la portée d'une locale à une requête. Elle définit la locale, exécute le bloc, restaure la locale précédente et est sécurisée pour les threads (thread-safe). default_url_options garantit que chaque URL générée par Rails porte la locale actuelle, afin que les utilisateurs restent dans la langue sélectionnée lors de leur navigation.
Installer rails-i18n pour les noms de mois traduits et les règles de pluralisation
La gem rails-i18n fournit des données de localisation pour des dizaines de langues. Cette gem contient les noms de mois traduits, les règles de pluralisation et les messages d'erreur par défaut de Rails. Ainsi, vous n'avez pas à traduire vous-même ce contenu générique.
# Gemfile
gem 'rails-i18n'
bundle install
Votre application Rails est maintenant entièrement configurée pour l'internationalisation.
Ajouter un sélecteur de langue avec url_for(locale: :code)
Comme default_url_options inclut automatiquement la locale dans chaque URL générée, votre sélecteur n'a qu'à mettre à jour le paramètre :locale tout en maintenant l'utilisateur sur la même page.
<%# 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>
Chaque lien utilise url_for(locale: :code) pour générer une URL avec la locale spécifiée. Lorsque les utilisateurs cliquent, switch_locale dans ApplicationController détecte le changement et Rails affiche la page dans la nouvelle langue.
Remplacer le texte codé en dur dans les vues par t(:key)
Le texte codé en dur n'apparaîtra pas dans vos fichiers YAML, ce qui signifie qu'il ne pourra pas être traduit. Utilisez toujours des clés de traduction pour tout texte destiné à l'utilisateur.
<%# 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>
Dans les contrôleurs (pour les messages flash) :
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
Dans les modèles (pour les messages de validation, utilisez les conventions Active Model) :
# config/locales/en.yml
en:
activerecord:
attributes:
post:
title: "Title"
errors:
models:
post:
attributes:
title:
blank: "is required"
Interpolation de variables avec %{name}
%{name} dans le YAML est remplacé par la valeur que vous passez à t() :
current_time: "Current time: %{time}"
<%= t(:current_time, time: @time) %>
Utiliser la recherche différée (.key) pour les traductions limitées à la vue
Lorsque vos clés de traduction sont organisées pour correspondre à la structure de vos dossiers de vues, utilisez un point au début. Rails complète le préfixe à partir de la vue actuelle :
<%# Instead of this: %>
<%= t('home.index.hello') %>
<%# Use this: %>
<%= t('.hello') %>
Rails détecte que vous êtes dans home/index.html.erb et ajoute home.index. au début. Si vous renommez ou déplacez une vue, les chemins de recherche différée se mettent à jour automatiquement.
Organiser config/locales/ par fonctionnalité plutôt qu'un seul fichier en.yml géant
Pour une application réelle, un seul fichier en.yml géant devient impossible à maintenir. Organisez par fonctionnalité :
config/locales/
en.yml # global / shared keys
models/
post.en.yml
views/
posts.en.yml
home.en.yml
flash.en.yml
Exemple de fichier 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"
Conventions :
- Clés imbriquées : regroupent les chaînes liées et permettent la recherche différée.
- Interpolation
%{name}: pour les variables en ligne. - Pluralisation
zero/one/other: clés pour les pluriels. Rails s'oriente vers la bonne clé en fonction decount::t('posts.show.comments_count', count: 5).
Ajouter également les chaînes JavaScript au YAML
Rails n'extrait pas automatiquement le texte des fichiers JavaScript. Tout texte côté client (alertes, info-bulles, messages de confirmation) doit résider dans votre YAML afin d'être traduit en même temps que le reste :
en:
confirm: "Are you sure?"
Lorsque vous traduisez avec PTC dans la section suivante, ces chaînes sont traitées avec les autres.
Traduire config/locales/*.en.yml avec PTC en 4 étapes
Une fois vos fichiers de traduction en place, vous avez besoin de versions pour chaque langue cible. PTC s'en charge :
- Démarrez un projet PTC et choisissez l'anglais comme source. L'essai gratuit couvre 20.000 mots vers 2 langues, sans carte bancaire.
- Téléchargez vos fichiers
config/locales/*.en.yml. PTC analyse le YAML, reconnaît les clés de pluralisation de Rails (zero,one,other,few,many) et préserve les interpolations%{name}. - Ajoutez une courte description de votre application Rails et de votre public. PTC utilise ce contexte pour traduire avec le ton et la terminologie appropriés.
- Choisissez les langues cibles et confirmez. PTC produit les fichiers
posts.es.yml,posts.fr.yml,posts.de.yml, structurellement identiques à la source avec les valeurs traduites. Les formes plurielles sont générées par langue. Le polonais obtientone/few/many/other. Le japonais n'obtient queother.
Placez les fichiers dans config/locales/views/, redémarrez votre serveur Rails, et l'application servira les nouvelles langues.
Pour les projets gérés par Git, connectez PTC à votre dépôt. Les nouvelles chaînes dans n'importe quel fichier *.en.yml déclenchent une traduction automatique. PTC ouvre une pull request avec les fichiers de langue cible mis à jour. Consultez la référence de l'API PTC pour le flux de synchronisation.
Utiliser I18n.with_locale dans les tâches de fond, les mailers et les tâches cron
Le modèle I18n.with_locale(locale, &block) est essentiel pour tout code s'exécutant en dehors d'une requête normale. Cela inclut les tâches de fond, les tâches cron et les mailers.
# 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
Sans with_locale, la tâche s'exécute dans la locale qui était active au démarrage du worker. Généralement :en, quel que soit le choix de l'utilisateur. Avec cette méthode, l'e-mail est rendu dans la langue de l'utilisateur et la locale est réinitialisée à la fin du bloc.
Exporter les traductions Rails en JSON avec i18n-js pour une utilisation côté client
Les pages rendues par Rails reçoivent les traductions via t() dans ERB. Le JavaScript s'exécutant dans le navigateur ne voit pas directement l'I18n de Rails. La méthode la plus propre consiste à utiliser la gem i18n-js pour exporter les traductions en JSON et les charger côté client.
# Gemfile
gem 'i18n-js'
bundle install
i18n init
Mettez à jour la configuration générée pour exporter les traductions vers public/locales.json :
# config/i18n.rb
require "i18n-js"
I18n::JS.config do |config|
config.export_i18n_js = false
config.translations_path = "public/locales.json"
end
Générez le fichier JSON :
i18n export
Cela lit tous vos fichiers YAML (en.yml, es.yml, de.yml) et écrit public/locales.json avec chaque traduction dans un format lisible par JS.
Épinglez i18n-js avec l'Importmap de Rails 7+ :
# config/importmap.rb
pin "i18n-js", to: "https://esm.sh/i18n-js@latest/dist/import/index.js"
pin "load_locale", to: "load_locale.js"
Créez un chargeur :
// app/javascript/load_locale.js
export async function loadLocale() {
const response = await fetch('/locales.json');
return await response.json();
}
Passez la locale actuelle au JavaScript via la balise <body> :
<%# app/views/layouts/application.html.erb %>
<body data-locale="<%= I18n.locale %>">
Ensuite, utilisez les traductions dans votre 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() fonctionne comme l'assistant t de Rails. Lorsque les utilisateurs changent de langue, le JavaScript utilise les bonnes traductions à partir de l'attribut data-locale.
Traduire le contenu ActiveRecord avec l'API PTC
Le modèle ci-dessus traduit les chaînes statiques de vos fichiers YAML. Le contenu ActiveRecord (articles d'utilisateurs, commentaires, descriptions de produits stockés en tant qu'entrées utilisateur) n'apparaît pas dans le YAML et nécessite une approche différente. L' API REST de PTC traduit ce contenu à la demande avec une authentification par jeton Bearer, en utilisant le même glossaire et la même voix de marque que vos fichiers config/locales/*.yml. Envoyez votre contenu à PTC via POST, puis recevez un rappel (callback) lorsque les traductions sont prêtes ou interrogez le statut depuis une tâche de fond.
Localiser les dates, les nombres et les devises avec les assistants Rails
Dates et heures. Utilisez l'assistant l (abréviation de localize) :
<%= l Time.now, format: :long %>
La gem rails-i18n fournit des formats de date/heure par défaut pour de nombreuses langues, incluant les noms de mois traduits et un formatage spécifique à la locale. Vous pouvez définir des formats personnalisés dans vos fichiers YAML.
Nombres et devises. Rails inclut des assistants tenant compte de la locale :
<%= number_to_currency(100, locale: :es) %> <!-- 100,00 € -->
<%= number_with_delimiter(1000000) %> <!-- 1,000,000 -->
Ceux-ci respectent les conventions de la locale pour les séparateurs décimaux, les séparateurs de milliers et les symboles monétaires.
Vues localisées par langue. Pour les pages dont le contenu diffère considérablement selon la locale, créez des fichiers de vue distincts. Rails affiche la vue appropriée en fonction de la locale actuelle :
app/views/pages/
about.html.erb <!-- Default -->
about.es.html.erb <!-- Spanish version -->
about.de.html.erb <!-- German version -->
Relecture visuelle de la traduction de votre application Rails en cours d'exécution - livrez sans contrôle qualité manuel par version
Une fois que PTC a traduit vos fichiers config/locales/*.yml, l'application Rails rendue doit encore être vérifiée. Un libellé traduit peut déborder d'un bouton en allemand. Un message de validation en français peut utiliser une forme grammaticale incorrecte. Une chaîne en anglais codée en dur dans un modèle ERB (sans appel à t()) s'affichera non traduite, quel que soit le nombre de langues que vous proposez.
L'AI Visual QA de PTC remplace l'étape de contrôle qualité manuel. Pour les applications Rails (basées sur un navigateur), installez l'extension de navigateur PTC et enregistrez un parcours guidé des écrans critiques de votre application (connexion, flux principaux, pages d'administration). À partir de là, PTC rejoue l'enregistrement dans chaque langue cible après chaque mise à jour de traduction, capture chaque écran et signale :
- Des corrections dans les fichiers YAML lorsque PTC les contrôle. PTC retraduit un sens erroné, choisit un synonyme plus court, régénère une forme plurielle.
- Des prompts Cursor / Claude Code lorsque le problème réside dans votre code Ruby ou ERB. Une chaîne en anglais codée en dur en dehors de
t(), un message flash construit par concaténation au lieu d'interpolation, un assistant qui devrait utiliserI18n.lpour le formatage de date.
Le résultat : une application Rails multilingue vérifiée à chaque version. Pas seulement du YAML traduit.
Traduire les notes de version, les mailers Devise et les pages marketing
Vos notes de version, les e-mails destinés aux clients envoyés via Devise ou Action Mailer, et les pages marketing résident en dehors de config/locales. L'outil Paste to Translate de PTC traite ces textes dans le même projet. Collez le texte source dans le tableau de bord PTC, choisissez les langues cibles, et récupérez des traductions utilisant le même glossaire et la même voix de marque que vos traductions YAML.
Traduisez vos fichiers config/locales/*.yml avec PTC
Commencez votre essai gratuit de 30 jours - 20.000 mots vers 2 langues, sans carte bancaire. Téléchargez vos fichiers YAML, obtenez les versions traduites en quelques minutes, puis installez l'extension de navigateur pour vérifier votre application Rails en cours d'exécution.
Voir aussi :
- Référence de l'API PTC - points de terminaison REST pour l'intégration CI.
- Traduction logicielle par IA conçue pour les pipelines CI/CD - présentation du service pour les équipes d'ingénierie.
- Guide officiel i18n de Rails - la référence canonique.