Joshua Leung
Joshua Leung

Reputation: 2399

How to set dynamic route prefix in Laravel?

I need to create an app with multiple locales. And each route is prefixed with the locale. For example, xxx.com/en/home, xxx.com/fr/home.

The thing is, I need to dynamically bind the locale string to route prefix. Since users can change locale, the locale string is stored in session. And I need reference to the session on web.php. Session object can't be used in the globle scope on web.php, meaning session('key') won't get you anything (null) in the outermost scope except in route functions because Laravel parses web.php before instantiating any session object, I think. Therefore I face a conundrum in that I can't reference session in the outermost scope on web.php while I need session to create dynamic prefix. How can I solve this?

Upvotes: 2

Views: 12464

Answers (3)

Sanjit Singh
Sanjit Singh

Reputation: 276

I am not sure about your scenario and the complexity of you app, but I would try to keep things simple by generating all the routes at once something like

$locales = [
    'en',
    'ru',
];

foreach ($locales as $locale) {
    Route::group(['prefix' => $locale], function() {
        Route::get('route1',function(){});
        Route::post('route1',function(){});
    });
} return false;

and then I would write a middleware that parse the locale and set it accordingly. Hope it helps.

Upvotes: -1

Arseny Dugin
Arseny Dugin

Reputation: 59

You can use something like this:

Route::prefix(App::getLocale())->middleware('lang')->group(function () { 
    // Routes
});

Lang middleware:

class Language {

    public function handle(Request $request, Closure $next)
    {
        $locale = $request->segment(1);

        if (in_array($locale, config('app.locales'))) {
            \App::setLocale($locale);
            return $next($request);
        }

        if (!in_array($locale, config('app.locales'))) {

            $segments = $request->segments();
            $segments[0] = config('app.fallback_locale');

            return redirect(implode('/', $segments));
        }
    }

}

Upvotes: 4

sykez
sykez

Reputation: 2158

I recently prefixed my routes with locale and I found it pretty easy to implement using mcamara's Laravel Localization package. After setting up the package installation, I just had to add a route group for all the URLs I wanted with locale prefix.

Route::group([
    'prefix' => LaravelLocalization::setLocale(),
    'middleware' => ['localeSessionRedirect', 'localizationRedirect']
], function()
{
   Route::get('/contact', 'HomeController@contact_page');
});

Upvotes: 3

Related Questions