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

I18N Routing Bundle Laravel Package

financeua/i18n-routing-bundle

Internationalized routing bundle for Laravel/PHP apps, adding locale-aware route generation and URL handling so your application can serve translated, language-prefixed routes with minimal configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

Read this first: it is not a Laravel package. financeua/i18n-routing-bundle is a fork of the long-abandoned BeSimpleI18nRoutingBundle — a Symfony bundle wired into Symfony's Routing, HttpKernel, and DI container. There is no service provider, no facade, no RouteServiceProvider hook, and nothing that registers with Illuminate\Routing. composer require-ing it into a Laravel app buys you colliding Symfony components, 0 stars, 0 dependents, and no maintainer. You cannot use it day-to-day in Laravel.

What you can take from it is the pattern: one logical route name, many locale-specific path segments (/en/products, /fr/produits, /de/produkte), resolved per active locale so route('products.index') "just works."

Where to look first (as a port reference only):

  1. Routing/Loader/ — where per-locale path maps are parsed into route definitions. This is the actual idea worth stealing.
  2. DependencyInjection/ — the i18n_routing config tree (locales, default_locale, redirect_to_host, use_route_name). Match these keys to your own config/localized-routes.php.
  3. README annotation examples — the per-locale path arrays; that shape is your config file.

First real use case, in Laravel: "I have /en/products and /fr/produits, both named products.index, and a locale switcher must generate the correct URL." Solve it with a maintained package, not this one:

composer require mcamara/laravel-localization      # prefix-first, 90% case
composer require codezero/laravel-localized-routes # translated slugs

If your need is only /{locale}/... with untranslated slugs, skip packages entirely — a native route group with {locale} and a whereIn constraint is a one-day build.

Implementation Patterns

The bundle's concepts, mapped to workflows you'd actually ship in Laravel.

1. Locale-prefixed groups — the default pattern. Mirrors the bundle's prefix-per-locale behavior with mcamara/laravel-localization:

Route::group([
    'prefix'     => LaravelLocalization::setLocale(),
    'middleware' => ['localeSessionRedirect', 'localizationRedirect', 'localeViewPath'],
], function () {
    Route::get('products', [ProductController::class, 'index'])->name('products.index');
});

Route names stay singular; route('products.index') emits the active locale's prefix. This is the invariant the Symfony bundle enforces through its loader — in Laravel you get it from the prefix + middleware stack.

2. Translated path segments — the bundle's actual feature. Use codezero/laravel-localized-routes, or a hand-rolled slug map:

Route::localized(function () {
    Route::get(Lang::uri('products'), [ProductController::class, 'index'])
        ->name('products.index');
});

Back it with a single source of truth:

// config/localized-routes.php
'supported_locales' => ['en', 'fr', 'de'],
'routes' => [
    'products.index' => ['en' => 'products', 'fr' => 'produits', 'de' => 'produkte'],
],

Centralizing this map is what keeps hreflang, canonicals, and the locale switcher from drifting.

3. Locale switcher. Generate the counterpart URL from the same route name and current params, not from string surgery:

@foreach (config('app.supported_locales') as $locale)
    <a href="{{ localized_route('products.index', $product, $locale) }}">{{ $locale }}</a>
@endforeach

4. Middleware order matters. Put locale detection (localeSessionRedirect, localizationRedirect) before auth/web middleware that might redirect, and make the default-locale redirect a 301 — not a 302 — so you don't churn SEO.

5. hreflang + canonical. Emit from the route map, one entry per locale, plus x-default. Drive both from the same config that drives Lang::uri(), so a new locale is one config edit.

Gotchas and Tips

  • Framework mismatch is the headline gotcha. Symfony's RequestContext, RouterInterface, and UrlMatcher/UrlGenerator contracts don't exist in Laravel. Any adapter you build becomes a first-party component you own and must re-test on every Laravel upgrade. The port is almost always cheaper than the bridge.
  • Route cache staleness. Both php artisan route:cache and any config-driven slug map go stale after locale additions. Rebuild caches in deploy when config/localized-routes.php or translations change; otherwise you ship 404s for a language that "exists."
  • Wrong-locale route() generation. This is the failure mode everyone hits: a route registered under one locale's prefix and resolved while another locale is active. Keep prefixes and names 1:1, and if a name isn't localized, ensure it has no prefix or you'll double-prefix (/fr/en/products).
  • Default-locale redirect. Missing the / → /{default_locale}/ 301 produces duplicate content and two ways in to every page. Also decide whether the prefix is stripped or required for the default locale — changing that later is an SEO-visible break.
  • Prefix stripping/duplication. Custom middleware that strips a prefix and also lets the route group add one is the #1 source of 404s and double prefixes. One place owns prefixing.
  • Abandonment risk. Upstream is dead: 0 stars, 0 dependents, no CVE coverage, no Symfony 6/7 guarantees, unknown PHP constraint. Routing is the highest-blast-radius layer in the app — every URL flows through it. Treat the repo as reading material, not a dependency.
  • Name collisions across locale variants. If you do register per-locale variants (products.index.en), route() resolution order becomes load-bearing and brittle. Prefer one name + locale-aware generation.
  • Extension points to emulate, not inherit. The bundle's config keys (locales, default_locale, use_route_name, redirect_to_host) are a decent spec for your own config file — borrow the shape, write the implementation; it's ~a day of work and you own the tests.
  • Debugging tip. When a URL renders in the wrong language, dump app()->getLocale(), the matched route name (Route::currentRouteName()), and the generated URL side by side. Nearly every i18n routing bug is one of those three disagreeing.
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.
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
nodisrupt/laravel-agent
sierratecnologia/media-manager