Skip to main content

Laravel i18n:国際化・ローカリゼーション完全ガイド

最初のロケールファイルから本番環境まで。Laravel の翻訳システム、複数形処理、JSON フォールバックの不具合修正、地域バリアント向けのスマートなロケールフォールバックチェーンを解説します。

1

Laravel の翻訳システムを理解する

Laravel には、PHP 配列と JSON の 2 形式に対応する翻訳システムが組み込まれています。PHP ファイルは機能別に整理したネストキー(auth.failed、validation.required)を使用します。JSON ファイルは原文をキーとして使用するためシンプルですが、入れ子には対応しません。

Terminal
composer create-project laravel/laravel my-app
cd my-app

# Laravel includes i18n out of the box
# No extra packages needed for basic usage
Laravel の翻訳システムは、lang/ ディレクトリ(Laravel 9 以降)または resources/lang/(Laravel 8 以前)にあります。フレームワークがディレクトリを自動検出します。両方がある場合は lang/ が優先されます。
2

ロケール設定

config/app.php で、アプリケーションのデフォルトロケールとフォールバックロケールを設定します。フォールバックロケールは、有効なロケールに翻訳キーがない場合に使用されます。アプリケーションの対応ロケールを構成し、ユーザーが選んだロケールを検出・設定するミドルウェアを追加します。

config/app.php
// config/app.php
return [
    'locale' => 'en',            // Default locale
    'fallback_locale' => 'en',   // Fallback when key is missing
    'faker_locale' => 'en_US',

    // Available locales (for your language switcher)
    'available_locales' => ['en', 'de', 'ja', 'es', 'fr', 'pt-BR'],
];
app/Http/Middleware/SetLocale.php
// app/Http/Middleware/SetLocale.php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class SetLocale
{
    public function handle(Request $request, Closure $next)
    {
        $locale = $request->segment(1); // e.g. /de/about

        if (in_array($locale, config('app.available_locales'))) {
            app()->setLocale($locale);
        }

        return $next($request);
    }
}
3

翻訳関数の使用

Laravel で文字列を翻訳する方法は、__() ヘルパー関数(推奨)、trans() 関数、Blade の @lang ディレクティブの 3 つです。いずれも翻訳キーと、任意の置換パラメーターを受け取ります。PHP コードと Blade テンプレートでは __()、HTML のエスケープが不要な Blade では @lang を使用します。

lang/en/messages.php
// lang/en/messages.php
return [
    'welcome' => 'Welcome to our application',
    'greeting' => 'Hello, :name!',
    'nav' => [
        'home' => 'Home',
        'about' => 'About',
        'settings' => 'Settings',
    ],
];

// lang/de/messages.php
return [
    'welcome' => 'Willkommen in unserer Anwendung',
    'greeting' => 'Hallo, :name!',
    'nav' => [
        'home' => 'Startseite',
        'about' => 'Über uns',
        'settings' => 'Einstellungen',
    ],
];
新しいコードでは trans() より __() を推奨します。__() は PHP と JSON の両翻訳ファイルに対応しますが、trans() は PHP ファイルにしか対応しません。@lang ディレクティブは Blade テンプレートの {'{ __() }'} と同等ですが、構文がやや簡潔です。
4

複数形の処理

Laravel は、パイプ区切りの複数形式構文を使用します。最も単純な形式は 'apples' => 'There is one apple|There are many apples' です。範囲を明示する場合は 'apples' => '{0} No apples|{1} One apple|[2,*] :count apples' を使用します。trans_choice() ヘルパーまたは Str::plural() が、件数に基づいて適切な形式を選択します。

lang/en.json
// lang/en.json
{
    "Welcome back!": "Welcome back!",
    "You have :count new notifications": "You have :count new notifications",
    "Copyright :year :company": "Copyright :year :company"
}

// lang/de.json
{
    "Welcome back!": "Willkommen zurück!",
    "You have :count new notifications": "Sie haben :count neue Benachrichtigungen",
    "Copyright :year :company": "Copyright :year :company"
}
Laravel 組み込みの複数形処理が多くの言語で正しく扱えるのは、単純な one/other 規則だけです。アラビア語は 6、ロシア語は 4、ポーランド語は 3 つの複数形式を持つため、必要な CLDR 複数形カテゴリをすべて定義する必要があります。定義しなければ、文法的に誤ったテキストが表示されます。
5

ロケールフォールバックチェーンの追加

Laravel 組み込みのフォールバックは、有効なロケールから fallback_locale へ直接切り替わり、中間段階がありません。そのため、pt-BR でキーが欠落すると、利用可能な pt-PT 翻訳ではなく英語が表示されます。laravel-locale-chain は、読み込み時に構成可能なフォールバックチェーンから翻訳をディープマージし、この問題を解決します。

resources/views/example.blade.php
{{-- Simple translation --}}
<h1>{{ __('messages.welcome') }}</h1>

{{-- With variables --}}
<p>{{ __('messages.greeting', ['name' => $user->name]) }}</p>

{{-- Using @lang directive --}}
<h2>@lang('messages.nav.home')</h2>

{{-- JSON translations (use the string itself as key) --}}
<p>{{ __('Welcome back!') }}</p>

{{-- Pluralization --}}
{{ trans_choice('{0} No items|{1} One item|[2,*] :count items', $count) }}

{{-- Inside Blade components --}}
<x-button>{{ __('messages.nav.settings') }}</x-button>
6

翻訳の自動化

Laravel の i18n 設定が完了したら、AI でロケールファイルを翻訳します。AI アシスタントに翻訳元ロケールファイルを指定するか、CI/CD パイプラインで i18n Agent CLI を使用します。PHP と JSON の両翻訳ファイルに対応しています。

config/locale-chain.php
// Install locale chain package
composer require i18n-agent/laravel-locale-chain

// config/locale-chain.php
return [
    'chains' => [
        'pt-BR' => ['pt-BR', 'pt', 'en'],
        'zh-Hant-TW' => ['zh-Hant-TW', 'zh-Hant', 'zh', 'en'],
        'es-419' => ['es-419', 'es', 'en'],
    ],
];

// In AppServiceProvider::boot()
use I18nAgent\LocaleChain\LocaleChainServiceProvider;

// The package automatically deep-merges translations
// across the chain: pt-BR -> pt -> en
差分ごとに翻訳してください。新しいキーを追加した際は、全ファイルを再生成せず差分のみを翻訳します。人が確認した翻訳を保持し、不要な変更を避けられます。

よくある落とし穴

単数形/複数形ロジックのハードコード

trans_choice() を使わず $count == 1 ? 'item' : 'items' と記述すると、0 を単数扱いする言語(フランス語)、3 つ以上の複数形式を持つ言語(ロシア語、ポーランド語)、6 形式を持つ言語(アラビア語)で正しく動作しません。必ず Laravel の複数形構文を使用し、必要な形式をすべて定義してください。

JSON 翻訳がフォールバックしない

Laravel の fallback_locale が機能するのは、PHP 翻訳ファイルだけです。JSON 翻訳は原文をキーにするため、翻訳がなければフォールバックロケールを検索せず、キー自体(英語のテキスト)を返します。つまり、JSON 翻訳には本来のロケールフォールバックがありません。laravel-locale-chain で解決できます。

優先順位を理解せず PHP と JSON を混在させる

同じキーが PHP と JSON の両ファイルにある場合は、PHP が優先されます。PHP ファイルが JSON の値を隠すため、JSON ファイルを更新しても反映されないという分かりにくい動作につながります。機能の名前空間ごとに 1 つの形式を選び、統一してください。

i18n Agent を今すぐ試す

翻訳ファイルをここにドロップ

JSON, YAML, PO, XML, CSV, Markdown, Properties

またはクリックしてファイルを選択

翻訳先言語

登録不要すぐに見積もり

Laravel i18n のよくある質問