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 Localizer Laravel Package

niels-numbers/laravel-localizer

Locale-aware routing for Laravel with static, route:cache-ready localized routes. Auto-detects language, redirects to prefixed URLs, and resolves route() to the correct locale. Successor to mcamara/laravel-localization.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**:
   ```bash
   composer require niels-numbers/laravel-localizer

Publish the config (optional):

php artisan vendor:publish --provider="NielsNumbers\Localizer\LocalizerServiceProvider" --tag="config"
  1. Configure Locales: Edit config/localizer.php to define supported locales (e.g., ['en', 'de', 'fr']) and set a default.

  2. First Localized Route:

    Route::localize(function () {
        Route::get('/about', [AboutController::class, 'index'])->name('about');
    });
    

    This generates:

    • /about (auto-detects locale)
    • /en/about, /de/about, etc. (explicit locales)
  3. Detect User Locale: Override config/localizer.php's detectors array to use custom logic (e.g., user profile, cookie, or session).

  4. Test the Flow:

    • Visit /about → Redirects to /en/about (or your default locale).
    • Visit /de/about → Stays on /de/about (explicit locale wins).

Implementation Patterns

Core Workflow: Localization in Action

  1. Route Registration: Use Route::localize() as a wrapper for all public routes needing localization. Example:

    Route::localize(function () {
        Route::get('/products/{product}', [ProductController::class, 'show'])->name('products.show');
    });
    
    • Generates /products/{product} (auto-detect) and /{locale}/products/{product}.
  2. Locale Detection Chain: The package checks these signals in order:

    • Explicit URL prefix (e.g., /de/about).
    • Session cookie (localizer_locale).
    • Accept-Language header (default detector).
    • Fallback to config/localizer.default_locale.
  3. Middleware Integration: Add to app/Http/Kernel.php:

    protected $middlewareGroups = [
        'web' => [
            // ... other middleware
            \NielsNumbers\Localizer\Middleware\SetLocale::class,
            \NielsNumbers\Localizer\Middleware\RedirectLocale::class,
        ],
    ];
    
    • Order Matters: SetLocale must run after StartSession (to read session locale) and before SubstituteBindings (to resolve translated route models correctly).
  4. Locale Switching:

    • URL Switcher: Use route('about') in Blade (auto-localized).
    • Language Links: Generate switcher URLs with:
      {{ route('about', [], ['locale' => 'de']) }}
      
    • JavaScript Helpers: For Ziggy/Inertia, bind the LocalizerBladeRouteGeneratorV2 (see docs).
  5. Dynamic Locale Handling:

    • Override Locale Temporarily:
      Localizer::setLocale('fr');
      // ... logic using French locale
      Localizer::forgetLocale(); // Reset to previous
      
    • Locale-Aware Redirects:
      return redirect()->localized('products.show', ['product' => $id]);
      
  6. Blade Directives:

    • Current Locale:
      {{ Localizer::currentLocale() }}  <!-- e.g., 'de' -->
      
    • Localized URLs:
      <a href="{{ route('about') }}">About</a>  <!-- Auto-localized -->
      
    • RTL/LTR Direction:
      <html dir="{{ Localizer::currentLocaleDirection() }}">
      
  7. API Routes:

    • Exclude from localization if needed:
      Route::prefix('api')->group(function () {
          Route::middleware('api')->group(function () {
              Route::get('/products', [ProductController::class, 'index']);
          });
      });
      

Integration Tips

  1. Ziggy/Inertia:

    • Bind LocalizerBladeRouteGeneratorV2 in AppServiceProvider:
      public function register()
      {
          $this->app->bind(
              \Tighten\Ziggy\BladeRouteGenerator::class,
              \NielsNumbers\Localizer\Ziggy\LocalizerBladeRouteGeneratorV2::class
          );
      }
      
    • For Inertia, ensure localizer_locale is shared in props.
  2. Translated Route Bindings:

    • Use {post:slug} in routes with Route::localize(). The SubstituteBindings middleware resolves the model in the correct locale.
  3. Fallback Locales:

    • Configure config/localizer.php:
      'fallback_locales' => ['en'],
      
    • Ensures unsupported locales (e.g., /es/about) fall back to en.
  4. Caching:

    • Routes are static and route:cache compatible. Run:
      php artisan route:cache
      
    • Clear cache when locales change:
      php artisan route:clear
      
  5. Testing:

    • Mock locale detection:
      Localizer::shouldReceive('detectLocale')->andReturn('fr');
      
    • Test redirects:
      $response = $this->get('/about');
      $response->assertRedirect('/fr/about');
      

Gotchas and Tips

Pitfalls

  1. Case-Sensitive Locale Prefixes:

    • /EN/about (wrong case) will 404 unless you configure case-insensitive matching in Route::localize() (not supported by default; requires custom regex).
    • Fix: Use lowercase in URLs or configure a custom detector to normalize case.
  2. Middleware Order:

    • Symptom: Translated route bindings (e.g., {post:slug}) resolve to the wrong locale.
    • Cause: SetLocale runs after SubstituteBindings.
    • Fix: Reorder middleware in Kernel.php:
      protected function middlewareGroup($group, array $middleware)
      {
          // Remove existing middleware
          $middleware = collect($middleware)->reject(fn ($item) =>
              $item instanceof SetLocale || $item instanceof RedirectLocale
          )->toArray();
      
          // Append in correct order
          return array_merge($middleware, [
              SetLocale::class,
              RedirectLocale::class,
          ]);
      }
      
  3. Route Defaults Leak:

    • Symptom: Route::localizedUrl() appends route defaults as query params (e.g., /about?view=home).
    • Fix: Updated in v1.2.2; ensure you’re on the latest version.
  4. Session Locale Persistence:

    • Symptom: Locale resets on page refresh.
    • Cause: Missing localizer_locale cookie or session driver.
    • Fix: Ensure SESSION_DRIVER is file, database, or redis in .env.
  5. Ziggy/TypeScript Issues:

    • Symptom: route() helper fails in browser with "invalid regexp group".
    • Cause: Ziggy v1 shipped PCRE-only regex flags (e.g., (?i)).
    • Fix: Upgrade to LocalizerBladeRouteGeneratorV2 (v1.3.2+).
  6. Default Locale Visibility:

    • Symptom: /about (default locale) doesn’t show locale prefix even when hide_default_locale: false.
    • Cause: RedirectLocale skips default locale by default.
    • Fix: Set 'hide_default_locale' => false in config.
  7. Route Name Confusion:

    • Symptom: $route->getName() returns with_locale.about instead of about.
    • Fix: Use Localizer::baseName($route->getName()) or the baseName() macro:
      $route->baseName(); // Returns 'about'
      

Debugging Tips

  1. Log Locale Detection: Add to AppServiceProvider:

    Localizer::detectLocale(); // Log the result
    
  2. Inspect Route Registration: Dump registered routes:

    php artisan route:list | grep localizer
    

    Look for with_locale.* and without_locale.* prefixes.

  3. Disable Redirects Temporarily: Set 'redirect' => false in config to debug without redirects.

  4. Check Middleware: Verify SetLocale and RedirectLocale are registered:

    php artisan middleware:list
    
  5. Test Locale Switcher: Manually set the locale cookie:

    curl -H "Cookie: localizer_locale=fr" http://localhost/about
    
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.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor