Weave Code
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 Multilingual Routes Laravel Package

chinleung/laravel-multilingual-routes

Register multilingual Laravel routes from a single definition. Automatically generates locale-prefixed URLs based on configured locales, with optional default-locale prefixing. Includes middleware to detect request locale and switch the app locale accordingly.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require chinleung/laravel-multilingual-routes
    

    Ensure compatibility with your Laravel version (check version matrix).

  2. Middleware Setup: Add DetectRequestLocale as the first middleware in bootstrap/app.php:

    $middleware->web(prepend: [DetectRequestLocale::class]);
    
  3. Configure Locales: Publish the config and set app.locales (e.g., ['en', 'fr']):

    php artisan vendor:publish --provider="ChinLeung\MultilingualRoutes\MultilingualRoutesServiceProvider" --tag="config"
    

    Or use chinleung/laravel-locales for dynamic locale management.

  4. First Route: Replace manual locale-specific routes (e.g., Route::get('/fr', ...)) with:

    Route::multilingual('/', 'HomeController')->name('home');
    

    This auto-generates / (en) and /fr/ (fr) routes.


Where to Look First

  • Route Translations: Check resources/lang/{locale}/routes.php for URI translations (e.g., 'test' => 'teste' for French).
  • Helper Functions: Use localized_route(), current_route(), and current_route_is() in Blade/views or controllers.
  • Demo Repository: laravel-multilingual-routes-demo for real-world examples.

First Use Case

Scenario: A bilingual blog with English (/posts) and French (/articles) URLs. Solution:

  1. Define translations in resources/lang/fr/routes.php:
    return ['posts' => 'articles'];
    
  2. Register the route:
    Route::multilingualResource('posts', 'PostController');
    
  3. Access routes dynamically:
    // English: /posts
    localized_route('posts.index');
    
    // French: /articles
    localized_route('posts.index', [], 'fr');
    

Implementation Patterns

Core Workflows

1. Route Registration

  • Basic Route:

    Route::multilingual('contact', 'ContactController')->name('contact');
    

    Generates:

    • GET /contact (en.contact)
    • GET /fr/contact (fr.contact) if translated in routes.php.
  • Resource Routes:

    Route::multilingualResource('products', 'ProductController')
         ->only(['index', 'show'])
         ->middleware('auth');
    

    Supports all Laravel resource features (e.g., withTrashed, missing, parameters).

2. Locale-Specific Customization

  • Dynamic Names:
    Route::multilingual('home')->names(['en' => 'home', 'fr' => 'accueil']);
    
  • Locale Restrictions:
    Route::multilingual('admin')->only(['en']); // Only English
    Route::multilingual('promo')->except(['fr']); // Exclude French
    

3. View Routes

  • Default View:
    Route::multilingual('about'); // Loads `about.blade.php`
    
  • Custom View/Data:
    Route::multilingual('team')->view('members', ['active' => true]);
    

4. Redirects and Checks

  • Redirects:
    Route::multilingual('old-page')->redirect('new-page');
    
  • Route Checks:
    if (Request::localizedRouteIs('dashboard')) { ... }
    

Integration Tips

1. With Laravel Localization Packages

  • Use chinleung/laravel-locales to dynamically manage locales (e.g., user-selected languages).
  • Example:
    // app/Providers/AppServiceProvider.php
    public function boot()
    {
        $locales = Locale::getSupportedLocales(); // From laravel-locales
        config(['app.locales' => $locales]);
    }
    

2. API Routes

  • For APIs, prefix routes with /api and ensure locale detection works:
    Route::prefix('api')->group(function () {
        Route::multilingual('v1/users', 'UserController');
    });
    
  • Use localized_route() in API responses for consistent URLs.

3. Middleware for Locale-Specific Logic

  • Create middleware to modify behavior per locale:
    public function handle(Request $request, Closure $next)
    {
        if ($request->routeIs('fr.*')) {
            // French-specific logic
        }
        return $next($request);
    }
    

4. Testing

  • Use actingAs() with locale switching:
    $response = $this->actingAs($user)->withHeaders(['Accept-Language' => 'fr'])
        ->get(localized_route('home'));
    

Gotchas and Tips

Pitfalls

1. Missing Translations

  • Issue: Routes fail silently if translations are missing in routes.php.
  • Fix: Validate translations during deployment or use a fallback:
    Route::multilingual('blog')->fallbackLocale('en'); // Fallback to English
    

2. Route Caching

  • Issue: Route caching (php artisan route:cache) may not update multilingual routes.
  • Fix: Clear cache after adding new locales/translations:
    php artisan route:clear
    php artisan route:cache
    

3. Locale Detection Conflicts

  • Issue: DetectRequestLocale may override other middleware (e.g., session-based locales).
  • Fix: Place it first in the middleware stack and avoid duplicate locale detection.

4. Resource Route Parameters

  • Issue: Forgetting to translate parameterized URIs (e.g., photos/{photo}).
  • Fix: Always include translations for dynamic segments:
    // resources/lang/fr/routes.php
    return [
        'photos/{photo}' => 'photos/{photo_id}'
    ];
    

5. Signed Routes

  • Issue: signedLocalizedRoute() may break if the locale changes.
  • Fix: Use absolute URLs or ensure the signed route’s locale matches the request:
    URL::signedLocalizedRoute('unsubscribe', [], 'fr');
    

Debugging Tips

1. Route Listing

  • Dump all multilingual routes to debug:
    Route::get('/debug-routes', function () {
        return response()->json(Route::getRoutes()->getByName());
    });
    

2. Locale Detection

  • Log the detected locale in middleware:
    public function handle($request, Closure $next)
    {
        \Log::info('Detected locale:', ['locale' => app()->getLocale()]);
        return $next($request);
    }
    

3. Translation Overrides

  • Temporarily override translations for testing:
    app()->setLocale('fr');
    Route::multilingual('test')->translations(['test' => 'debug']);
    

Extension Points

1. Custom Route Generator

  • Extend the package by creating a custom route generator:
    use ChinLeung\MultilingualRoutes\RouteGenerator;
    
    class CustomRouteGenerator extends RouteGenerator
    {
        public function generate($uri, $locale)
        {
            // Custom logic (e.g., add API version)
            return parent::generate($uri, $locale) . '/v1';
        }
    }
    
    Bind it in AppServiceProvider:
    $this->app->bind(RouteGenerator::class, function () {
        return new CustomRouteGenerator();
    });
    

2. Dynamic Locale Switching

  • Add a route to switch locales dynamically:
    Route::get('/switch-locale/{locale}', function ($locale) {
        app()->setLocale($locale);
        return redirect()->back();
    })->name('switch.locale');
    

3. Fallback Routes

  • Implement a fallback for missing locales:
    Route::multilingual('fallback')->fallback(function ($request) {
        return redirect()->route('home');
    });
    

4. Custom URI Translations

  • Load translations from a database or API:
    // Override the translation resolver
    Route::multilingual('dynamic')->translations(function ($locale, $uri) {
        return DB::table('route_translations')->where('uri', $uri)->where('locale', $locale)->first()->translated_uri
    
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope