PHPackages                             enesthedev/translated-routes - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Localization &amp; i18n](/categories/localization)
4. /
5. enesthedev/translated-routes

ActiveLibrary[Localization &amp; i18n](/categories/localization)

enesthedev/translated-routes
============================

Simple route translation for Laravel 11+. Just add -&gt;translate() to your routes. Wildcard support, validation, export to JSON/JS/TS. Works with any locale management system.

3.2.0(6mo ago)121[2 PRs](https://github.com/enesthedev/translated-routes/pulls)MITPHPPHP ^8.2CI passing

Since Nov 2Pushed 1mo agoCompare

[ Source](https://github.com/enesthedev/translated-routes)[ Packagist](https://packagist.org/packages/enesthedev/translated-routes)[ Docs](https://github.com/enesthedev/translated-routes)[ GitHub Sponsors](https://github.com/Enes)[ RSS](/packages/enesthedev-translated-routes/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (3)Dependencies (13)Versions (7)Used By (0)

Laravel Translated Routes
=========================

[](#laravel-translated-routes)

[![Latest Version on Packagist](https://camo.githubusercontent.com/d14e418d2d752fbb60ffedeb0affc0369f31c4d0d3fccc90b3be5e6e8853dbd6/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f656e65737468656465762f7472616e736c617465642d726f757465732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/enesthedev/translated-routes)[![Total Downloads](https://camo.githubusercontent.com/6a5646e29029dadf5872f3ae0f72a179233645ac95af89b44df0231aa01569d4/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f656e65737468656465762f7472616e736c617465642d726f757465732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/enesthedev/translated-routes)

Simple, elegant route translation for Laravel 11+. Just add `->translate()` to your routes.

Why This Package?
-----------------

[](#why-this-package)

- **Zero configuration** - Works with Laravel's locale system
- **Native feel** - Uses `->translate()` macro on routes
- **Cache-optimized** - Built-in caching with configurable TTL
- **Inertia-ready** - Shares locale data automatically
- **No magic** - Simple translation lookup from `lang/{locale}/routes.php`

Installation
------------

[](#installation)

```
composer require enesthedev/translated-routes
```

```
php artisan vendor:publish --tag="translated-routes-config"
php artisan translated-routes:install
```

Quick Start
-----------

[](#quick-start)

### 1. Create Translation Files

[](#1-create-translation-files)

You have **two options** for organizing your translation files:

#### Option A: Separate Files Per Locale (Recommended)

[](#option-a-separate-files-per-locale-recommended)

**lang/en/routes.php**

```
return [
    'about' => 'about-us',
    'contact' => 'contact',
    'blog' => 'blog/{slug}',
    'products' => 'products/{category}/{id}',
];
```

**lang/tr/routes.php**

```
return [
    'about' => 'hakkimizda',
    'contact' => 'iletisim',
    'blog' => 'blog/{slug}',
    'products' => 'urunler/{category}/{id}',
];
```

#### Option B: Single File with All Locales

[](#option-b-single-file-with-all-locales)

**lang/routes.php**

```
return [
    'en' => [
        'about' => 'about-us',
        'contact' => 'contact',
        'blog' => 'blog/{slug}',
        'products' => 'products/{category}/{id}',
    ],
    'tr' => [
        'about' => 'hakkimizda',
        'contact' => 'iletisim',
        'blog' => 'blog/{slug}',
        'products' => 'urunler/{category}/{id}',
    ],
];
```

> **Note:** The package automatically detects which structure you're using. If `lang/routes.php` exists, it uses that. Otherwise, it looks for `lang/{locale}/routes.php`.

### 2. Use `->translate()` on Your Routes

[](#2-use--translate-on-your-routes)

```
use Illuminate\Support\Facades\Route;

// Single route translation
Route::get('about', [PageController::class, 'about'])
    ->name('about')
    ->translate();

Route::get('contact', [PageController::class, 'contact'])
    ->name('contact')
    ->translate();

Route::get('blog/{slug}', [BlogController::class, 'show'])
    ->name('blog.show')
    ->translate();

// Group translation - Option 1: translateGroup helper
Route::translateGroup(['middleware' => 'auth'], function () {
    Route::get('settings/profile', [ProfileController::class, 'edit'])->name('profile.edit');
    Route::get('settings/password', [PasswordController::class, 'edit'])->name('password.edit');
});

// Group translation - Option 2: Individual translate calls
Route::middleware('auth')->group(function () {
    Route::get('settings/profile', [ProfileController::class, 'edit'])
        ->name('profile.edit')
        ->translate();
    Route::get('settings/password', [PasswordController::class, 'edit'])
        ->name('password.edit')
        ->translate();
});
```

### 3. Set Your App Locale

[](#3-set-your-app-locale)

The package uses Laravel's `App::getLocale()`, so use any locale management package or middleware you prefer:

```
// In a middleware or wherever you set locale
App::setLocale('tr');
```

### 4. Results

[](#4-results)

When `App::getLocale()` is `'en'`:

```
/about-us
/contact
/blog/hello-world
/products/electronics/123

```

When `App::getLocale()` is `'tr'`:

```
/hakkimizda
/iletisim
/blog/hello-world
/urunler/electronics/123

```

**Parameters are automatically preserved!**

Inertia.js Support
------------------

[](#inertiajs-support)

### Backend

[](#backend)

Add the middleware to share locale data:

```
Route::middleware(['web', 'share-inertia-locale'])->group(function () {
    Route::get('about', [PageController::class, 'about'])->translate();
});
```

### Frontend (React/TypeScript)

[](#frontend-reacttypescript)

**types/index.d.ts**

```
export interface LocaleData {
  code: string;
  name: string;
  native: string;
  active: boolean;
}

export interface PageProps {
  locale: {
    current: string;
    default: string;
    supported: Record;
  };
}
```

**LanguageSwitcher.tsx**

```
import { usePage, router } from '@inertiajs/react';
import { PageProps } from '@/types';

export default function LanguageSwitcher() {
  const { locale } = usePage().props;

  const switchLocale = (code: string) => {
    // Use your preferred locale switching method
    router.post('/locale/switch', { locale: code });
  };

  return (

      {Object.values(locale.supported).map((lang) => (
         switchLocale(lang.code)}
          className={lang.active ? 'font-bold' : ''}
        >
          {lang.native}

      ))}

  );
}
```

**Current Locale Usage**

```
const { locale } = usePage().props;

console.log(locale.current);  // 'en' or 'tr'
console.log(locale.supported.tr.native);  // 'Türkçe'
```

API
---

[](#api)

### Route Macro

[](#route-macro)

```
// Translate a single route
Route::get('about', $action)->translate();

// Translate all routes in a group - Option 1 (Recommended)
Route::translateGroup(['middleware' => 'auth'], function () {
    Route::get('settings/profile', [ProfileController::class, 'edit']);
    Route::get('settings/password', [PasswordController::class, 'edit']);
});

// Translate all routes in a group - Option 2
Route::middleware('auth')->group(function () {
    Route::get('settings/profile', [ProfileController::class, 'edit'])->translate();
    Route::get('settings/password', [PasswordController::class, 'edit'])->translate();
});
```

### Facade

[](#facade)

```
use Enes\TranslatedRoutes\Facades\TranslatedRoutes;

// Get locale data for Inertia
TranslatedRoutes::getLocaleData();

// Get supported locales
TranslatedRoutes::getSupportedLocales();

// Clear cache
TranslatedRoutes::clearCache();
TranslatedRoutes::clearCache('en');
```

### Helper Function

[](#helper-function)

```
// Remove locale from URL
non_localized_url('/tr/about');  // Returns: '/about'
```

Configuration
-------------

[](#configuration)

```
// config/translated-routes.php

return [
    // Define your supported locales
    'supported_locales' => [
        'en' => ['name' => 'English', 'native' => 'English'],
        'tr' => ['name' => 'Turkish', 'native' => 'Türkçe'],
    ],

    // Cache settings
    'cache_enabled' => env('TRANSLATED_ROUTES_CACHE', true),
    'cache_ttl' => env('TRANSLATED_ROUTES_CACHE_TTL', 86400),
];
```

How It Works
------------

[](#how-it-works)

1. You define your routes with keys (e.g., `'about'`, `'contact'`)
2. You add `->translate()` to the route or group
3. The package looks up the translation in `lang/{App::getLocale()}/routes.php`
4. Route parameters (`{slug}`, `{id}`) are automatically preserved
5. The translated route is set and cached

Locale Management
-----------------

[](#locale-management)

This package **does not** manage locale switching. Use any method you prefer:

**Option 1: mcamara/laravel-localization**

```
Route::group([
    'prefix' => LaravelLocalization::setLocale(),
    'middleware' => ['localeSessionRedirect']
], function () {
    Route::get('about', $action)->translate();
});
```

**Option 2: Custom Middleware**

```
class SetLocale
{
    public function handle($request, $next)
    {
        if ($locale = $request->segment(1)) {
            if (in_array($locale, ['en', 'tr'])) {
                App::setLocale($locale);
            }
        }
        return $next($request);
    }
}
```

**Option 3: Session-based**

```
Route::post('/locale/switch', function (Request $request) {
    session(['locale' => $request->locale]);
    App::setLocale($request->locale);
    return back();
});

// In a middleware
App::setLocale(session('locale', 'en'));
```

Artisan Commands
----------------

[](#artisan-commands)

```
# Create translation files
php artisan translated-routes:install

# Clear cache
php artisan translated-routes:clear        # All locales
php artisan translated-routes:clear en     # Specific locale

# Validate translations
php artisan translated-routes:validate     # Check for missing/inconsistent translations

# List translated routes
php artisan translated-routes:list         # All locales
php artisan translated-routes:list --locale=en  # Specific locale

# Export translations
php artisan translated-routes:export --format=json  # Export to JSON
php artisan translated-routes:export --format=js    # Export to JavaScript
php artisan translated-routes:export --format=ts    # Export to TypeScript

# Profile performance
php artisan translated-routes:profile      # Benchmark translation performance
```

Advanced Usage
--------------

[](#advanced-usage)

### Wildcard Translations

[](#wildcard-translations)

Support for dynamic route patterns:

```
// lang/en/routes.php
return [
    'blog/*' => 'blog/*',
    'user/*/profile' => 'user/*/profile',
];

// lang/tr/routes.php
return [
    'blog/*' => 'blog/*',
    'user/*/profile' => 'kullanici/*/profil',
];
```

This allows matching multiple routes with a single pattern, reducing repetition.

### Translation Validation

[](#translation-validation)

Check your translations for consistency:

```
php artisan translated-routes:validate
```

### Export for Frontend

[](#export-for-frontend)

Export translations for SPA/PWA applications:

```
php artisan translated-routes:export --format=ts
```

Then use in your TypeScript application:

```
import { getRoute, type RouteKey, type Locale } from '@/translations/routes';

const route = getRoute('about', 'tr'); // 'hakkimizda'
```

### Named Routes with Parameters

[](#named-routes-with-parameters)

```
Route::get('blog', [BlogController::class, 'show'])
    ->name('blog.show')
    ->translate();

// Generate URL
route('blog.show', ['slug' => 'hello-world']);
// Result: /blog/hello-world (en) or /blog/hello-world (tr)
```

### API Routes

[](#api-routes)

```
Route::prefix('api')->group(function () {
    Route::get('user', [UserController::class, 'show'])->translate();
});
```

### Fallback

[](#fallback)

If a translation key doesn't exist, the original URI is used:

```
// lang/en/routes.php - 'missing-key' not defined

Route::get('missing-key', $action)->translate();
// Result: /missing-key (uses original URI)
```

Performance
-----------

[](#performance)

- **First request**: ~2ms (loads and caches translations)
- **Cached requests**: ~0.01ms (static memory cache)
- **Cache TTL**: Configurable (default 24 hours)

Real-World Example
------------------

[](#real-world-example)

```
// routes/web.php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\{HomeController, BlogController, ProductController};

Route::middleware(['web', 'share-inertia-locale'])->group(function () {

    // Home page
    Route::get('/', [HomeController::class, 'index'])->name('home');

    // Translated routes
    Route::group([], function () {
        Route::get('about', [HomeController::class, 'about'])->name('about');
        Route::get('contact', [HomeController::class, 'contact'])->name('contact');
        Route::get('services', [HomeController::class, 'services'])->name('services');

        Route::get('blog', [BlogController::class, 'index'])->name('blog.index');
        Route::get('blog/{slug}', [BlogController::class, 'show'])->name('blog.show');

        Route::get('products', [ProductController::class, 'index'])->name('products.index');
        Route::get('products/{category}/{id}', [ProductController::class, 'show'])->name('products.show');
    })->translate();

    // Forms
    Route::post('contact', [HomeController::class, 'contactSubmit'])->name('contact.submit')->translate();
});
```

What This Package Does
----------------------

[](#what-this-package-does)

✅ Translates route URIs based on `App::getLocale()`
✅ Preserves route parameters automatically
✅ Caches translations for performance
✅ Shares locale data with Inertia.js
✅ Provides `non_localized_url()` helper

What This Package Does NOT Do
-----------------------------

[](#what-this-package-does-not-do)

❌ Locale detection/switching (use other packages)
❌ Content translation (use Laravel's `trans()`)
❌ Session management (use Laravel's session)
❌ URL redirects (handle in your middleware)

Requirements
------------

[](#requirements)

- PHP 8.4+
- Laravel 11.0+

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

See [CHANGELOG](CHANGELOG.md) for more information.

License
-------

[](#license)

MIT License. See [License File](LICENSE.md) for more information.

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance81

Actively maintained with recent releases

Popularity8

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 77.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

3

Last Release

191d ago

PHP version history (2 changes)3.1.0PHP ^8.4

3.1.2PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/9f903405986a80e858576b51717a7c707e9bfc84f46be7e516bede7c2f01a311?d=identicon)[enesthedev](/maintainers/enesthedev)

---

Top Contributors

[![enesthedev](https://avatars.githubusercontent.com/u/16338242?v=4)](https://github.com/enesthedev "enesthedev (14 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (3 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (1 commits)")

---

Tags

laravellocalizationlaravel 11i18nroutesmultilinguallocaleseotranslated-routes

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/enesthedev-translated-routes/health.svg)

```
[![Health](https://phpackages.com/badges/enesthedev-translated-routes/health.svg)](https://phpackages.com/packages/enesthedev-translated-routes)
```

###  Alternatives

[codezero/laravel-localized-routes

A convenient way to set up, manage and use localized routes in a Laravel app.

543638.1k4](/packages/codezero-laravel-localized-routes)[tractorcow/silverstripe-fluent

Simple localisation for Silverstripe

92421.6k26](/packages/tractorcow-silverstripe-fluent)[opgginc/codezero-laravel-localized-routes

A convenient way to set up, manage and use localized routes in a Laravel app.

2770.1k1](/packages/opgginc-codezero-laravel-localized-routes)[smousss/laravel-globalize

Make Laravel projects translatable in a matter of seconds!

2266.3k](/packages/smousss-laravel-globalize)[jayesh/laravel-gemini-translator

An interactive command to extract and generate Laravel translations using Gemini AI.

691.7k1](/packages/jayesh-laravel-gemini-translator)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
