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 Localized Routes Laravel Package

codezero/laravel-localized-routes

A Laravel package for localized routes: automatically prefix routes with the current locale, translate route segments and route names, and generate localized URLs with the same route helper API you already use.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and publish the config:

composer require codezero/laravel-localized-routes
php artisan vendor:publish --provider="CodeZero\LocalizedRoutes\LocalizedRoutesServiceProvider" --tag="config"

Open config/localized-routes.php first — it is the whole API surface in one file. The two keys you will touch daily are supported_locales (a list of locales, optionally with display names) and the redirect/prefix options. Set the locales you actually ship:

'supported_locales' => ['en', 'nl', 'fr'],

Register the middleware in the web group of app/Http/Kernel.php so the locale is resolved from the URL and applied with App::setLocale() before your controllers run:

protected $middlewareGroups = [
    'web' => [
        // ...
        \CodeZero\LocalizedRoutes\Middleware\SetLocale::class,
    ],
];

Wrap the routes that should be localized. This registers each route once per supported locale under a {locale} prefix:

Route::localized(function () {
    Route::get('/', [HomeController::class, 'index'])->name('home');
    Route::get('/about', [PageController::class, 'about'])->name('about');
});

You now have /en/about, /nl/about, /fr/about. In Blade, swap route() for localized_route() — that is the single most important habit with this package:

<a href="{{ localized_route('about') }}">About</a>

That is a complete first use case: two languages, a nav bar, and locale-aware links.

Implementation Patterns

Group, don't repeat. Call Route::localized() once per logical section (public site, dashboard, auth) rather than per route. Everything inside inherits the prefix, the middleware, and the locale name suffixing. Nested groups with their own middleware work normally:

Route::localized(function () {
    Route::middleware('auth')->group(function () {
        Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');
    });
});

Locale switcher. Build it from the current route, preserving parameters so a user on /en/products/42 lands on /nl/products/42:

@foreach (config('localized-routes.supported_locales') as $locale)
    <a href="{{ localized_route(Route::currentRouteName(), [...request()->route()->parameters(), 'locale' => $locale]) }}">
        {{ strtoupper($locale) }}
    </a>
@endforeach

Translate the content, not just the URL. The package switches App::setLocale(), so __('messages.about'), validation messages, Carbon formatting, and pluralization all follow automatically. Keep translation files in lang/{locale}/ and this package becomes free i18n plumbing.

Localized slugs. If you want /en/about vs /nl/over-ons, define separate named routes inside conditionals on app()->getLocale(), or use a model accessor / resolveRouteBinding() to translate entity slugs per locale. The prefix handles the locale segment; the rest of the path is yours.

Testing. Pass the locale explicitly, since there is no request context in some test setups:

$this->get(localized_route('about', 'nl'))->assertOk();
$this->get('/nl/about')->assertSee('Over ons');

Consistency with auth scaffolding. Laravel's RouteServiceProvider::HOME and the Authenticate middleware redirect to route('login') / RouteServiceProvider::HOME. Override redirectTo() in app/Http/Middleware/Authenticate.php to return localized_route('login') so unauthenticated users keep their locale.

Gotchas and Tips

  • route() will silently give you the wrong URL. Route names are registered per locale (suffixed internally), and the plain route() helper resolves a default. Use localized_route() everywhere, including in emails, notifications, and redirects. This is the #1 source of "why am I on /en when I clicked Dutch?"
  • Console and queued jobs have no locale. localized_route('invoice.show', $invoice) has no request to read the locale from. Pass the locale explicitly as the second argument or set it with App::setLocale($user->locale) at the top of the job. For mailables, capture the recipient's locale, not the sender's.
  • route:list explodes. Every route appears once per locale. That is expected; filter with php artisan route:list --path=nl when hunting a specific one.
  • Don't reuse {locale}. It is a reserved parameter name inside the localized group. A route that also has {locale} in its own path will collide.
  • Middleware ordering matters. SetLocale should sit early in the web group so session, auth, and view composers see the correct locale. If you use mcamara/laravel-localization style packages alongside it, pick one — two locale middlewares will fight over App::setLocale().
  • Redirects at the root. Set redirect_to_localized_url to send / to the default locale, and use omit_url_prefix_for_locale if you want your default locale to be unprefixed (/about instead of /en/about) — but then remember that only one locale is prefix-free, and your switcher must handle both shapes.
  • use_property_fallback controls whether a missing translated model property falls back to the default locale. Turn it on if your content is partially translated; turn it off if you would rather see blanks and catch missing translations in QA.
  • Cache config and routes as usual — php artisan config:cache && php artisan route:cache works because the macro expands at boot. Just re-run both after editing supported_locales, otherwise new locales will 404 in production.
  • Extension point: the Localizer facade (CodeZero\LocalizedRoutes\Facades\Localizer) exposes the current locale, supported locales, and whether the current route is localized. Use it in view composers and middleware instead of reaching into app()->getLocale() directly, so behaviour stays consistent if you later change prefix or redirect settings.
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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core