Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Translation Laravel Package

symfony/translation

Symfony Translation component for internationalizing apps: manage translators, message catalogs, pluralization and locales, load translations from arrays/files, and translate strings with parameters and domains. Install via Composer and integrate in Symfony or standalone PHP.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup in Laravel

  1. Install the package:

    composer require symfony/translation
    

    Laravel already bundles this component, so no additional installation is needed if using Laravel’s built-in localization.

  2. Configure the translator (typically in config/app.php or a custom config file):

    'translator' => [
        'default_locale' => 'en',
        'fallback_locale' => 'en',
        'locales' => ['en', 'fr', 'es', 'de'],
        'supported_locales' => [
            'en' => 'English',
            'fr' => 'Français',
            'es' => 'Español',
            'de' => 'Deutsch',
        ],
        'loaders' => [
            'array',
            'yaml',
            'json',
            'xliff',
            'csv',
            'php',
            'qmo',
            'po',
        ],
    ],
    
  3. First use case: Translating a string

    // In a controller or view
    $translated = trans('messages.welcome', ['name' => 'John'], [], 'fr');
    // Outputs: "Bonjour John !" (assuming 'messages.welcome' is defined in fr_FR translation file)
    
  4. Locate translation files: Laravel expects files in resources/lang/{locale}/messages.php (or .json, .yaml, etc. based on config). Example:

    // resources/lang/fr/messages.php
    return [
        'welcome' => 'Bonjour :name !',
    ];
    
  5. Switch locales dynamically:

    app()->setLocale('fr');
    $translated = trans('messages.welcome');
    

Implementation Patterns

1. Loader Integration Workflows

  • For JSON/YAML/CSV files: Use Laravel’s built-in loaders by placing files in resources/lang/{locale}/{domain}.{ext}. Example: resources/lang/fr/validation.json for validation messages.

  • For database-backed translations: Create a custom loader (e.g., DatabaseLoader) extending Symfony\Component\Translation\Loader\LoaderInterface:

    use Symfony\Component\Translation\Loader\LoaderInterface;
    use Illuminate\Support\Facades\DB;
    
    class DatabaseLoader implements LoaderInterface
    {
        public function load($resource, $locale, $domain = 'messages')
        {
            return DB::table('translations')
                ->where('locale', $locale)
                ->where('domain', $domain)
                ->pluck('translation', 'key')
                ->toArray();
        }
    }
    

    Register it in config/app.php under translator.loaders.

  • For XLIFF files (common in professional translation workflows): Use the XliffFileLoader for .xlf files. Example structure:

    resources/lang/
        ├── fr/
        │   └── messages.xlf
    

2. Message Domains

  • Organize translations by domain (e.g., validation, notifications):

    // In config/app.php
    'translator' => [
        'domains' => ['messages', 'validation', 'notifications'],
    ],
    

    Access domain-specific translations:

    trans('validation.required', [], [], 'validation');
    
  • Dynamic domain loading: Useful for plugins or modular apps. Example:

    $translator->addResource('yaml', new FileLoader(), 'vendor/package/lang/{locale}/messages.yaml', 'package_messages');
    

3. Pluralization and Interpolation

  • Pluralization rules: Define rules in resources/lang/{locale}/messages.php:

    return [
        'apples' => '{0} No apples|{1} One apple|]1,Inf[ {count} apples',
    ];
    

    Use in code:

    trans_choice('messages.apples', 5); // Outputs: "5 apples"
    
  • Interpolation with parameters:

    trans('messages.greeting', ['name' => 'John']); // "Hello, John!"
    

4. Fallback and Default Locales

  • Configure fallback locales in config/app.php:
    'translator' => [
        'fallback_locale' => 'en',
    ],
    
    If fr_CA is missing a translation, it falls back to fr or en.

5. CLI Workflows

  • Dump translations to files:
    php artisan translation:dump fr
    
  • Extract missing translations:
    php artisan translation:extract
    
  • Push translations to services (e.g., Crowdin, Lokalise):
    php artisan translation:push crowdin --force
    

6. Testing Translations

  • Mock the translator in tests:
    $translator = $this->createMock(TranslatorInterface::class);
    $translator->method('trans')->willReturn('Mocked translation');
    $this->app->instance(TranslatorInterface::class, $translator);
    
  • Assert translations:
    $this->assertEquals('Bonjour', trans('greeting'));
    

7. Integration with Laravel Ecosystem

  • Blade directives:
    @lang('fr')
        Bonjour
    @endlang
    
  • Localization middleware:
    public function handle($request, Closure $next)
    {
        if ($request->has('locale')) {
            app()->setLocale($request->locale);
        }
        return $next($request);
    }
    
  • Route localization:
    Route::group(['prefix' => '{locale}'], function () {
        // Routes here will inherit the locale from the URL
    });
    

Gotchas and Tips

Pitfalls

  1. Locale vs. Language Code Confusion:

    • Use full locale codes (e.g., fr_FR for French-France) instead of just language codes (e.g., fr) to avoid ambiguity in regional variations (e.g., fr_FR vs. fr_CA).
  2. Missing Fallback Locales:

    • If a translation is missing in the requested locale and its fallbacks, the original string is returned. Always test edge cases:
      trans('nonexistent.key'); // Returns 'nonexistent.key' if no fallback exists.
      
  3. Caching Issues:

    • Translations are cached by default in Laravel. Clear the cache after updating translation files:
      php artisan cache:clear
      php artisan view:clear
      
  4. Pluralization Edge Cases:

    • Pluralization rules can be complex (e.g., Russian, Arabic). Test thoroughly with all possible values (0, 1, 2, 5, 21).
    • Example for Russian (ru_RU):
      '{0} {1} apple|{1} {1} apple|[2,4] {1} apples|[5,Inf] {1} apples'
      
  5. File Loader Quirks:

    • CSV files: Ensure no empty lines or malformed entries (fixed in v8.0.4). Use UTF-8 encoding.
    • XLIFF files: Validate metadata (fixed in v8.1.0). Avoid special characters in keys.
    • YAML/JSON: Indentation matters in YAML. JSON must be valid.
  6. Database Loader Performance:

    • Avoid querying the database for every translation. Cache results:
      $translator->addCache(new FileCache(), true);
      
  7. Third-Party Service Integration:

    • When pushing/pulling translations (e.g., Crowdin, Lokalise), ensure the --force flag is used carefully to avoid overwriting partial data (fixed in v8.0.6).
  8. Deprecated Methods:

    • Avoid TranslatableMessage::__toString() (deprecated in v8.0.0). Use trans() or getMessage() instead.

Debugging Tips

  1. Enable Debug Mode:

    $translator->setFallbackLocales([$locale]); // Debug fallback chain
    

    Or use the TranslationDebugger:

    $debugger = new \Symfony\Component\Translation\Debug\TranslationDebugger();
    $debugger->setTranslator($translator);
    
  2. Log Missing Translations: Create a custom logger for missing keys:

    $translator->setLogger(new \Monolog\Logger('translations'));
    
  3. Validate Translation Files: Use the translation:extract command to ensure all used keys are defined in files.

  4. Check Locale Negotiation: If app()->getLocale() returns unexpected values, inspect the LocaleMiddleware or LocaleServiceProvider.

Extension Points

  1. Custom Loaders: Extend LoaderInterface for unsupported formats (e.g., Markdown, Excel):
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
croct/coding-standard
croct/plug-php
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
imbo/imbo-coding-standard
visualbuilder/filament-lottie
servicioslineaonce/starter-kit
atomcoder/laravel-reorderable
irajul/filament-shadcn-theme
agtp/agtp-php
agtp/mod-php
centraldesktop/protobuf-php
trappistes/laravel-custom-fields
splash/sonata-admin
splash/metadata