App::setLocale()
is not persistent, and sets locale only for current request(runtime). You can achieve persistent in multiple ways (example of 2):
Route::post('/locale', function(){
session(['my_locale' => app('request')->input('locale')]);
return redirect()->back();
});
This will set session key
with lang
value from request for current user. Next create a Middleware
to set locale based on user session language
<?php namespace AppHttpMiddleware;
use Closure;
use IlluminateHttpRequest;
use IlluminateFoundationApplication;
class Language {
public function __construct(Application $app, Request $request) {
$this->app = $app;
$this->request = $request;
}
/**
* Handle an incoming request.
*
* @param IlluminateHttpRequest $request
* @param Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$this->app->setLocale(session('my_locale', config('app.locale')));
return $next($request);
}
}
This will get current session and if is empty will fallback to default locale, which is set in your app config.
In appHttpKernel.php
add previously created Language
middleware:
protected $middleware = [
AppHttpMiddlewareLanguage::class,
];
As global middlware or just for web (based on your needs).
I hope this helps, and gives an idea on how things are working.
Scenario №2 - Lang based on URL path
Create an array
with all available locales on your app inside app config
'available_locale' => ['fr', 'gr', 'ja'],
Inside the Middleware we will check the URL first segment en, fr, gr, cy
if this segment is in available_locale
, set language
public function handle($request, Closure $next)
{
if(in_array($request->segment(1), config('app.available_locale'))){
$this->app->setLocale($request->segment(1));
}else{
$this->app->setLocale(config('app.locale'));
}
return $next($request);
}
You will need to modify appProvidersRouteServiceProvider
for setting prefix to all your routes. so you can access them domain.com
or domain.com/fr/
with French language
Find: mapWebRoutes
And add this to it: (before add use IlluminateHttpRequest;
)
public function map(Request $request)
{
$this->mapApiRoutes();
$this->mapWebRoutes($request);
}
protected function mapWebRoutes(Request $request)
{
$locale = null;
if(in_array($request->segment(1), config('app.available_locale'))){
$locale = $request->segment(1);
}
Route::group([
'middleware' => 'web',
'namespace' => $this->namespace,
'prefix' => $locale
], function ($router) {
require base_path('routes/web.php');
});
}
This will prefix all your routes with country letter like 'fr gr cy' except en for non-duplicate content, so is better to not add into available_locales_array