Fixing Spatie’s Laravel ResponseCache to Respect Accept-Language

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 u…


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


Print Share Comment Cite Upload Translate Updates
APA

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/

MLA
" » Fixing Spatie’s Laravel ResponseCache to Respect Accept-Language." Dawid Makowski | Sciencx - Thursday August 21, 2025, https://www.scien.cx/2025/08/21/fixing-spaties-laravel-responsecache-to-respect-accept-language/
HARVARD
Dawid Makowski | Sciencx Thursday August 21, 2025 » Fixing Spatie’s Laravel ResponseCache to Respect Accept-Language., viewed ,<https://www.scien.cx/2025/08/21/fixing-spaties-laravel-responsecache-to-respect-accept-language/>
VANCOUVER
Dawid Makowski | Sciencx - » Fixing Spatie’s Laravel ResponseCache to Respect Accept-Language. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/08/21/fixing-spaties-laravel-responsecache-to-respect-accept-language/
CHICAGO
" » Fixing Spatie’s Laravel ResponseCache to Respect Accept-Language." Dawid Makowski | Sciencx - Accessed . https://www.scien.cx/2025/08/21/fixing-spaties-laravel-responsecache-to-respect-accept-language/
IEEE
" » Fixing Spatie’s Laravel ResponseCache to Respect Accept-Language." Dawid Makowski | Sciencx [Online]. Available: https://www.scien.cx/2025/08/21/fixing-spaties-laravel-responsecache-to-respect-accept-language/. [Accessed: ]
rf:citation
» Fixing Spatie’s Laravel ResponseCache to Respect Accept-Language | Dawid Makowski | Sciencx | 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.

You must be logged in to translate posts. Please log in or register.