saleh_mir's avatar

How to prefixing in routes for localization

I just want to be a prefix translated routes and when user hit those routes the locale gets selected and all the config.url changes to serve with prefix included

I’ve tried this:

Route::group(['prefix' => 'ja'], function () {
    App::setLocale('ja');
    Route::get('/', 'PagesController@index');
});

But it doesn’t work, cuz the `App::setLocale('ja' gets run anyways!

Any idea?

0 likes
12 replies
starmatt's avatar
starmatt
Best Answer
Level 3

I've implemented a system that looks like what you need.

Here's an example route group:

web.php

// Main GET routes with locale
Route::prefix('{lang?}')->middleware('locale')->group(function() {

    Route::get('/', function () {
        return view('index');
    });
});

The rest happens in a middleware:

App/Http/Middleware/Locale.php

<?php

namespace App\Http\Middleware;

use Closure;

class Locale
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($request->method() === 'GET') {
            $segment = $request->segment(1);

            if (!in_array($segment, config('app.locales'))) {
                $segments = $request->segments();
                $fallback = session('locale') ?: config('app.fallback_locale');
                $segments = array_prepend($segments, $fallback);

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

            session(['locale' => $segment]);
            app()->setLocale($segment);
        }

        return $next($request);
    }
}

I've set up some new keys in the config/app.php array:


    'locale' => 'fr',

    'locales' => ['fr', 'en'],

    'fallback_locale' => 'fr',
9 likes
letsDesign's avatar

@starmatt , I am trying your solution but I got this error "Function name must be a string" please can you help me with that ?

cklow's avatar

@starmatt, i am using Laravel Framework 5.4.36. i am trying your solution but it is doesn't work if url without locale.

example:

Route::prefix('{lang?}')->middleware('locale')->group(function() {

    Route::get('/', function () { return view('index');  });

    Route::get('/author/{id}', function () { return view('author');  })->name('author');

});

it is can't work for www.domainname.com/author/1.

it is return error page

(1/1) NotFoundHttpException

in RouteCollection.php (line 180)

at RouteCollection->match(object(Request))in Router.php (line 546)

at Router->findRoute(object(Request))in Router.php (line 525)

at Router->dispatchToRoute(object(Request))in Router.php (line 511)

at Router->dispatch(object(Request))in Kernel.php (line 176)

at Kernel->Illuminate\Foundation\Http{closure}(object(Request))in Pipeline.php (line 30)

........

........

on the other hand, route('author', ['id' => 1]) generates www.domainname.com/author/1, doesn't this www.domainname.com/en/author/1.

please help me.

bshbair's avatar

@letsDesign add 'locale' middleware to $routeMiddleware definitions in app/Http/Kernel.php:

'locale' => \App\Http\Middleware\Locale::class
gummydummyk's avatar

How can it redirect to the same page after i change the language?

1 like
Wiezo's avatar
  1. How do you then link between pages.

  2. Can't get it to use English without it make /en/ in the url

vardges's avatar

Route::get('/', function () {

$locale = config('app.locale');
return redirect($locale);

});

alqahtani's avatar

It worked fine for me but I want to add Auth::routes() to the prefix routes group but it didn't work I returns Symfony \ Component \ HttpKernel \ Exception \ MethodNotAllowedHttpException

Mikegk's avatar

Hi,

I just wonder what

                $segments = array_prepend($segments, $fallback);

should do, because "array_prepend()" is not defined.

Please or to participate in this conversation.