4
votes

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)
3
I saw this but it's not really the same... It's a fixed prefix where I need a variable one - Jeremy Belolo
i know. but what you can do is put a parameter prefix like /{lang} and fill it with a middleware. - TEFO
Interesting! Apparently I can define what middleware to use in the fortify config file as well. But it wouldnt work for the routes defined in jetstream, right? - Jeremy Belolo
yes currently you cant define a prefix for jetstream but you can make you own route. the main package that do real authentication is fortify so if you have to customize your a lot or dont work with livewire and inertia jetstream is not a fit for your project - TEFO

3 Answers

12
votes

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.

3
votes

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'

0
votes

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...