Middleware Parameters

Passing Parameters to Middleware

Anything after a colon in a middleware name is split on commas and passed to handle after $next. locale:en,ms,zh therefore reaches SetLocale as three strings, which a variadic parameter collects:

The handle method of app/Http/Middleware/SetLocale.phpPHP
public function handle(Request $request, Closure $next, string ...$allowed): Response
{
    $allowed = $allowed ?: [config('app.locale')];
    $locale = in_array($request->query('lang'), $allowed, true)
        ? $request->query('lang')
        : $request->getPreferredLanguage($allowed);        // reads Accept-Language
    App::setLocale($locale);                               // __() now uses lang/<locale>
    $response = $next($request);
    $response->headers->set('Content-Language', $locale);
    $response->setVary('Accept-Language', false);          // caches must key on it
    return $response;
}

The built-in throttle:3,1 works the same way: three requests per minute, per user or IP. With $K and $B from Middleware Aliases and Sorting, ask for Malay and Chinese greetings, then hit the stock route four times:

A parameterized locale switch and throttle:3,1Shell
curl -si -H "$K" -H 'Accept-Language: ms-MY,ms;q=0.9' $B/greeting \
  | grep -i '^content-lang\|^vary\|text'
curl -s -H "$K" "$B/greeting?lang=zh"; echo
for i in 1 2 3 4; do curl -s -o /dev/null $B/stock/978-1-4919-0456-8 \
  -w '%{http_code} %header{x-ratelimit-remaining} %header{retry-after}\n'; done
Output
Content-Language: ms
Vary: Accept-Language
{"text":"Selamat datang ke kedai buku"}
{"text":"\u6b22\u8fce\u5149\u4e34\u4e66\u5e97"}
200 2
200 1
200 0
429 0 60

getPreferredLanguage matched ms-MY to ms; an unlisted fr falls back to en. Parameters arrive as strings, so cast and validate them. For per-user or per-plan limits, define a named limiter with RateLimiter::for() and use throttle:name (Rate Limiting Routes).