skip to Main Content

I have to setup a multi-language application with Laravel 11, this is the first time that I use multi-language feature in laravel, I will not use any package, I will set it manually, so I prepared the web.php file like this :

Route::group(['middleware' => ['setLocale']], function () {
    Route::get('/products/{slug}', [ProductController::class, 'fetchProduct']);
});
Route::group(['middleware' => ['setLocale'], 'prefix' => '{locale?}', 'where' => ['locale' => 'en|fr|de|jp']], function () {
    Route::get('/', LandingController::class);
    Route::get('/products/{slug}', [ProductController::class, 'fetchProduct']);
});

When I access ‘/products/fr/exemple-product’ it works but when I tried to access to the default route like this: ‘/products/exemple-product’ it doesn’t work and handles an error:
Too few arguments to function App\Http\Controllers\Front\ProductController::fetchProduct(), 1 passed in C:\...\ControllerDispatcher.php on line 46 and exactly 2 expected

this is the definition of the fetchProduct method :

public function fetchProduct($locale = null, $slug) {dd($slug);}

Even if I set $locale to null, it doesn’t work.

2

Answers


  1. You cannot have an optional parameter before a required one, i.e. you cannot have ($lang = null, $slug).

    Swapping them is a no-go since laravel, in this case, injects the parameters based on the order they appear in the url.

    A solution could be to create a separate function for the route with different parameters. An even better solution is to use a package such as mcamara/laravel-localization to handle this requirement for you.

    routes.php

    Route::group(['middleware' => ['setLocale']], function () {
        Route::get('/products/{slug}', [ProductController::class, 'fetchProductWithoutLocale']);
    });
    
    Route::group(['middleware' => ['setLocale'], 'prefix' => '{locale?}', 'where' => ['locale' => 'en|fr|de|jp']], function () {
        Route::get('/products/{slug}', [ProductController::class, 'fetchProduct']);
    });
    

    Controller.php

    public function fetchProduct($locale, $slug) {dd($slug);}
    
    public function fetchProductWithoutLocale($slug) {
      $locale = config('app.fallback_locale'); // or your logic to retrieve a default
    
      return $this->fetchProduct($locale, $slug);
    }
    
    Login or Signup to reply.
  2. The positioning of the parameters in the method fetchProduct is the problem on there. You cannot have an optional parameter before a required one. When the method is called, it will assume the first parameter is also required thereby assigning the value passed to the $locale variable and requiring you to provide a second argument for $slug. The positioning of the parameters should be swapped as below to rectify this.

    public function fetchProduct($slug, $locale = null){}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search