Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Locale Collection Laravel Package

wotz/laravel-locale-collection

A Laravel package that treats your app's supported locales as a collection, making it easy to register, query, and manage languages with clean helpers built for Laravel's container and views. Lightweight and configurable.

View on GitHub
Deep Wiki
Context7

Getting Started

The package is tiny and undocumented in the wild (0 stars, 0 dependents), so treat the source as the docs. Start here:

  1. Install and inspect the diff.

    composer require wotzebra/laravel-locale-collection
    

    Then open vendor/wotzebra/laravel-locale-collection/src/ and read two files first: the service provider (to see what it binds/singletons) and the config file (to see the shape of a "locale entry"). Everything else is a thin wrapper over those.

  2. Publish config before writing any code.

    php artisan vendor:publish --provider="Wotz\LocaleCollection\LocaleCollectionServiceProvider"
    

    The config file is where you declare supported locales. Do not scatter ['en','fr','de'] arrays through your app — the whole point of this package is to make that config the single source of truth.

  3. Smoke-test the binding.

    // tinker
    app(\Wotz\LocaleCollection\LocaleCollection::class)->all();
    // or the facade if one is registered
    \Wotz\LocaleCollection\Facades\LocaleCollection::all();
    

    If you get back an array/Collection of locale objects or codes, you're wired up. If it autowires as a plain Illuminate\Support\Collection instead, check the provider's alias/binding name — this is the most common first stumble with small packages.

  4. First real use case: kill the hardcoded locale list. Replace:

    $locales = ['en', 'fr', 'nl'];
    

    with a loop over the collection, and use the package to answer "is this locale supported?" in middleware/validation instead of in_array($x, config('app.locales')).

Once that's done, the second use case is almost always the language switcher in the navbar — see below.

Implementation Patterns

Config as the source of truth, plus a thin presenter. Keep native names, direction (LTR/RTL), and any regional metadata in the config array, and let the collection resolve the current locale against it. This prevents the classic bug where config('app.locale') says en_US but your switcher only knows en.

// config/locale-collection.php (typical shape for a package like this)
'locales' => [
    'en' => ['name' => 'English',  'native' => 'English',  'dir' => 'ltr'],
    'fr' => ['name' => 'French',   'native' => 'Français', 'dir' => 'ltr'],
    'ar' => ['name' => 'Arabic',   'native' => 'العربية',  'dir' => 'rtl'],
],
'fallback' => 'en',

Locale-prefixed routing with a single middleware. The standard Laravel pattern, made cleaner by pulling the supported set from the package:

Route::middleware(\Wotz\LocaleCollection\Http\Middleware\SetLocale::class)
    ->prefix('{locale}')
    ->whereIn('locale', LocaleCollection::codes()->all())
    ->group(function () {
        Route::get('/', HomeController::class)->name('home');
    });

If the package ships its own middleware, use it rather than rolling one — but verify it actually calls App::setLocale() and sets the session, otherwise url()->previous() and redirects will wobble between locales.

Language switcher that preserves the current path. Don't link to / — users expect to stay on the equivalent page:

@foreach (\Wotz\LocaleCollection\Facades\LocaleCollection::all() as $code => $locale)
    <a href="{{ route(
        request()->route()->getName(),
        array_merge(request()->route()->parameters(), ['locale' => $code])
    ) }}" @class(['font-bold' => app()->getLocale() === $code])>
        {{ $locale['native'] }}
    </a>
@endforeach

Persist the choice, then apply it on every request. Session is fine for guests; add a locale column for authenticated users and let a global middleware prefer the user column over the session over config('app.fallback_locale'). Wire the switcher as a small POST route that writes to both and redirects back.

Sync Carbon and validation. Two lines that are easy to forget and cause subtle bugs:

Carbon::setLocale($locale);                 // dates in the wrong language otherwise
'locale' => ['required', 'string', Rule::in(LocaleCollection::codes())],

Put the Carbon call in the same middleware that calls App::setLocale().

Testing helper. Wrap "set the app locale for this test" in a base-test-case method that goes through the package ($this->actingAsLocale('fr')) so your tests exercise the same code path as production.

Gotchas and Tips

  • Zero stars means zero StackOverflow answers. Pin the exact version in composer.json, and when behaviour surprises you, dump() inside the provider. Budget an hour to read the whole src/ directory — it will be short.
  • Unpublished config = silent no-op. Many small Laravel packages merge defaults in register() but only read the published file. If nothing works, check config('locale-collection') in tinker before blaming your code.
  • config:cache in production. If your locale list only lives in a runtime-edited config (e.g. an admin panel writes to the config file), it will not update until you re-run php artisan config:cache. Prefer a DB-backed source and feed the package from it if locales are user-managed.
  • Locale string normalisation. en_US vs en-us vs en is the #1 source of "why is my switcher blank" bugs. Normalise to one casing at the boundary and compare against LocaleCollection::codes() — never against raw request input.
  • App::setLocale() does not do what users think. It changes validation messages and __() lookup but not Carbon, not the <html lang> attribute, and not cached responses. Handle each separately.
  • Middleware ordering. If you have \Illuminate\Session\Middleware\StartSession after your locale middleware in the priority list, session-stored locales won't be readable. Add your middleware to $middlewarePriority in bootstrap/app.php (Laravel 11+) or Kernel.php (10 and below) immediately after StartSession.
  • Cache/query interactions. If you cache rendered pages per-locale, include the locale in the cache key — the fallback locale will happily serve the wrong page otherwise.
  • Extension points. If the collection is bound as a singleton, you can app()->instance(...) in a service provider for tests; look for a ->extend()/->macro() hook in the collection class before reaching for that. For anything missing (e.g. a toSelectOptions() helper for form dropdowns), a Laravel Collection::macro in a service provider is the lean fix and won't fight the package.
  • Don't confuse UI locale with content translation. This package (per the name and scope) handles the former. If you also need per-model translated fields, pair it with spatie/laravel-translatable — they solve different problems and mixing the two concepts causes architectural pain later.
  • Debugging checklist when a page renders in the wrong language: (1) app()->getLocale() in tinker, (2) config('app.fallback_locale'), (3) middleware order, (4) browser Accept-Language if the package does auto-detection, (5) the lang/ files actually exist for that code.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console