orkhanahmadov/laravel-accept-language-middleware
Lightweight Laravel middleware that reads the Accept-Language request header and sets the application locale automatically. It parses language preferences, matches them against your configured locales, and falls back gracefully. Easy to register and works without configuration.
example.com/fr/... over cookie-only or header-only detection is a product decision with SEO, cacheability, and analytics consequences. This package makes header detection cheap as a fallback layer underneath a URL-first strategy, which is the pattern most teams converge on. It does not replace the decision — it removes the excuse for not doing it.App::setLocale. It does not do translation content management, review workflows, RTL layout, currency/date formats, database content localization, hreflang emission, or CDN Vary handling. Treating it as an i18n strategy is the most likely PM-level mistake here.Adopt when:
example.com/ landing, deep links from search or email that lack a locale segment).Accept-Language you currently ignore.Look elsewhere or build in-house when:
pt-BR vs pt_BR vs pt-br), und/zxx handling, and weighted-wildcard semantics are not fully covered. If correct RFC 7231 content negotiation is a requirement (e.g., a public API with contractual behaviour), you want a fuller negotiation library or a custom resolver.Default recommendation: adopt behind an owned interface, pin ^3.0, and treat the package as replaceable. It is small enough that the exit cost is near zero — which is exactly why the decision doesn't deserve a long debate.
For executives — one paragraph. We can serve visitors in their own language from day one of a market launch instead of waiting on a routing or personalization project. This is a small, free, open-source component that reads the language the browser already sends and applies it automatically. Cost is roughly a day of engineering plus a day of QA; the benefit is that launching a new language becomes a content task rather than a software project, and multilingual API clients stop getting English by default. The risk is proportionate: single maintainer, low adoption, so we wrap it behind our own boundary and can replace it in under a day if needed. Decision needed: approve adoption as a thin utility, not as our localization strategy.
For engineering — the short version. Standard Laravel package: Composer, service provider, publishable config listing supported locales and a fallback. Registers as global or route middleware, parses weighted Accept-Language, sets the locale per request. 3.0.1 adds a guard so * is never assigned as the application locale — verify that path explicitly, since * is a legitimate header value from crawlers and privacy browsers, and previously produced app()->getLocale() === '*', broken route() output, and missing translation keys.
Three things we own regardless of the package:
Accept-Language → app fallback → config default, defined in exactly one place.*, *, fr;q=0.8, missing header, ?locale=*, and an unsupported locale. Assert the resulting locale, not the implementation.Vary: Accept-Language on any header-negotiated route, and re-run the matrix under config:cache and Octane, where locale state can leak across requests.Success metrics to watch post-launch: share of sessions served in a non-default locale; support tickets tagged "wrong language"; bounce rate on locale-redirect landing pages; and locale-mismatch reports from API partners. If "wrong language" tickets don't fall, the problem is almost always session precedence or a stale cached locale list — not this middleware.
How can I help you explore Laravel packages today?