PTC

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 de count: : 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 :

  1. Démarrez un projet PTC et choisissez l'anglais comme source. L'essai gratuit couvre 20.000 mots vers 2 langues, sans carte bancaire.
  2. 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}.
  3. 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.
  4. 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 obtient one / few / many / other. Le japonais n'obtient que other.

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 utiliser I18n.l pour 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 :