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

Generate fully typed TypeScript functions for your Laravel routes and controller methods. Wayfinder lets your frontend call endpoints like normal imports—no hardcoded URLs or manual param syncing. Works with Vite via @laravel/vite-plugin-wayfinder.

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 (safe to .gitignore).

  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 Integration:

    • Use Wayfinder to call Laravel controllers directly from TypeScript.
    • Example: Fetch a post:
      import { show } from "@/actions/App/Http/Controllers/PostController";
      const { url, method } = show(1);
      fetch(url, { method });
      
  2. Route-Based Navigation:

    • Import named routes for type-safe URLs:
      import { show } from "@/routes/post";
      const link = <Link href={show(1)}>View Post</Link>;
      
  3. Form Handling:

    • Generate form attributes with .form():
      import { store } from "@/actions/App/Http/Controllers/PostController";
      <form {...store.form()}>
        {/* Auto-generates action="/posts" method="post" */}
      </form>
      
  4. Query Parameters:

    • Append or merge query params:
      show(1, { query: { page: 2 } }); // "/posts/1?page=2"
      show(1, { mergeQuery: { page: 2 } }); // Merges with existing URL params
      
  5. HTTP Method Overrides:

    • Force a method (e.g., PUT for forms):
      update.form.put(1); // Generates `_method=PUT`
      
  6. Invokable Controllers:

    • Call controllers directly if they implement __invoke:
      import StorePostController from "@/actions/App/Http/Controllers/StorePostController";
      StorePostController(); // Calls the controller's __invoke method
      

Integration Tips

  • Inertia.js: Pass Wayfinder results to useForm.submit():
    form.submit(store()); // Auto-resolves URL/method
    
  • API Clients: Use Wayfinder to build API clients:
    const client = {
      getPost(id: number) { return show(id); },
      createPost(data: Post) { return store(data); }
    };
    
  • Dynamic Imports: Lazy-load Wayfinder modules for code-splitting:
    const { show } = await import("@/actions/App/Http/Controllers/PostController");
    

Gotchas and Tips

Pitfalls

  1. Route Caching:

    • Issue: Stale routes in route:cache cause missing Wayfinder definitions.
    • Fix: Clear routes before generating:
      php artisan route:clear
      php artisan wayfinder:generate
      
  2. Reserved Words:

    • Issue: JavaScript reserved words (e.g., delete) are renamed to [method]Method.
    • Fix: Rename controller methods or use aliases in TypeScript.
  3. Multiple Routes to Same Action:

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

    • Issue: Falsy values (e.g., 0, "") may not bind correctly.
    • Fix: Explicitly pass objects for optional params:
      show({ id: 1, optionalParam: null }); // Ensures null is passed
      
  5. Vite Dev Server:

    • Issue: Changes to routes/controllers may not trigger regen.
    • Fix: Restart Vite or use --force:
      npm run dev -- --force
      

Debugging Tips

  • Check Generated Files: Verify resources/js/wayfinder/ for errors.
  • TypeScript Errors: Ensure vite.config.js includes the plugin.
  • URL Mismatches: Use php artisan route:list to validate backend routes.

Extension Points

  1. Custom Paths:

    • Override output paths via --path flag or config:
      php artisan wayfinder:generate --path=custom/path
      
  2. Skip Generation:

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

    • Enable with --with-form for React/Vue form helpers.
  4. Runtime Defaults:

    • Preserve functional defaults (e.g., APP_URL) in generated URLs.
  5. Query Parameter Handling:

    • Customize merging logic by extending the Vite plugin or TypeScript types.

Pro Tips

  • Tree-Shaking: Import individual actions to exclude unused code.
  • Type Safety: Leverage TypeScript autocompletion for route params.
  • Testing: Mock Wayfinder in tests:
    vi.mock("@/actions/App/Http/Controllers/PostController", () => ({
      show: () => ({ url: "/mock", method: "get" })
    }));
    
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.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
ecotone/kafka
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata