Skip to content

Conversation

@Manavsaliya
Copy link

@Manavsaliya Manavsaliya commented Sep 27, 2025

Current Route Detection Feature for Laravel Wayfinder

Overview

This update brings a new currentRoute function to Laravel Wayfinder, designed as a modern, TypeScript-friendly replacement for Ziggy's route().current(). It provides powerful route detection capabilities with full TypeScript support and intuitive APIs.

Key Benefits

  • Zero Configuration: Works immediately with your existing Laravel routes
  • Full TypeScript Support: Auto-completion and type safety for all route names
  • Modern API: Cleaner, more intuitive function calls than Ziggy
  • Smart Navigation: Build navigation that automatically highlights active routes
  • Conditional Rendering: Show or hide components based on the current route

Core Features

Basic Route Detection

import { currentRoute } from "@/wayfinder";

// Get current URL
const url = currentRoute(); // "https://example.com/posts/123"

// Check if current route matches
currentRoute("posts.index"); // true/false

Controller RouteDefinition Approach

Use Wayfinder-generated controller methods directly:

import PostController from "@/actions/App/Http/Controllers/PostController";
import { show } from "@/actions/App/Http/Controllers/PostController";

// Using controller object
currentRoute(PostController.show(123)); // true
currentRoute(PostController.show.url({ post: 123 })); // true

// Using imported method
currentRoute(show({ post: 123 })); // true

// With query parameters
currentRoute(PostController.show({ post: 123 }, { query: { q: "test" } })); // true

Invokable Controllers

import InvokableController from "@/actions/App/Http/Controllers/InvokableController";

currentRoute(InvokableController()); // true

Direct Named Routes

// Direct named route matching
currentRoute("posts.show", { post: 123 }); // true
currentRoute("posts.index", { page: 2, sort: "name" }); // true

// Wildcard matching
currentRoute("posts.*"); // Matches posts.index, posts.show, etc.
currentRoute("admin.*"); // Matches admin.dashboard, admin.users, etc.

Advanced Parameter Handling

// Mixed route and query parameters
currentRoute("posts.show", {
    post: 123, // Route parameter
    edit: true, // Query parameter
    tags: ["red", "blue"], // Array query parameters
});

// Arrays are always query parameters, never route parameters
currentRoute("posts.show", { post: ["12"] }); // false - arrays are query params only

Ziggy Migration

Before (Ziggy)

// Ziggy approach - no TypeScript support
route().current("posts.show");
route().current("posts.show", { post: 123 });

After (Wayfinder)

// Wayfinder approach - full TypeScript support
currentRoute("posts.show");
currentRoute("posts.show", 123);
currentRoute(PostController.show(123)); // Controller approach

Real-World Use Cases

Navigation Components

const NavItem = ({ route, children }) => {
    const isActive = currentRoute(route);
    return <li className={isActive ? "active" : ""}>{children}</li>;
};

Conditional Rendering

const AdminPanel = () => {
    if (currentRoute("admin.*")) {
        return <AdminNavigation />;
    }
    return null;
};

Form State Management

const PostForm = ({ postId }) => {
    const isEditMode = currentRoute("posts.edit", { post: postId });
    return (
        <form>
            {isEditMode && <input type="hidden" name="_method" value="PUT" />}
            {/* form fields */}
        </form>
    );
};

Technical Implementation

GenerateCommand.php

  • Vendor Route Detection: Introduced isVendorRoute method to identify vendor routes
  • Optional Vendor Route Inclusion: Added --with-vendor-routes flag for including vendor routes
  • Improved Route Filtering: Better filtering logic for route generation

Updated Route.php

  • Vendor Route Detection: New isVendorRoute method to identify vendor routes
  • Better Route Analysis: Improved route parsing and URL generation
  • Enhanced Parameter Handling: Better support for complex route parameters

New Type Definitions

  • RouteArguments: Flexible, type-safe way to pass route parameters
  • RoutePrimitive: Basic types (string, number, boolean) for route values
  • RouteObject: Support for complex, nested parameters
  • RouteName: Auto-complete and type-checking for all route names

TypeScript Named Route Auto-Suggestion

When you use Wayfinder, TypeScript auto-suggestion for route names (RouteName) is enabled by generating a routes.ts file in the same directory where your wayfinder/index.ts file is created. This routes.ts file is automatically generated alongside index.ts and contains:

  • namedRoutes: An object with all available route names for auto-completion and type safety.
  • isValidWildcardPattern: A utility to validate wildcard route patterns.
  • checkQueryParams: A helper to check and match query parameters for routes.

With this setup, we’ll always get the latest route name suggestions and helpful utilities right in our editor. That means you can quickly find, check, and match routes with confidence—no guesswork, no manual updates, and no type errors.

Update: 2025-10-21

  • Add support for middle wildcard routes like post.*.show
  • Remove forcedScheme and forcedRoot in CurrentRouteService, becase it's not used
  • Improve currentRoute() funtion and remove duplicate code

- Introduced `currentRoute` function in README with detailed usage examples, return types, and handling of route and query parameters.
- Updated `wayfinder.ts` to include new type definitions for route arguments.
- Enhanced `GenerateCommand.php` to support vendor route generation and improved route filtering.
- Added `isVendorRoute` method in `Route.php` to identify vendor routes.
- Updated web routes in `web.php` for testing current route functionality.
@Manavsaliya Manavsaliya marked this pull request as draft September 30, 2025 17:18
@Manavsaliya Manavsaliya marked this pull request as ready for review September 30, 2025 17:19
@SantosVilanculos
Copy link

SantosVilanculos commented Oct 1, 2025

Watch this Laravel Podcast video TypeScript, Wayfinder, and Ranger with Joe Tannenbaum.

According to it 'wayfinder', is front-end framework agnostic (not just for InertiaJS).

I believe this feature is better suited to the Inertia library itself.

I opened a discussion thread inertiajs/inertia#2564, where I suggest implementing the useRoute hook, which already includes this feature. Feel free to use it as a basis for opening a pull request there.

@Manavsaliya
Copy link
Author

Hey, thanks a lot for pointing this out, it's a really good angle. Let me explain why I believe putting that functionality in Wayfinder gives a better developer experience — especially for type safety and route suggestions.

  • Because Wayfinder (and its Vite plugin) has full visibility over all route definitions — names, parameters, HTTP methods, etc. we can auto-generate TypeScript types representing the named routes, valid parameter shapes (including optional ones), query params, wildcards, etc. And with dev server / file watching, every time you modify web.php or controller files, you trigger regeneration (via php artisan wayfinder:generate under the hood) so the definitions used for suggestions always match backend.

  • Inertia’s docs emphasize that routing is defined server-side. Inertia itself doesn’t (by default) provide type-safe named-route suggestions or client-side detection — it simply consumes what’s defined on the backend.

  • In the future, it makes sense for Inertia to expose a thin wrapper like useCurrentRoute() that sits on top of Wayfinder’s logic. That way Inertia developers get a convenient hook while still relying on the type-safe foundation Wayfinder provides.
    but in current stage we can add currentRoute() into Wayfinder not Inertia,.

For the current stage, I believe currentRoute() belongs in Wayfinder, where it can guarantee type safety and accurate route suggestions. Later, Inertia can easily wrap it if needed.

@yoeriboven
Copy link

With Wayfinder I don't have to name my routes anymore. Could this PR do something like currentRoute(InvokableController())?

@Manavsaliya
Copy link
Author

Hey @yoeriboven you are absolutely right 👏

Some users still rely on named routes being passed from the backend to the frontend (for example, to highlight the active navigation tab or conditionally render components). In those cases, they can’t easily reference the controller or route definition directly through Wayfinder.

So, to cover both use cases, I’ve added support for both approaches in currentRoute():

  • Named routes — with full type-safe suggestions.
  • Wayfinder controller / route-definition approach — consistent with how Wayfinder routes are usually referenced.

Example usage:

import PostController from "@/actions/App/Http/Controllers/PostController";
import { show } from "@/actions/App/Http/Controllers/PostController";

// Using controller object
currentRoute(PostController.show(123));
currentRoute(PostController.show.url({ post: 123 }));

// Using imported method
currentRoute(show({ post: 123 }));

// With query parameters
currentRoute(PostController.show({ post: 123 }, { query: { q: "test" } }));

// Also works with Invokable controllers
currentRoute(InvokableController());

Thanks again, @yoeriboven, for the great suggestion — this helped make the feature more flexible for everyone. 🙌

@timacdonald
Copy link
Member

With Wayfinder I don't have to name my routes anymore

4pw07x

@Manavsaliya
Copy link
Author

Hey @joetannenbaum @taylorotwell @timacdonald

should i completely remove named route and keep only controller route definition approach for checking

or should i keep current version which is named route + controller route definition approach because as i mention earlier

Some users still rely on named routes being passed from the backend to the frontend (for example, to highlight the active navigation tab or conditionally render components). In those cases, they can’t easily reference the controller or route definition directly through Wayfinder.

so what you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants