Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

lat4732's avatar
Level 12

Multi-language website with URL prefix

Hello buds!

I'm stuck on trying to achieve a multi language website with URL prefix like:

site.com -> default locale
site.com/en -> en locale
site.com/category/bathroom -> default locale
site.com/en/category/bathroom -> en locale

I've read many threads but still didn't found a solution. What I've tried so far:|

Route::group(['prefix' => '{lang?}', 'middleware' => 'language'], function() {
    Route::get('/', [WebController::class, 'home'])->name('home');
    Route::get('/category/{category:slug}', [WebController::class, 'category'])->name('category');
});
class LanguageMiddleware
{
    public function handle($request, Closure $next)
    {
        $locale = $request->segment(1);
        $languages = config('app.locales');

        if (in_array($locale, $languages)) {
            app()->setLocale($locale);
        } else {
            app()->setLocale(config('app.fallback_locale'));
        }

        return $next($request);
    }
}

While hitting site.com/en/category/bathroom I get a proper view, but when I try to access it without any lang prefix like site.com/category/bathroom I get a 404 Not Found error.

Here is my php artisan route:list:

  POST       _ignition/execute-solution ........................... ignition.executeSolution › Spatie\LaravelIgnition › ExecuteSolutionController
  GET|HEAD   _ignition/health-check ....................................... ignition.healthCheck › Spatie\LaravelIgnition › HealthCheckController
  POST       _ignition/update-config .................................... ignition.updateConfig › Spatie\LaravelIgnition › UpdateConfigController
  GET|HEAD   api/user ........................................................................................................................... 
  GET|HEAD   sanctum/csrf-cookie .............................................. sanctum.csrf-cookie › Laravel\Sanctum › CsrfCookieController@show
  GET|HEAD   {lang?} .................................................................................................. home › WebController@home
  GET|HEAD   {lang?}/category/{category} ...................................................................... category › WebController@category
0 likes
3 replies
lat4732's avatar
Level 12

@MohamedTammam Hey!

This solution doesn't work for my case. First of all, I don't want when hitting the index route of the website to get redirected to "another" route. Second, when having a route with another parameters:

Route::group(['prefix' => '{lang?}', 'middleware' => 'language'], function() {
    Route::get('/', [WebController::class, 'home'])->name('home');
    Route::get('/category/{categorySlug}', [WebController::class, 'category'])->name('category');
});

I can't get it work. When I hit site.com/en/category/bathroom it works, but when I hit site.com/category/bathroom it simply gives me 404 Not found, probably because the route pattern {lang?} is optional and matches all URLs that do not explicitly include a language prefix, which results in confusion with other routes. Have a look at my routes list

Please or to participate in this conversation.