jeffersongoncalves/laravel-locale-cookie
Persist and restore your Laravel app's locale with a simple cookie. This package detects, stores, and applies the user's chosen language across requests, making localized apps feel seamless without extra config or middleware boilerplate. Lightweight and easy to integrate.
Install the package via Composer:
composer install jeffersongoncalves/laravel-locale-cookie
Publish the config file (if the package provides one):
php artisan vendor:publish --tag=locale-cookie-config
The package provides middleware that reads a locale from a cookie and sets the application locale. Register the middleware in app/Http/Kernel.php (or bootstrap/app.php for Laravel 11+) — typically in the web group after session/cookie middleware.
First use case: support multiple languages via URL prefixes (e.g. /en/about, /fr/about). Define routes with a dynamic {locale} parameter:
Route::prefix('{locale}')
->middleware(\JeffersonGoncalves\LocaleCookie\Middleware\SetLocaleFromCookie::class)
->group(function () {
Route::get('/', [HomeController::class, 'index']);
});
With v1.5.0, when no locale cookie is present and the URL contains a {locale} segment, the package falls back to that route parameter. This makes the initial visit to a localized URL work without requiring a cookie first.
Start by testing a simple route that returns app()->getLocale(). Switch languages by setting the cookie manually or via a language-switcher endpoint, then revisit the localized URL to confirm the cookie takes precedence.
Middleware placement: Put the locale middleware in the web group so it runs after EncryptCookies and StartSession. If you use it on API routes, ensure cookie encryption is either enabled or disabled consistently.
Route groups with {locale}: Define a top-level prefix group:
Route::prefix('{locale}')
->middleware(SetLocaleFromCookie::class)
->whereIn('locale', ['en', 'fr', 'de'])
->group(function () {
// all localized routes
});
Language switcher: Create a controller action that validates the target locale, sets the cookie (Cookie::queue('locale', $locale, 60*24*365)), and redirects back. The middleware will pick up the cookie on subsequent requests.
Generating localized URLs: Use route('name', ['locale' => app()->getLocale()]) to include the current locale. For convenience, set a default via URL::defaults(['locale' => app()->getLocale()]) in a service provider or middleware.
Fallback chain: The package’s middleware likely resolves locale in this order: cookie → route {locale} parameter (v1.5.0+) → app default. This matches common expectations: explicit user choice (cookie) wins, then the URL, then config fallback.
Integration with route model binding: When using {locale} alongside other parameters, keep {locale} first in the URI pattern to avoid ambiguity (e.g. /{locale}/posts/{post}). Laravel matches segments left-to-right, so {locale} first is essential.
Testing: In feature tests, set the cookie via $this->withCookie('locale', 'fr') and assert the response locale. Also test the new fallback by hitting a localized URL without a cookie.
EncryptCookies is applied before the locale middleware; otherwise the cookie value will be unreadable.web group, the locale middleware should run after StartSession (so sessions are available if needed) but before route model binding — placing it early in the group is usually correct. If you need the locale for route resolution, put it before SubstituteBindings.{locale}, be careful if you already have a route parameter named {locale} elsewhere. The package will use the first matching parameter. Avoid using {locale} for non-language purposes.spatie/laravel-responsecache), include the locale in the cache key. The cookie-based locale can cause users to see cached content in the wrong language if caching ignores cookies.{locale}: When using URL::defaults(['locale' => ...]), ensure the default is set before generating URLs. A common pattern is to set it in a middleware that runs after the locale middleware.app()->getLocale() inside a route. Temporarily log the cookie value and the route parameter. The package may silently fall back to the app default if the cookie is missing or invalid.whereIn constraint on the {locale} route parameter to restrict values and avoid 404s for unsupported languages.url-prefix mode. If you use a different mode (e.g. query string or session), the {locale} parameter won’t be considered. Verify your config’s mode setting.{locale} parameter exists.How can I help you explore Laravel packages today?