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

Extended Routes Laravel Package

andrey-helldar/extended-routes

Extended Routes adds convenient helper methods to Laravel's router so you can define routes and route groups with less boilerplate. A lightweight package for cleaner, more expressive route files in Laravel applications.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a small, single-purpose package: it swaps in a slightly richer Route facade and adds naming/localization helpers on top of Laravel's router. Treat it as a thin convenience layer, not a framework.

Minimal steps

composer require andrey-helldar/extended-routes

Laravel's package auto-discovery registers the service provider. If you are on an older Laravel or have discovery disabled, add the provider manually in config/app.php:

'providers' => [
    AndreyHelldar\ExtendedRoutes\ServiceProvider::class,
],

No config file, no migrations, no publish step. Existing routes/*.php files are untouched — the package decorates the router, it does not replace route definition syntax.

Where to look first

  1. vendor/andrey-helldar/extended-routes/src/ — the whole package is a handful of files. Read the facade class and the service provider before using anything; the public method list is shorter than the README implies, and the source is the only authoritative documentation (the docs are thin).
  2. php artisan route:list — confirm your existing routes still resolve and names are unchanged after install.
  3. composer show andrey-helldar/extended-routes — check the installed version and its illuminate/* constraints against your Laravel version before committing to it. Version 4.0.1 is the current patch (see Gotchas: it only corrects dependency constraints, it does not widen framework support).

First use case

The honest first use case is: you already have named routes, you want to resolve names in fewer keystrokes and handle locale-prefixed groups without hand-building route() calls. A two-minute smoke test:

use Illuminate\Support\Facades\Route;

Route::get('/posts', fn () => 'ok')->name('posts.index');

// Verify the package facade is bound, not just Laravel's
dump(Route::class);            // should resolve to the package facade if aliased
dump(Route::currentRouteName());
dump(route('posts.index'));

If that works and route:list is unchanged, the package is safe to adopt incrementally. If you are starting a new project, do not adopt it — see Gotchas.

Implementation Patterns

1. Localized route groups (the main real-world win)

The package's localization support is aimed at the pattern where each locale gets its own prefixed group and a name prefix, so route('posts.index', ['locale' => 'de']) produces /de/posts without you repeating the prefix in every definition.

foreach (config('app.locales', ['en', 'de', 'fr']) as $locale) {
    Route::prefix($locale)
        ->name("$locale.")
        ->group(function () {
            Route::get('/posts', [PostController::class, 'index'])->name('posts.index');
            Route::get('/posts/{post}', [PostController::class, 'show'])->name('posts.show');
        });
}

Use the package helpers to resolve the current locale's name instead of interpolating the prefix manually. Where you would otherwise write route(app()->getLocale() . '.posts.index'), the package gives you a name-resolution helper that reads the active locale — verify the exact signature in src/ on install, then wrap it once in your own helper so a future package swap is a one-line change:

// app/Support/routes.php
function localized_route(string $name, array $params = []): string
{
    return route(app()->getLocale() . '.' . $name, $params);
}

2. Resolving route names in middleware and controllers

The enhanced facade is most useful where you need the current route's name as data — breadcrumbs, active-nav state, analytics, permission mapping:

use Illuminate\Support\Facades\Route;

$name = Route::currentRouteName();   // 'de.posts.show'

// Strip the locale prefix the package added
[$locale, $base] = array_pad(explode('.', $name, 2), 2, null);

Prefer this over request()->route()->getName() only if you want the package's normalization; otherwise stay native. Since the underlying object is still Laravel's router, everything is interchangeable — you are not locking yourself in at the call site.

3. Name-based authorization / feature gating

Map route names to abilities in one place rather than scattering checks:

// config/route-abilities.php
return [
    'posts.index'  => 'posts.view',
    'posts.show'   => 'posts.view',
    'posts.store'  => 'posts.create',
    'posts.update' => 'posts.edit',
    'posts.destroy'=> 'posts.delete',
];

Then a single middleware resolves Route::currentRouteName(), strips the locale prefix, and checks Gate::allows(config("route-abilities.$base")). This is where the package earns its keep — one normalized name, one lookup table, all locales covered.

4. Language switcher / URL generation

For a switcher that preserves the current page across locales, resolve the base name and regenerate:

$current = Route::currentRouteName();          // 'de.posts.show'
$base    = Str::after($current, '.');          // 'posts.show'
$params  = request()->route()->parameters();   // ['post' => 42]

$url = route('fr.' . $base, $params);

Guard with Route::has('fr.' . $base) so locales that intentionally lack a translation fall back to home rather than throwing RouteNotFoundException at render time.

5. Blade integration

Keep Blade dumb. Register a directive or a view composer that exposes the normalized name, so templates never call the router directly:

Blade::directive('active', fn ($expr) => "<?php echo Route::currentRouteName() === $expr ? 'active' : ''; ?>");

6. Route caching

The package claims route-cache compatibility because it decorates the router rather than registering routes dynamically. That holds only if your localized groups are defined inside routes/*.php and nowhere else — see below.

Gotchas and Tips

4.0.1 is a packaging patch, not a revival. The only change in the latest release is a dependency-constraint fix. It does not add features, change router behaviour, or extend the supported Laravel range. Read it as "someone can still install this on a supported dependency set", not as "actively maintained": there is still no changelog of router-level work and the project remains low-traffic. Run the full test suite plus php artisan route:cache && php artisan route:clear on the target Laravel version before relying on it. If the dependency fix is what makes it installable on your stack, pin the version explicitly ("andrey-helldar/extended-routes": "4.0.1") so a future constraint change is a deliberate upgrade. For a greenfield project, the whole feature set is ~50 lines of your own code — write it yourself and keep the dependency count down.

Dependency constraints can silently move under you. Because the release was constraint-only, composer update on a patch range is exactly the operation that changes which illuminate/* versions you get. Commit composer.lock, and after any update re-run route:list and one localized URL resolution — that catches the realistic failure mode here (a resolution binding that no longer matches) far faster than reading release notes.

Facade alias collision. The package ships its own Route facade. If you globally alias it, every use Illuminate\Support\Facades\Route; import in your app still points at Laravel's class, and you get confusing "method does not exist" errors. Either import the package facade explicitly at each call site, or — better — keep Laravel's facade as the default and call the package facade only where the extra helpers are needed. Never register both under the same alias.

Facade swap breaks Route::has()-style static analysis. IDE helpers and PHPStan Laravel plugins are trained on Illuminate\Support\Facades\Route. Expect a wave of undefined-method warnings. Add a @method docblock stub or exclude the package facade from static analysis.

Route caching and closures. route:cache fails on closure routes — unrelated to this package, but localized groups make it tempting to inline closures per locale. Always use controller arrays in files that must be cacheable.

Localized names vs. route() resolution. route('posts.index') will throw once you name everything de.posts.index; the default name no longer exists. Either keep an unprefixed default locale group or audit every route() call. A quick audit:

grep -rn "route('" app/ resources/ | grep -v "\."

Testing. Route::currentRouteName() returns the locale-prefixed name, so assertions written before adoption will fail. In feature tests, set the locale explicitly (app()->setLocale('de')) rather than relying on the middleware ordering — the prefix comes from the group, the name from the prefix, and a missing middleware silently yields the wrong combination.

Debugging checklist when a localized URL 404s or a name doesn't resolve:

  1. php artisan route:list --name=posts — confirm the name actually includes the locale prefix.
  2. php artisan route:clear — stale cached routes are the #1 cause of "it worked locally", and the most likely symptom of a dependency bump.
  3. Check middleware order: locale-detection middleware must run before anything that reads Route::currentRouteName().
  4. Dump Route::getRoutes()->getByName('de.posts.index') to confirm the route object exists.

Extension point. Because the package only decorates the router, the safest long-term move is to wrap its helpers in your own thin RouteNames support class on day one. When the package stops working on a future Laravel release, you replace one class instead of grepping the codebase. Given the project's thin maintenance history, treat that wrapper as mandatory, not optional.

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.
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk