goodcat/laravel-l10n
A Laravel localization package for building multilingual apps, with helpers for locale detection, language switching, and localized routes/URLs. Lightweight and easy to integrate into existing Laravel projects.
Accept-Language header and matches the best available one, which is the behavior users actually expect when they arrive with a mixed-language preference list.RedirectToPreferredLocale middleware performs a once-per-session redirect to the user's preferred locale while preserving explicit locale switches. That converts "remember and honor the user's language choice" from a custom feature into a supported one — a real scope reduction for any product where language preference must persist across sessions without fighting the user when they deliberately switch.config('app.preferred_locale') becomes config('app.preferred_locales'), LocaleResolver::resolve() may now return a list, and the PreferredLocaleUpdated event's $locale/$previousLocale become $locales/$previousLocales. If we adopt, we inherit this cadence of breaking minor releases; scope migration work accordingly.LocalizedRoutes type and fixed TypeScript signatures (required/optional args and query options preserved) mean typed, locale-aware route helpers are a supported path rather than a hand-rolled wrapper.SessionLocale in v0.5.3 — session-managed locale preferences are now explicitly "bring your own LocaleResolver," so a product that needs per-user stored language preference (a database column, a profile setting) must plan custom resolver work rather than assume it is provided.getPreferredLocales() / optional $locales argument. Conversely, if the roadmap needs geo-IP-based or account-based locale selection, that remains custom.Consider adoption when:
Accept-Language entries, ranked matching against your supported locale list, and a once-per-session redirect that still respects a deliberate user switch. This is now the package's strongest single argument over native lang files.LocalizedRoutes type and the TypeScript signature fixes make typed locale-aware route generation viable; without a typed front end, this benefit is moot.Look elsewhere when:
lang files plus a commercial TMS, or a package with an active maintainer base.SessionLocale is deprecated and the once-per-session redirect keys off the session, not a user record. Products where language is a persisted profile setting will be writing a custom LocaleResolver and probably a custom persistence layer. That is fine, but it is no longer "free."preferred_locale → preferred_locales config rename and the event payload shape change before taking any further upgrades. Do not upgrade mid-sprint on a surface with live users.Mitigation if you proceed: fork it internally, vendor the source, add a named internal owner, pin to an exact version, and write a two-page exit plan for migration to native Laravel lang files plus a small custom resolver. Given the v0.5.3 breaking changes, also add a standing checklist item: read the changelog for every bump and treat every 0.x minor as potentially breaking.
For executives: This is a small, MIT-licensed Laravel component that lets us stand up basic app localization without custom engineering. The latest release adds the behavior users notice most — detecting the visitor's browser language, suggesting it once, and then respecting whatever they choose — plus typed route helpers for our front end. Those are features we would otherwise build. The trade-off is unchanged and worth restating: it is a community package with minimal adoption and it just shipped breaking API changes, so we would treat it as a starting point we own, not a platform we depend on. Recommendation: timebox a two-week proof of concept against our top locales, covering browser negotiation and locale-switch persistence, then decide whether to adopt, fork, or fall back to Laravel's built-in translation files.
For engineering: The package is opinionated, so adopting it means accepting its locale-resolution and translation-storage conventions. Expect to review the source, pin a version, and own upgrades — there is no community buffer at 17 stars and zero dependents, and v0.5.3 confirms we should treat every 0.x minor as potentially breaking. Concretely in this release: config('app.preferred_locale') is replaced by config('app.preferred_locales'); LocaleResolver::resolve() may now return an ordered list rather than a single locale; PreferredLocaleUpdated now carries $locales/$previousLocales instead of $locale/$previousLocale; SessionLocale is deprecated in favor of a custom resolver. New surface to evaluate: RedirectToPreferredLocale middleware (once-per-session, preserves explicit switches), getPreferredLocales() and the optional $locales argument for best-match selection, and the exported Wayfinder LocalizedRoutes type with corrected TypeScript signatures for required/optional args and query options. Upside is that it removes boilerplate and gives us a consistent pattern across services; downside is potential lock-in, single-maintainer risk, and a live breaking-change cadence. Please assess the diff against native lang files before we commit, and name an internal owner.
For design/content: Localization conventions will be set by this package's defaults, which may constrain string formatting, pluralization, and fallback display. One behavior change is worth a design decision: the app will now pick the best match from the user's full browser language list and, once per session, redirect first-time visitors to it — so the user's first impression of language is inferred, not chosen. Decide whether that redirect is desirable for our audience (it usually is for consumer-facing, less so for internal tools where a URL or account setting should win) and make sure a deliberate switch is never overridden. Loop content in before we commit so we don't hard-code assumptions we later have to unwind.
How can I help you explore Laravel packages today?