Weave Code
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

Wayfinder Laravel Package

laravel/wayfinder

Generates fully typed, importable TypeScript functions from your Laravel routes and controllers. Call backend endpoints like normal TS functions—no hardcoded URLs or manual syncing. Includes an Artisan generator and Vite plugin for auto-regeneration.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require laravel/wayfinder
    npm i -D @laravel/vite-plugin-wayfinder
    

    Update vite.config.js:

    import { wayfinder } from "@laravel/vite-plugin-wayfinder";
    export default defineConfig({
        plugins: [wayfinder()],
    });
    
  2. Generate TypeScript Definitions:

    php artisan wayfinder:generate
    

    This creates resources/js/wayfinder/, actions/, and routes/ directories (auto-gitignored).

  3. First Use Case: Import a controller action in your frontend:

    import { show } from "@/actions/App/Http/Controllers/PostController";
    show(1); // Returns { url: "/posts/1", method: "get" }
    

Implementation Patterns

Core Workflows

  1. Controller-Centric Development:

    • Action Binding: Use Wayfinder to bind directly to controller methods:
      import { store } from "@/actions/App/Http/Controllers/PostController";
      store({ title: "Hello" }); // Auto-generates POST `/posts`
      
    • Invokable Controllers: For single-method controllers:
      import StorePostController from "@/actions/App/Http/Controllers/StorePostController";
      StorePostController({ title: "Hello" });
      
  2. Route-Centric Development:

    • Named Routes: Import routes by name for clarity:
      import { show } from "@/routes/post";
      show(1); // Resolves to `/posts/1`
      
    • Query Parameters: Append dynamically:
      show(1, { query: { page: 2 } }); // `/posts/1?page=2`
      
  3. Form Integration:

    • Generate form attributes with .form():
      <form {...store.form()}>
        {/* Auto-generates action="/posts" method="post" */}
      </form>
      
    • Specify HTTP methods:
      <form {...update.form.put(1)}>
        {/* Auto-generates action="/posts/1?_method=PUT" */}
      </form>
      
  4. Inertia.js Integration:

    • Form Submission:
      import { useForm } from "@inertiajs/react";
      import { store } from "@/actions/App/Http/Controllers/PostController";
      const form = useForm({ title: "Hello" });
      form.submit(store()); // Auto-resolves URL/method
      
    • Links:
      import { Link } from "@inertiajs/react";
      import { show } from "@/actions/App/Http/Controllers/PostController";
      <Link href={show(1)}>View Post</Link>
      

Advanced Patterns

  1. Dynamic Route Resolution:

    • Handle multiple routes to the same action via URI keys:
      import { index } from "@/actions/App/Http/Controllers/ClientPaymentsController";
      index["/clients/{client}/payments"]({ client: 1 });
      
    • Prefer named routes for clarity:
      import { index } from "@/routes/clients/payments";
      index({ client: 1 });
      
  2. Query Parameter Management:

    • Merge with existing query params:
      show(1, { mergeQuery: { page: 2 } }); // Preserves other params
      
    • Remove params by setting to null:
      show(1, { mergeQuery: { page: null } });
      
  3. HTTP Method Overrides:

    • Explicitly set methods:
      show.head(1); // Forces HEAD method
      show.url(1);   // Returns only the URL
      
  4. Tree-Shaking:

    • Import specific actions to exclude unused methods:
      import { show } from "@/actions/App/Http/Controllers/PostController";
      // Only `show` is bundled
      

Gotchas and Tips

Pitfalls

  1. Route Cache Inconsistencies:

    • Issue: Deployments with route:cache may generate stale TypeScript definitions.
    • Fix: Clear routes before generating:
      php artisan route:clear
      npm run build
      
  2. Reserved JavaScript Words:

    • Issue: Controller methods like delete or import are renamed to deleteMethod/importMethod.
    • Fix: Rename methods in PHP or use the generated name in TypeScript.
  3. Multiple Routes to Same Action:

    • Issue: Ambiguous routes generate a URI-keyed object instead of a callable.
    • Fix: Use named routes or explicitly select the URI:
      index["/clients/{client}/payments"]({ client: 1 });
      
  4. Optional Route Parameters:

    • Issue: Falsy values (e.g., 0, false) may not render in URLs.
    • Fix: Explicitly pass null or omit the parameter.
  5. Base URL Mismatches:

    • Issue: Generated URLs may ignore APP_URL if not configured.
    • Fix: Ensure APP_URL is set in .env or use absolute paths.

Debugging Tips

  1. Regenerate Definitions:

    • Run php artisan wayfinder:generate --force to overwrite files.
  2. Check Vite Plugin:

    • Ensure @laravel/vite-plugin-wayfinder is enabled in vite.config.js.
  3. Inspect Generated Files:

    • Verify resources/js/wayfinder/ for correct imports and types.
  4. TypeScript Errors:

    • Rebuild Vite after changing routes/controllers:
      npm run dev
      

Extension Points

  1. Custom Output Paths:

    • Change generation path:
      php artisan wayfinder:generate --path=custom/path
      
  2. Skip Generation:

    • Exclude actions/routes:
      php artisan wayfinder:generate --skip-actions
      
  3. Form Variants:

    • Enable form support:
      php artisan wayfinder:generate --with-form
      
  4. Runtime Defaults:

    • Override defaults at runtime:
      show(1, { defaults: { page: 1 } });
      

Performance

  • Tree-Shaking: Import specific actions to minimize bundle size.
  • Lazy Loading: Dynamically import Wayfinder functions in React/Vue components:
    const { show } = await import("@/actions/App/Http/Controllers/PostController");
    
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.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai