Search code examples
laravellocalizationtranslationlaravel-routinglaravel-8

Laravel 8 route() does not localize strings


EDIT: found the answer to all my questions: https://github.com/codezero-be/laravel-localized-routes (and, of course, 42).

I'm working on a multi-language website where the URL's contain localized strings. For instance:

https://site/en/members/john-doe
https://site/nl/leden/john-doe
(and so for every language)

In web.php, I prefixed my routes. Via middleware, I set the current language (retrieved from the first URL-segment). This works fine for everything (both in controllers and in blade)... except for the URLs generated by route(). They are always in the default language. Even though everything else is correctly localized. If I dump app()->getLocale() in a controller of blade it shows the correct language. Only the URLs generated by the route()-function are always in the default fallback language.

I've tried moving my middleware-class higher up in the middleware-groups list. That didn't make a difference.

web.php

Route::prefix('{lang}')->group(function() {
        Route::get(trans('routes.members') . '/{username}/', 'MembersController@profile')
            ->name('members.show');
}

SetLanguage middleware

... 
public function handle(Request $request, Closure $next)  
{  
        $lang = $request->segment(1) ?? app()->getLocale(); 

        //set app language  
        app()->setLocale($lang);  
        //set default url parameter  
        URL::defaults(['lang' => $lang]);  
        return $next($request);  
    }  
...

App\Http\Kernel.php

...
protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Laravel\Jetstream\Http\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \App\Http\Middleware\SetLanguage::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
            \App\Http\Middleware\UserLastSeenAt::class,
        ],
        ...

Solution

  • Got it (with a little help from a friend)

    In the AppServiceProvider's boot function I've added

     public function boot(Request $request)
     {
            //set app language
            app()->setLocale($request->segment(1) ?? app()->getLocale());
      }
        
    

    & the SetLanguage-middleware now only contains

    public function handle(Request $request, Closure $next)
    {
        //set default url parameter
        URL::defaults(['lang' => app()->getLocale()]);
         return $next($request);
     }
    

    That did the trick!