PHPackages                             veltix/wayfinder-locales - 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. veltix/wayfinder-locales

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

veltix/wayfinder-locales
========================

Multilingual route + translation generation extending Laravel Wayfinder.

v2.0.1(1mo ago)0105↓93.7%MITPHPPHP ^8.2

Since Feb 10Pushed 1w agoCompare

[ Source](https://github.com/veltix/wayfinder-locales)[ Packagist](https://packagist.org/packages/veltix/wayfinder-locales)[ RSS](/packages/veltix-wayfinder-locales/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (6)Dependencies (17)Versions (7)Used By (0)

veltix/wayfinder-locales
========================

[](#veltixwayfinder-locales)

Localized route URLs and type-safe TypeScript translation catalogs for [Laravel Wayfinder](https://github.com/laravel/wayfinder).

One logical route, a different URL per locale:

```
products       →  /products        /de/produkte      /fr/produits
products.show  →  /products/{id}   /de/produkte/{id} /fr/produits/{id}

```

…plus `t()` / `tChoice()` over your `lang/` files, with a `TranslationKey` union so a typo is a build error rather than a string that renders as itself.

> **This is v3. It targets `laravel/wayfinder: dev-next` (the `next` branch) and nothing else.**The stable `^0.1` line is not supported. See [UPGRADING.md](UPGRADING.md).

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

[](#requirements)

- PHP 8.2+
- Laravel 12 or 13
- `laravel/wayfinder: dev-next`

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

[](#installation)

```
composer require veltix/wayfinder-locales
php artisan vendor:publish --tag=wayfinder-locales-config
```

The service provider is auto-discovered. On boot it registers:

- the `Route::localized()` macro,
- the `setlocale` middleware alias,
- the `wayfinder-locales:generate` artisan command,
- a `Routes` converter binding that adds localized URL templates to Wayfinder's own generation.

How it works
------------

[](#how-it-works)

The two halves of the package are independent, and only one of them generates files.

**Routes.** Laravel serves a single `{locale}`-parameterised URI. `Route::localized()` tags the route with a per-locale path segment map; at generation time the package's converter — bound over Wayfinder's `Converters\Routes` — turns that into a template table the generated function picks from. So localized routes come out of `wayfinder:generate`, not out of a second generator.

**Translations.** `wayfinder-locales:generate` reads `lang/` and writes the frontend catalogs. It has nothing to do with routing and never writes into `resources/js/wayfinder` — that directory is Wayfinder's, and `wayfinder:generate` deletes anything there it did not write itself.

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

[](#configuration)

Everything lives in `config/wayfinder-locales.php`. There is one locale list and one default locale, shared by both halves.

```
return [
    'locales' => ['en', 'de'],
    'default_locale' => env('WAYFINDER_DEFAULT_LOCALE', 'en'),

    'enabled' => env('WAYFINDER_LOCALES_ENABLED', true),
    'mode' => env('WAYFINDER_LOCALES_MODE', 'segment'),
    'strict' => env('WAYFINDER_LOCALES_STRICT', true),

    'locale_parameter' => env('WAYFINDER_LOCALE_PARAMETER', 'locale'),
    'hide_default_prefix' => env('WAYFINDER_HIDE_DEFAULT_PREFIX', false),

    'exclude_groups' => ['routes'],
    'action_key' => 'wayfinder_locales',
];
```

keywhat it does`locales`Every locale generated for. Drives the `Locale` union, the catalog modules, and the locales `setlocale` will accept.`default_locale`Seeds the `TranslationKey` union, is the runtime's fallback for a missing key, and is the locale whose URL prefix `hide_default_prefix` drops. Should be in `locales`.`enabled`Turn off localized URL emission without unwinding your `Route::localized()` calls.`mode``segment` replaces the first static slug segment after the locale. `tail` treats the translation as the whole localized path tail.`strict`Throw on malformed `localized()` metadata instead of skipping the route.`locale_parameter`The URI parameter carrying the locale.`hide_default_prefix`Register an unprefixed twin (`{name}.default`) for the default locale and emit its URL without the prefix.`exclude_groups`Lang groups kept out of the frontend catalogs.`action_key`Route action key `localized()` stashes its map under. Change only on a collision.Localized routes
----------------

[](#localized-routes)

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

Route::middleware('setlocale')->group(function () {
    Route::get('/{locale}/products', [ProductController::class, 'index'])
        ->name('products')
        ->localized(['en' => 'products', 'de' => 'produkte']);

    Route::get('/{locale}/products/{product}', [ProductController::class, 'show'])
        ->name('products.show')
        ->localized(['en' => 'products', 'de' => 'produkte']);
});
```

Use `{locale?}` if the segment may be omitted; the generated function fills in `default_locale`.

With `hide_default_prefix => true` and `default_locale => 'en'`, `localized()` also registers an unprefixed twin named `products.default` bound to `en`, so `/products` and `/en/products` both resolve.

Then run Wayfinder as usual:

```
php artisan wayfinder:generate
```

```
import products from '@/wayfinder/routes/products';

products.url({ locale: 'de' });              // "/de/produkte"
products.show.url({ locale: 'de', product: 7 }); // "/de/produkte/7"
```

The `locale` argument is typed to the locales that route declares, so `products.url({ locale: 'es' })`is a type error.

On the server, `lroute()` fills the locale parameter in for you:

```
lroute('products');            // active locale
lroute('products', [], 'de');  // "/de/produkte"
```

Translations
------------

[](#translations)

Point `locales` at your lang directories and generate:

```
php artisan wayfinder-locales:generate
```

```
resources/js/translations/
├── en.ts          # flat catalog, its own lazily-loaded chunk
├── de.ts
├── keys.ts        # TranslationKey union + per-key placeholder types
├── locales.ts     # Locale union, locales[], defaultLocale, setLocale/getLocale
└── index.ts       # t(), tChoice(), loadLocale()

```

`lang/{locale}/{group}.php` becomes dotted keys (`messages.nested.key`), `lang/{locale}.json`contributes its keys verbatim, and `lang/vendor/{package}/{locale}` becomes `package::group.key`. The default locale's catalog is the source of truth for the key union.

Tell the runtime which locale is active once, at boot — a getter is re-read on every lookup, which is what you want with Inertia:

```
import { loadLocale } from '@/translations';
import { setLocale } from '@/translations/locales';

setLocale(() => usePage().props.locale);
await loadLocale('de');
```

```
import { t, tChoice } from '@/translations';

t('messages.greeting', { name: 'Ada' });  // placeholders are typed per key
tChoice('messages.apples', 3);
```

Missing keys fall back to the default locale's catalog, then to the key itself — the same order Laravel's `__()` uses.

Commands
--------

[](#commands)

command`php artisan wayfinder:generate`Wayfinder's own. Emits routes and actions, localized URLs included.`php artisan wayfinder-locales:generate [--path=]`Emits the translation output. `--path` is the JS root, default `resources/js`.License
-------

[](#license)

MIT

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance95

Actively maintained with recent releases

Popularity12

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 95.5% 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 ~28 days

Recently: every ~35 days

Total

6

Last Release

46d ago

Major Versions

v0.0.4 → v2.0.02026-07-02

PHP version history (2 changes)v0.0.1PHP ^8.2

v0.0.4PHP ^8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/f2bc1d8551638205f4ec624ec9bd3619e16f0dd94baa576246eaf90d08f631c8?d=identicon)[Veltix](/maintainers/Veltix)

---

Top Contributors

[![veltix](https://avatars.githubusercontent.com/u/46252663?v=4)](https://github.com/veltix "veltix (21 commits)")[![vdisain-staging](https://avatars.githubusercontent.com/u/263354160?v=4)](https://github.com/vdisain-staging "vdisain-staging (1 commits)")

---

Tags

laravellocalizationi18nroutestypescriptwayfinder

###  Code Quality

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/veltix-wayfinder-locales/health.svg)

```
[![Health](https://phpackages.com/badges/veltix-wayfinder-locales/health.svg)](https://phpackages.com/packages/veltix-wayfinder-locales)
```

###  Alternatives

[laravel/ai

The official AI SDK for Laravel.

1.1k4.6M322](/packages/laravel-ai)[erag/laravel-lang-sync-inertia

A powerful Laravel package for syncing and managing language translations across backend and Inertia.js (Vue/React/Svelte) frontends, offering effortless localization, auto-sync features, and smooth multi-language support for modern Laravel applications.

5031.3k](/packages/erag-laravel-lang-sync-inertia)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

79227.1M228](/packages/laravel-mcp)[laravel/wayfinder

Generate TypeScript representations of your Laravel actions and routes.

1.8k10.6M159](/packages/laravel-wayfinder)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9922.4M146](/packages/roots-acorn)[psalm/plugin-laravel

Psalm plugin for Laravel

3345.4M354](/packages/psalm-plugin-laravel)

PHPackages © 2026

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