|
ドキュメント
デモを予約プラットフォーム
プラットフォームMCPCLIAPIワークフロー
ガイド
変更履歴

ローカライゼーション

  • 概要
  • 翻訳API
  • Webアプリのローカライゼーション
  • モバイルアプリのローカライズ
  • String Catalogを使ったiOS
  • Android with strings.xml
  • メールのローカライズ
  • 静的コンテンツ(例: .md、.json)
  • Next.js with Markdoc
  • Rails with i18n

ワークフロー

  • MCP でエンジンを設定
  • Jiraトリアージ
  • CI/CD

i18n API を使った Ruby on Rails のローカライズ

Lingo.dev の CLI は、設定した config/localesローカライゼーションエンジン を通じて Rails の YAML ファイルを翻訳します。Rails には i18n API が標準で組み込まれており、アプリ内の翻訳可能なテキストはロケールごとの YAML ファイルに保存されます。Lingo.dev はランタイム依存を追加することなく、既存のパイプラインに自然に組み込めます。

このガイドでは、Rails アプリを最初から最後までローカライズする手順を紹介します。CLI の設定、ロケールごとの YAML ファイル構成、リクエスト時のロケール切り替え、そして CI での翻訳自動化までを扱います。

デモリポジトリ

一緒に試すなら、lingodotdev/ruby-on-rails-localization-example をクローンまたはフォークしてください。実際に動く Rails アプリで、config/locales YAML ファイル、コミット済みの .lingo/config.json、さらに翻訳もすでに入っているので、設定とその出力結果を並べて確認できます。

Rails のローカライズの仕組み#

Rails は config/locales/ 配下の YAML ファイルから翻訳を読み込みます。各ファイルはルートにロケールコードを持ち、I18n.t を使ってコードから参照する検索パスに対応した、ネスト構造のキーを含みます。

レイヤー内容ファイル例
UI 文言ボタン、ラベル、フラッシュメッセージconfig/locales/en.yml
メーラー文面ActionMailer の件名と本文config/locales/mailers.en.yml
モデルのエラーバリデーションメッセージと属性名config/locales/activerecord.en.yml

Rails の YAML ファイルは、先頭のキーが en:、es:、fr: のようなロケールコードになっています。Rails はファイル名ではなく、このルートキーをもとに翻訳を管理します。config/locales/ 配下のすべてのファイルを読み込み、それぞれの内容を宣言されたルートキーの下に格納します。つまり、es.yml のルートが en: のままでも無視されるわけではなく、en 名前空間にマージされます。その結果、スペイン語には翻訳がまったく入らず、英語の翻訳だけが気づかないうちに上書きされてしまいます。

つまり、この形式を翻訳するには値だけでなく、そのキー自体も書き換える必要があります。yaml-root-key 形式はまさにそのためのものです。ルートキー配下のツリーをたどり、文字列の値だけを翻訳し、ターゲットロケールをルートにしたファイルを書き出します。ネストしたキー、%{name} の補間トークン、CLDR の複数形カテゴリ(zero/one/two/few/many/other)は構造なので、そのまま保持されます。コメントや YAML アンカーも同様です。

前提条件#

1

ローカライゼーションエンジンを作成する

CLI を実行するたびに、コンテンツはローカライゼーションエンジンを通ります。これは、どの LLM モデル、用語集、ブランドボイス、ルールを適用するかを決める設定です。Lingo.dev dashboardで作成し、API keyを生成してください。

2

Ruby と Rails を確認する

このガイドは Rails 7.2 以上を対象としており、Ruby 3.1 以上が必要です。バージョンを確認してください。

bash
ruby -v
rails -v
3

Node.js を確認する

CLI の利用には Node.js 22 以上が必要です。

bash
node -v
4

Rails i18n を設定する

このガイドでは、アプリがすでに config/locales/*.yml に翻訳を保存していることを前提としています。ビューやコントローラーに文字列がハードコードされている場合は、まずそれらを t() 呼び出しに切り出してください。たとえば、次のようなコードを置き換えます。

erb
<h1>Welcome</h1>

次のようにします。

erb
<h1><%= t(".welcome") %></h1>

その後、対応するキーを config/locales/en.yml に追加してください。移行手順の全体については、Rails の internationalization guide を参照してください。

翻訳ファイルを整理する#

Rails は *.yml 配下にある config/locales/ ファイルをすべて自動で読み込みます。ソースロケールは翻訳済みファイルと並べて配置し、ディレクトリ全体を信頼できる単一の情報源にしましょう。

text
config/locales/
  en.yml          # Source locale
  es.yml          # Generated by Lingo.dev
  fr.yml
  de.yml

一般的な en.yml には、プレーンな文字列、ネストされた名前空間、%{name} の補間、複数形が混在しています。

yaml
en:
  hello: "Hello"
  home:
    welcome: "Welcome, %{name}!"
    cta: "Get started"
  notifications:
    unread:
      zero: "No unread notifications"
      one: "1 unread notification"
      other: "%{count} unread notifications"
  errors:
    messages:
      blank: "can't be blank"

CLI を設定する#

CLI をインストールし、認証を済ませて、プロジェクトを自分のエンジンにリンクします。

bash
npm install -g @lingo.dev/cli
lingo login
lingo init
lingo link

lingo init と lingo link を実行すると、使用するロケールとエンジンの .lingo/config.json、orgId を含む engineId が作成されます。これを .lingo/lock.json と一緒にコミットしておけば、どのマシンでも、どの CI 実行でも同じ状態を共有できます。

files[] エントリでソースロケールファイルを指定し、形式を明示的に設定します。

json
{
  "orgId": "org_...",
  "engineId": "eng_...",
  "sourceLocale": "en",
  "targetLocales": ["es", "fr", "de"],
  "files": [{ "pattern": "config/locales/en.yml", "format": "yaml-root-key" }]
}

ここでは "format": "yaml-root-key" は必須です。.yml のパスだけでは、ルートキーがロケールなのか通常の設定なのか判別できないため、CLI は推測しません。format を省略すると、そのファイルは汎用の yaml として扱われ、値だけが翻訳され、ルートは en: のまま残ります。これが前述のサイレントフェイルです。

出力先はソースパスから導かれるため、config/locales/en.yml から config/locales/es.yml、config/locales/fr.yml、config/locales/de.yml が生成されます。

Rails は en.yml に加えて、devise.en.yml、mailers.en.yml、activerecord.en.yml のような用途別ファイルも読み込みます。これらも対象にするには、glob を使った 2 つ目のエントリを追加します。

json
{
  "files": [
    { "pattern": "config/locales/en.yml", "format": "yaml-root-key" },
    { "pattern": "config/locales/*.en.yml", "format": "yaml-root-key" }
  ]
}

この 2 つのパターンは重なりません。1 つ目は en.yml にだけ一致し、2 つ目は .en.yml で終わるファイルにだけ一致します。そのため、es.yml や devise.es.yml のような翻訳済みファイルがソースとして拾われることはありません。devise.en.yml から devise.es.yml が生成されます。

複数ロケール向けに Rails を設定する#

利用可能なロケールと、デフォルトで使うロケールを Rails に指定します。config/application.rb では次のように設定します。

ruby
module YourApp
  class Application < Rails::Application
    config.i18n.available_locales = [:en, :es, :fr, :de]
    config.i18n.default_locale = :en
    config.i18n.fallbacks = [:en]
  end
end

URL パラメータまたは ApplicationController ヘッダーをもとに、Accept-Language でリクエストごとのロケールを選択します。

ruby
class ApplicationController < ActionController::Base
  around_action :switch_locale

  private

  def switch_locale(&action)
    locale = params[:locale] || http_accept_locale || I18n.default_locale
    I18n.with_locale(locale, &action)
  end

  def http_accept_locale
    header = request.headers["Accept-Language"].to_s
    header.scan(/[a-z]{2}/).find { |l| I18n.available_locales.map(&:to_s).include?(l) }
  end

  def default_url_options
    { locale: I18n.locale }
  end
end

ビューで翻訳を表示する#

ERB テンプレートでは t と l ヘルパーを使います。キーの先頭にドットを付けると現在のビューパス基準で解決されるため、翻訳キーをそのテンプレートの近くに保てます。

erb
<h1><%= t(".welcome", name: @user_name) %></h1>
<p><%= t("notifications.unread", count: @unread_count) %></p>
<%= link_to t(".cta"), signup_path, class: "btn-primary" %>

レイアウトにロケール切り替えを追加します。

erb
<nav>
  <% I18n.available_locales.each do |locale| %>
    <%= link_to locale.upcase, url_for(locale: locale) %>
  <% end %>
</nav>

ローカルで翻訳する#

bash
lingo push --wait

push はソースファイルをアップロードし、ローカライゼーションエンジンで処理して、翻訳済みファイルを書き戻します。--wait を付けると、出力がそろうまでコマンドは待機したままになります。これは明示的に指定しておく価値があります。というのも、今後のリリースでデフォルトが変わり、push は実行を送信したらすぐ終了し、結果は lingo pull で取得する形になるためです。

2 回目以降は差分だけが翻訳されます。push はソースをハッシュ化して .lingo/lock.json と比較するため、変更のない項目にはコストがかかりません。プロジェクトでの初回実行時、またはロケール追加後は、コーパス全体の処理が必要です。

bash
lingo push --backfill-missing

glob を渡せば、実行対象をファイルの一部に絞り込めます。

bash
lingo push "config/locales/**"

別の場所で生成された出力、たとえば別マシンや CI の結果を取得するには、lingo pull を実行します。

初回の翻訳実行後は、新しい YAML ファイルを読み込ませるために Rails サーバーを再起動してください。

bash
bin/rails server

スペイン語の表示を確認するには、/es にアクセスしてください。

複数形#

Rails は CLDR plural categories、つまり zero、one、two、few、many、other を使います。count: に I18n.t 引数を渡すと、Rails が対応するキーを選択します。

ruby
t("notifications.unread", count: 0)   # => "No unread notifications"
t("notifications.unread", count: 1)   # => "1 unread notification"
t("notifications.unread", count: 12)  # => "12 unread notifications"

CLI は各複数形バリエーションをその場で翻訳します。ターゲットロケールで英語の one/other より多くのカテゴリが必要な場合は、ソースの en.yml で定義しておいてください。

CI で自動化#

Lingo.dev GitHub App は、プッシュやプルリクエストのたびにサーバー側で翻訳を実行します。ランナーは不要で、API キーをリポジトリに保存する必要もありません。使用するエンジンはコミット済みの .lingo/config.json から解決されるため、コミットするファイルには orgId と engineId が含まれている必要があります。

CLI を自分のパイプラインで動かしたいなら、GitHub Actions、GitLab CI、Bitbucket Pipelines 向けの CI/CD ワークフロー を参照してください。LINGO_API_KEY をシークレットとして渡し、lingo push --wait をほかのビルドステップと同じように実行します。

デプロイ前に検証する#

未翻訳のコンテンツを本番環境に出さないために、lingo check をデプロイゲートとして使います。未翻訳の項目が 1 つでも残っていれば非ゼロのステータスで終了し、何も書き込みません。

bash
lingo check

これを、アセットのプリコンパイルやコンテナビルドの前に独立した CI ステップとして追加します。

yaml
- name: Verify translations
  run: lingo check
- name: Precompile assets
  run: bundle exec rails assets:precompile

次のステップ#

静的コンテンツのローカライズ
Markdown、MDX、JSON、YAML などの静的ファイル形式
Web アプリのローカライズ
主要な Web フレームワークにおける UI 文言パターン
CI/CD ワークフロー
GitHub Actions、GitLab CI、Bitbucket Pipelines のパターン
用語集
ブランド名や技術用語を翻訳対象から外して固定する

このページは役に立ちましたか?

Max PrilutskiyMax Prilutskiy·更新済み 13日前·3分で読めます