Skip to main content

i18n Laravel: полное руководство по интернационализации и локализации

От первого файла локали до рабочей среды: настройте систему переводов Laravel, обработайте формы множественного числа, исправьте ошибку резервных значений JSON и добавьте умные цепочки для региональных вариантов.

1

Разобраться в системе переводов Laravel

Laravel поставляется со встроенной системой переводов с поддержкой двух форматов: массивов PHP и JSON. Файлы 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. Все они принимают ключ перевода и необязательные параметры замены. Используйте __() в коде PHP и шаблонах Blade, а @lang — в Blade, если не требуется экранировать HTML.

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

Автоматизировать перевод

После завершения настройки i18n Laravel переведите файлы локалей с помощью ИИ. Укажите ИИ-помощнику исходный файл локали или используйте CLI i18n Agent в конвейере CI/CD. Поддерживаются файлы перевода 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
Переводите постепенно: добавив новые ключи, переведите только различия, а не создавайте все файлы заново. Это сохранит переводы, проверенные людьми, и исключит ненужные изменения.

Распространённые ошибки

Жёстко заданная логика единственного и множественного числа

Запись $count == 1 ? 'item' : 'items' вместо trans_choice() нарушается в языках, где 0 считается единственным числом, например французском, где есть 3 и более форм, например русском и польском, или 6 форм, как в арабском. Всегда используйте синтаксис множественного числа Laravel и определяйте все необходимые формы.

Переводы JSON не используют резервную локаль

fallback_locale в Laravel работает только с файлами перевода PHP. В JSON исходная строка служит ключом, поэтому при отсутствии перевода возвращается сам ключ — английский текст — вместо поиска в резервной локали. Таким образом, у переводов JSON нет настоящей резервной локали. Используйте laravel-locale-chain для исправления.

Смешение PHP и JSON без понимания приоритета

Если один ключ существует и в PHP, и в JSON, приоритет имеет PHP. Это вызывает непонятное поведение: обновление JSON ничего не меняет, потому что файл PHP его перекрывает. Выберите один формат для каждого пространства имён функции и используйте последовательно.

Попробовать i18n Agent

Перетащите сюда файл перевода

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

или нажмите, чтобы выбрать

Целевые языки

Регистрация не требуетсяМгновенный расчёт

Частые вопросы об i18n Laravel