This content originally appeared on DEV Community and was authored by Dawid Makowski
I’ll be honest. Few things are more frustrating than solving a problem by reaching for a great package… only to realize the problem is still there. That was me last week, yelling at my API like it had just spoiled the finale of a Netflix show.
I was using Spatie’s Laravel ResponseCache package. It’s rock solid, it works out of the box, and it’s built by people I trust. But here’s the kicker: I turned it on in production and suddenly my multilingual API was speaking one language only. The first request cached in English. Every Arabic request after that? Still English.
So here’s what it took to fix it. I hope it will help some lost soul on the internet one day.
Photo by Douglas Lopes on Unsplash
The Problem
Spatie’s ResponseCache builds cache keys from the host, normalized URI, HTTP method, and a suffix (usually the user ID). That works fine most of the time, but it completely ignores request headers like Accept-Language
.
Which means:
- First request with
Accept-Language: en
→ response cached in English - Second request with
Accept-Language: ar
→ still gets the English version
My API became linguistically challenged.
The Fix: Middleware That Cares About Language
Spatie lets you influence the cache key by setting a per-request attribute called responsecache.cacheNameSuffix
. All we have to do is populate it with something that changes when the language changes.
Here’s the middleware I ended up shipping:
<?php
declare(strict_types=1);
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
class SetResponseCacheSuffixFromLanguage
{
public function handle(Request $request, Closure $next)
{
// Take the first language from the Accept-Language header
$accept = Str::of($request->header('Accept-Language', ''))
->before(',')
->replace('_', '-')
->lower()
->value();
// Add user id if you want to separate caches per user
$userId = auth()->id();
$suffix = implode('|', array_filter([$userId, $accept]));
if ($suffix !== '') {
$request->attributes->set('responsecache.cacheNameSuffix', $suffix);
}
// Optional: add a debug header so you can see what suffix is being used
$response = $next($request);
if ($suffix !== '') {
$response->headers->set('X-ResponseCache-Suffix', $suffix);
}
return $response;
}
}
Registering the Middleware
In Laravel 12, add it globally in bootstrap/app.php
:
use App\Http\Middleware\SetResponseCacheSuffixFromLanguage;
use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withMiddleware(function (Middleware $middleware) {
$middleware->append(SetResponseCacheSuffixFromLanguage::class);
})
->create();
Now the cache key varies by Accept-Language
and you no longer serve Arabic users the English version of your API.
Adding the Vary Header
If you’re running behind AWS ALB or a CDN, make sure your responses include Vary: Accept-Language
. Otherwise proxies and browsers might serve the wrong cached version.
Just drop this into the middleware:
$response->headers->set(
'Vary',
trim(($response->headers->get('Vary') ?: '') . ', Accept-Language', ', ')
);
Don’t Forget to Clear Old Cache
The existing cache entries are language-agnostic, so clear them once:
php artisan responsecache:clear
How to Prove It Works
Run these two curls and check the header:
curl -H 'Accept-Language: en' https://api.example.com/v1/pages -I | grep X-ResponseCache-Suffix
curl -H 'Accept-Language: ar' https://api.example.com/v1/pages -I | grep X-ResponseCache-Suffix
You should see en
vs ar
. That’s your proof the cache is now language-aware.
Will be chasing Spatie's team to add this to the package as well, fingers crossed!
This content originally appeared on DEV Community and was authored by Dawid Makowski

Dawid Makowski | Sciencx (2025-08-21T09:18:38+00:00) Fixing Spatie’s Laravel ResponseCache to Respect Accept-Language. Retrieved from https://www.scien.cx/2025/08/21/fixing-spaties-laravel-responsecache-to-respect-accept-language/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.