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

Ux Paths Laravel Package

krystal-sf/ux-paths

A Laravel package for defining, organizing, and resolving UX paths, helping you manage user-flow routes and navigation links consistently across your application. Lightweight, framework-friendly helpers keep path logic centralized and easy to maintain.

View on GitHub
Deep Wiki
Context7

Getting Started

krystal-sf/ux-paths is a Symfony UX library — "Intelligent Paths for Krystal Symfony Projects." Before you do anything, understand the constraint: this is a Symfony bundle, not a Laravel package. There is no UxPathsServiceProvider and no config/ux-paths.php. You'll use it either (a) inside a Symfony app, or (b) by pulling out its path/value objects into a Laravel service layer.

Minimal steps:

composer require krystal-sf/ux-paths

Then, in a Symfony host app:

// config/bundles.php
return [
    // ...
    Krystal\Ux\Paths\KrystalUxPathsBundle::class => ['all' => true],
];

In Laravel, you can't auto-register the bundle. Install it for its classes and wire the resolver yourself:

// app/Providers/AppServiceProvider.php
public function register(): void
{
    $this->app->singleton(\Krystal\Ux\Paths\PathResolver::class, function ($app) {
        return (new \Krystal\Ux\Paths\PathResolver(...))
            ->setRouter($app['router']); // adapt to the real constructor
    });
}

Where to look first:

  1. README.md and CHANGELOG.md — the API surface is small; the README is usually the spec.
  2. src/ — look for the Path value object and the resolver/service class. Those two tell you 90% of what the package does.
  3. config/services.yaml (if present) — shows service IDs, aliases, and injectable contracts.
  4. tests/ — treat tests as executable documentation; they reveal edge-case behavior (trailing slashes, optional params, locale suffixes).

First use case: stop hand-concatenating route strings. Replace '/users/' . $user->id . '/edit' with a resolved path from the package:

$path = $resolver->resolve('user_edit', ['id' => $user->id]); // -> "/users/42/edit"

Use that immediately in navigation menus, breadcrumbs, and redirect targets — that's where hardcoded paths rot fastest.

Implementation Patterns

1. Inject the resolver, never new it

The whole value of the package is that routing/context/config is centralized. Inject the resolver (Symfony autowiring, or a Laravel singleton + facade). Anything that constructs a path by hand defeats the point.

final class BreadcrumbBuilder
{
    public function __construct(private PathResolver $paths) {}

    public function forProfile(User $user): array
    {
        return [
            ['label' => 'Home',    'href' => $this->paths->resolve('home')],
            ['label' => 'Users',   'href' => $this->paths->resolve('user_index')],
            ['label' => $user->name, 'href' => $this->paths->resolve('user_show', ['id' => $user->id])],
        ];
    }
}

2. Treat paths as value objects, not strings

If the package exposes a Path (or similar) object, keep it typed all the way through your domain/controller layer and cast to string only at the view boundary ((string) $path, {{ $path }}). This keeps normalization (leading slash, encoding, trailing slash) in one place.

$path = $this->paths->path('user_show', ['id' => $user->id]);

return redirect((string) $path);

3. Map logical names in config, not in code

The "intelligent" part is usually a configurable mapping layer. Define path definitions once (YAML in Symfony, PHP array in Laravel) and reference them by logical key:

# config/packages/ux_paths.yaml (Symfony)
krystal_ux_paths:
    definitions:
        dashboard: { route: app_dashboard }
        user_edit: { route: user_edit, params: [id] }
// config/ux-paths.php (Laravel equivalent, consumed by your wrapper)
return [
    'definitions' => [
        'dashboard' => ['route' => 'dashboard'],
        'user_edit' => ['route' => 'users.edit', 'params' => ['id']],
    ],
];

This is the main extension point: when the package's naming doesn't fit your app, wrap it — don't fork it.

4. Symfony Twig vs Laravel Blade

In Symfony, register/consume the Twig extension the bundle ships (typically a path()-like function). In Laravel, you have two clean options:

  • A Blade directive that proxies to the singleton: @uxpath('user_edit', ['id' => $user->id]).
  • A global helper function (ux_path()) that resolves from app(PathResolver::class).

Avoid calling app() from views directly if you can — inject into view composers instead.

5. Context-aware paths (locale/tenant)

If the package supports context (locale, host, base path), pass it explicitly and test it. This is where Laravel and Symfony diverge most: Symfony's RequestContext lives in symfony/routing, which Laravel also depends on but doesn't use identically. Verify the resolver reads the context you expect — don't assume app()->getLocale() propagates.

$resolver->setContext(['locale' => app()->getLocale(), 'host' => request()->getHost()]);

6. Test paths, not strings

Assert semantic behavior in your tests:

$this->assertSame('/users/42/edit', (string) $this->paths->path('user_edit', ['id' => 42]));

If you're on Laravel, run these in a single resolver test suite — they're pure-PHP, no HTTP kernel needed. That's a strong argument for adopting the package even in a Laravel codebase.

Gotchas and Tips

  • It's a Symfony bundle. Laravel's PackageManifest won't see it, php artisan vendor:publish won't find it, and its config/services.yaml won't load. Budget time for a thin wrapper class in app/Support/. Do not try to shoehorn the bundle's DI into Laravel's container.
  • Autowiring by service ID won't survive the port. Symfony's autowiring magic uses type-hint → alias resolution. In Laravel you must bind() / singleton() explicitly. Missing bindings are the #1 "why does it say Target [PathResolver] is not instantiable" error.
  • Route names must match, exactly. Pass the package your framework's route names (users.edit in Laravel, user_edit in Symfony typically). A typo surfaces as an unresolvable path — assert on route existence in a test (Route::has(...)) rather than letting it break a page at runtime.
  • Optional and array route params. A path resolver can't infer whether a param is optional or repeatable; if you omit a key you'll usually get either a missing-parameter exception or an unexpected query string. Be explicit and validate at the config layer.
  • Trailing slashes and URL encoding are the classic bugs. Run a matrix test: root path, nested path, path with unicode slug, path with a param containing / or ?. Encoding behavior should be uniform across every caller — that's exactly what the value object buys you.
  • Symfony component version constraints can conflict. Check the package's composer.json require/conflict blocks against your Laravel version's symfony/* pins. If it requires symfony/ux-* you may end up dragging in a lot of transitively required, unused packages. Consider composer why symfony/ux-twig-component.
  • Config caching. In Symfony, path definitions in YAML get cached — clear with bin/console cache:clear after edits, or you'll debug stale paths for an hour. In Laravel, if you load definitions from config, php artisan config:clear is your friend during development.
  • Debugging entry points. Symfony: bin/console debug:container Krystal and bin/console debug:router. Laravel: php artisan tinker → app(PathResolver::class)->resolve(...), plus Route::getRoutes() to confirm names. Wrap the resolver in a small interface so you can swap in a fake during testing.
  • Extension points: subclass, don't edit vendor/. Custom path resolvers (for tenant-prefixed URLs, preview environments, etc.) should implement the package's interface and be swapped via your container binding. Same for Twig/Blade helpers — register your own, don't patch the bundle's.
  • Watch the score signals. Zero dependents and a low opportunity score means: no community examples, no Stack Overflow answers, and a small API surface may change between patch releases. Pin an exact version ("krystal-sf/ux-paths": "1.2.*") and add a resolver-level test suite on day one — you are your own support channel.
  • Best fit case: you're in a Krystal/Symfony project and want consistent path generation across templates, controllers, and commands. Worst fit case: you're in a pure Laravel app and only need route() — you probably don't. The value appears once you have many logical path definitions (nav, breadcrumbs, sitemaps, canonical URLs) and want one authority for them.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin