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

Laravel Localization Laravel Package

shureban/laravel-localization

Laravel middleware that auto-sets the application locale from the HTTP Accept-Language header. Install via Composer, register the service provider, and add the Localization middleware globally, per group, or per route.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require shureban/laravel-localization
    

    Add the provider to config/app.php:

    Shureban\LaravelLocalization\LocalizationServiceProvider::class,
    
  2. Publish Config (optional but recommended for customization):

    php artisan vendor:publish --provider="Shureban\LaravelLocalization\LocalizationServiceProvider"
    
  3. Register Middleware: Add to app/Http/Kernel.php:

    protected $middleware = [
        \Shureban\LaravelLocalization\Localization::class,
        // ...
    ];
    

    or for route-specific use:

    protected $routeMiddleware = [
        'localization' => \Shureban\LaravelLocalization\Localization::class,
    ];
    
  4. First Use Case: Test locale detection by accessing a route with an Accept-Language header (e.g., en-US or fr-FR). Verify the app respects the header via:

    dd(app()->getLocale()); // Should match the header's primary language
    

Implementation Patterns

Core Workflows

  1. Automatic Locale Detection:

    • The middleware parses the Accept-Language header and sets the app locale (e.g., en, fr).
    • Example: A user’s browser sends Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8, and the app defaults to fr.
  2. Fallback Logic:

    • Configure fallbacks in config/localization.php (e.g., ['fr' => 'en']).
    • Pattern: Use the config to define fallback chains:
      'fallbacks' => [
          'fr' => 'en',
          'es' => 'en',
          'de' => 'en',
      ],
      
  3. Route-Based Localization:

    • Override middleware behavior per route:
      Route::middleware(['localization'])->get('/fr', function () {
          // Force 'fr' locale for this route
      });
      
    • Tip: Combine with Laravel’s locale() helper for dynamic routes:
      Route::get('/{locale}/posts', function ($locale) {
          app()->setLocale($locale);
          // ...
      })->middleware('localization');
      
  4. API Responses:

    • Localize JSON responses by setting the locale before returning data:
      return response()->json([
          'message' => trans('api.welcome'),
      ])->setEncodingOptions(JSON_UNESCAPED_UNICODE);
      
  5. User-Specific Overrides:

    • Store user preferences in the session/database and merge with header-based detection:
      $userLocale = session('locale') ?? app()->getLocale();
      app()->setLocale($userLocale);
      

Integration Tips

  • Blade Templates: Use Laravel’s built-in {{ trans() }} or @lang() directives, which respect the set locale:

    <h1>@lang('welcome.title')</h1>
    
  • Validation Messages: Localize validation errors by setting the locale before validation:

    app()->setLocale('fr');
    $validator = Validator::make($request->all(), [...]);
    
  • Database Localization: For multilingual content (e.g., with spatie/laravel-translatable), ensure the package’s locale aligns with your model’s active locale:

    $post->setLocale(app()->getLocale());
    
  • Testing: Mock the Accept-Language header in tests:

    $response = $this->withHeaders(['Accept-Language' => 'fr-FR'])
        ->get('/');
    $this->assertEquals('fr', app()->getLocale());
    

Gotchas and Tips

Pitfalls

  1. Header Parsing Quirks:

    • The package may not handle malformed Accept-Language headers gracefully. Test with edge cases like:
      Accept-Language: en-US,en;q=0.5,fr-FR;q=0.3,*;q=0.1
      
    • Fix: Override the default parser in config:
      'parser' => \Shureban\LaravelLocalization\Parsers\CustomParser::class,
      
  2. Middleware Order:

    • Place Localization middleware before authentication or session middleware to ensure the locale is set early in the request lifecycle.
    • Anti-pattern: Adding it after auth may cause flash messages or redirects to lose locale context.
  3. Caching Conflicts:

    • If using Laravel’s cache for translations (trans()), ensure the package’s locale changes invalidate caches. Test with:
      Cache::forget('translations.' . app()->getLocale());
      
  4. Right-to-Left (RTL) Languages:

    • RTL locales (e.g., ar, he) may require additional CSS/HTML tags. The package doesn’t handle this automatically; add logic like:
      <html dir="{{ app()->getLocale() === 'ar' ? 'rtl' : 'ltr' }}">
      
  5. Fallback Loops:

    • Misconfigured fallbacks (e.g., ['en' => 'fr']) can cause infinite loops. Validate your fallbacks array:
      $this->assertFalse(array_intersect(['en'], array_keys(config('localization.fallbacks'))));
      

Debugging Tips

  1. Log Locale Changes: Add a middleware to log locale switches:

    public function handle($request, Closure $next) {
        $oldLocale = app()->getLocale();
        $response = $next($request);
        if ($oldLocale !== app()->getLocale()) {
            \Log::info("Locale changed from {$oldLocale} to " . app()->getLocale());
        }
        return $response;
    }
    
  2. Inspect Headers: Use Laravel’s dd() to debug the raw Accept-Language header:

    dd(request()->header('Accept-Language'));
    
  3. Disable Middleware Temporarily: Comment out the middleware in Kernel.php to isolate issues:

    // protected $middleware = [
    //     // \Shureban\LaravelLocalization\Localization::class,
    // ];
    

Extension Points

  1. Custom Parsers: Extend the parser to support non-standard formats:

    namespace App\Parsers;
    use Shureban\LaravelLocalization\Contracts\Parser;
    
    class CustomParser implements Parser {
        public function parse($header) {
            // Custom logic (e.g., prioritize 'user-locale' cookie)
            return 'en';
        }
    }
    

    Register in config:

    'parser' => \App\Parsers\CustomParser::class,
    
  2. Dynamic Fallbacks: Use a closure for dynamic fallbacks (e.g., based on user role):

    'fallbacks' => [
        'fr' => function () {
            return auth()->user()->preferredLocale ?? 'en';
        },
    ],
    
  3. Locale-Specific Routes: Combine with Laravel’s route model binding for locale-aware resources:

    Route::get('/{locale}/posts/{post}', [PostController::class, 'show'])
        ->middleware('localization')
        ->where('locale', config('localization.supported'));
    
  4. API Locale Overrides: Allow API clients to override the locale via a header or query param:

    if ($request->hasHeader('X-Locale')) {
        app()->setLocale($request->header('X-Locale'));
    }
    

Configuration Quirks

  1. Supported Locales: Ensure config/localization.php includes all locales used in your app:

    'supported' => ['en', 'fr', 'es', 'ar'],
    
    • Warning: Missing locales will default to the app’s fallback locale (often en).
  2. Case Sensitivity: The package may normalize locales to lowercase (e.g., FRfr). Test with mixed-case inputs.

  3. Default Locale: Override the default in config/app.php:

    'locale' => 'fr', // Default if no Accept-Language header
    
  4. Performance: Avoid heavy operations in the middleware (e.g., database queries). Offload logic to:

    • A separate LocaleService class.
    • A cached lookup table for user preferences.
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.
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon
itsemon245/lamet
baks-dev/dashboard
amoifr/pickle-panther-bundle
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle