Laravel localization and routes from Jetstream / Fortify

12.6k Views Asked by At

I have this new Laravel project to work on. We would like to make it available in multiple languages.

I started the project with JetStream. Routes for authentication and such are automatically handled by JetStream / Fortify. I then added https://github.com/mcamara/laravel-localization to handle the localization. it works fine for the routes I created myself :

Route::group(
    [
        'prefix' => LaravelLocalization::setLocale(),
        'middleware' => [ 'localeSessionRedirect', 'localizationRedirect', 'localeViewPath' ]
    ], function()
{
    Route::get('/', function () {
        return view('welcome');
    });

    Route::middleware(['auth:sanctum', 'verified'])->get('/dashboard', function () {
        return view('dashboard');
    })->name('dashboard');
});

But how can I set the group, prefix and middleware on the routes handled by Jetstream and Fortify?

[EDIT]

So after some suggestions from @TEFO, I'm trying to add a middleware to handle setting the locale. Added :

Fortify.php :

    'path' => '{lang}',
    'middleware' => ['web', 'setLang']

new middleware setLang :

class SetLang {
    /**
     * Handle an incoming request.
     *
     * @param \Illuminate\Http\Request $request
     * @param \Closure $next
     * @return mixed
     */
    public function handle(\Illuminate\Http\Request $request, Closure $next) {
        // $lang = 'en';
        // $request->attributes->add(['lang' => 'en']);
        $request->route()->setParameter('lang', 'en');
        // $request->request->set('lang', 'en');

        return $next($request);
    }
}

Added the middleware to $routeMiddleware.

I'm receiving this error when trying to reach http://mylaravel/en/login :

ErrorException
Missing required parameters for [Route: login] [URI: {lang}/login]. (View: /var/www/resources/views/auth/login.blade.php)
4

There are 4 best solutions below

2
On BEST ANSWER

Finally successfully nailed this. I simply disabled routes from Fortify and Jetstream, copied them over and shoved them inside my grouped prefix routes. Still using https://github.com/mcamara/laravel-localization but it should work anyway you want it - make your own system or whatever, as long as you control the routes you're good to go.

In JetstreamServiceProvider :

public function register() {
        Jetstream::ignoreRoutes();
    }

In FortifyServiceProvider :

public function register() {
        Fortify::ignoreRoutes();
    }

And copy over routes from Fortify vendor/laravel/fortify/routes/routes.php and Jetstream vendor/laravel/jetstream/routes/livewire.php (I guess adapt to Inertia if you're working with this) over to your web.php file, inside a route group with the prefix you need.

0
On

I made a new Laravel Project using Jetstream. I wanted to use multi-language support in my project, but when I used Prefix (en/login, de/login) according to languages in url, I was also having a problem with Route. I solved my problem by following these steps. I hope you will be useful too:

1 - I have included the package on this https://github.com/mcamara/laravel-localization in my project. and followed the instructions sequentially.

2 - I made the Route settings in the "rautes\web.php" file as follows.

Route::group(['prefix' => LaravelLocalization::setLocale(),'middleware' => [ 
'localeSessionRedirect', 'localizationRedirect','localeViewPath' ]], function(){

/** ADD ALL LOCALIZED ROUTES INSIDE THIS GROUP **/
Route::get('/', function () {return view('welcome');});

Route::middleware(['auth', 'verified'])->get('/dashboard', function () {
    return view('back.dashboard');})->name('dashboard');
});

3 - I have included the in app\Http\Middleware\Kernel.php. In middlewareGroups end of web prefix.

protected $middlewareGroups = [
    'web' => [....
     \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes::class,            
     \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter::class,
     \Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect::class,
     \Mcamara\LaravelLocalization\Middleware\LocaleCookieRedirect::class,
     \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationViewPath::class,]

4 - Fortify Routes, include prefix in vendor\laravel\fortify\routes.php - Route::group like this:

Route::group(['prefix' => LaravelLocalization::setLocale(),
'middleware' => config('fortify.middleware', ['web'])], function () {
$enableViews = config('fortify.views', true);
.......

5 - Livewire Routes, include prefix in vendor\laravel\jetstream\routes\livewire.php - Route::group like this:

Route::group(['prefix' => LaravelLocalization::setLocale(),
'middleware' =>config('jetstream.middleware', ['web'])], function () {
if (Jetstream::hasTermsAndPrivacyPolicyFeature()) {

Route::get('/terms-of-service', [TermsOfServiceController::class, 'show'])- 
>name('terms.show');
    
Route::get('/privacy-policy', [PrivacyPolicyController::class, 'show'])- 
>name('policy.show');}

6 - If you want to separate backend and frontend, you can add in app\Http\Middleware\Kernel.php end of protected $routeMiddleware with prefix like in this https://github.com/mcamara/laravel-localization.

protected $routeMiddleware = [
........
    'localize'=> \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes::class,
    'localizationRedirect' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter::class,
    'localeSessionRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect::class,
    'localeCookieRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleCookieRedirect::class,
    'localeViewPath'     => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationViewPath::class,
]

7 - And the happy end...

0
On

I know this might be old issue, but I'm still facing it so my solution was to go to app\Providers\FortifyServiceProvider.php and add configureRoutes protected method to the boot method and override the method as following:

public function boot(): void
{
    $this->configureRoutes();
    // The rest of the boot method code
}

// override the configureRoutes method as following

protected function configureRoutes()
{
    if (Fortify::$registersRoutes) {
        Route::group([
            'namespace' => 'Laravel\Fortify\Http\Controllers',
            'domain' => config('fortify.domain', null),
            'prefix' => LaravelLocalization::setLocale(),
        ], function () {
               $this>loadRoutesFrom(base_path('vendor/laravel/fortify/routes/routes.php'));
        });
    }
}
0
On

I faced almost the same problem with the expection that i do not use mcamara/laravel-localization at the moment.

Based on the useful discussion above between @JeremyBelolo and @TEFO, the following solution worked for me:

  1. Added 'path' => '{locale}/my-secret-path' to config/fortify.php. As @JeremyBelolo and @ETO discussed, the support for that was recenlty added.
  2. Added my middleware before \Laravel\Jetstream\Http\Middleware\AuthenticateSession::class to the web $middlewareGroups
  3. Where my middleware set the locale app()->setLocale($locale); and the default {locale} url parameter URL::defaults(['locale' => $locale]); before passing the request deeper into the application.

Considering Jetstream I had to apply the same steps as @JeremyBelolo did, exept I didn't copy the jetsream/livewire routes but used the following inside the route group:

require base_path('vendor/laravel/jetstream/routes/livewire.php');

Now I can access {locale}/my-secret-path/login where {locale} is a supported locale for my site.

UPDATE [Fortify config option changed]:

The path fortify config option changed to prefix. Thus in config/fortify.php the following key should be used:

'prefix' => '{locale}/my-secret-path'