Eliminate Route Guesswork with Laravel Wayfinder
Overview of Type-Safe Routing
Bridging the gap between a PHP backend and a JavaScript frontend often involves manually syncing route names and URLs. This process is fragile and prone to silent failures when a controller method changes or a route is renamed.
Prerequisites
To get the most out of this tutorial, you should be comfortable with Laravel 10 or 11 and have a basic understanding of
Key Libraries & Tools
- Laravel Wayfinder: The core package that transpile PHP routes into TypeScript functions.
- Inertia.js: A framework for building single-page apps using classic server-side routing.
- Vite Plugin Run: A utility that triggers the generation command whenever PHP files change.
- Ziggy: While optional, Wayfinder serves as a type-safe alternative or companion to Ziggy's named routes.
Code Walkthrough: Installation and Automation
First, pull the package into your project using
composer require laravel/wayfinder
You can manually generate types using php artisan wayfinder:generate. However, to make this truly seamless, integrate it into your vite.config.js using the vite-plugin-run package. This ensures your types update the moment you save a PHP file.
import run from 'vite-plugin-run';
export default defineConfig({
plugins: [
run([
{
name: 'generate wayfinder',
run: ['php', 'artisan', 'wayfinder:generate'],
pattern: ['routes/**/*.php', 'app/Http/Controllers/**/*.php'],
},
]),
],
});
Implementing Typed Actions
In a standard Inertia form, you might use form.post(route('login')). With Wayfinder, you switch to the submit method and pass the imported action directly. This removes the need for magic strings.
import { store } from '@/actions/RegisteredUserController';
const { data, setData, submit } = useForm({ /* ... */ });
const submitForm = () => {
submit(store());
};
Syntax Notes and Best Practices
Wayfinder uses a functional approach. Instead of referencing a route by a string like 'user.store', you import the actual store function. This enables IDE features like "Go to Definition," which takes you straight to the PHP controller. For cleaner imports, configure a Vite alias for your generated routes directory.
Tips & Gotchas
Always check the HTTP method when using the submit helper. Wayfinder understands if an action requires POST, PUT, or DELETE, so you don't have to specify the method manually in your frontend code. If a new route isn't appearing, ensure your Vite watcher is running or trigger a manual generation to refresh the TypeScript definitions.
