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',