SKILL.blade.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. ---
  2. name: livewire-development
  3. description: "Use for any task or question involving Livewire. Activate if user mentions Livewire, wire: directives, or Livewire-specific concepts like wire:model, wire:click, wire:sort, or islands, invoke this skill. Covers building new components, debugging reactivity issues, real-time form validation, drag-and-drop, loading states, migrating from Livewire 3 to 4, converting component formats (SFC/MFC/class-based), and performance optimization. Do not use for non-Livewire reactive UI (React, Vue, Alpine-only, Inertia.js) or standard Laravel forms without Livewire."
  4. license: MIT
  5. metadata:
  6. author: laravel
  7. ---
  8. @php
  9. /** @var \Laravel\Boost\Install\GuidelineAssist $assist */
  10. @endphp
  11. # Livewire Development
  12. ## Documentation
  13. Use `search-docs` for detailed Livewire 4 patterns and documentation.
  14. ## Basic Usage
  15. ### Creating Components
  16. ```bash
  17. # Single-file component (SFC - default in v4)
  18. # Creates: resources/views/components/⚡create-post.blade.php
  19. {{ $assist->artisanCommand('make:livewire create-post') }}
  20. # Page component (SFC - Full Page in v4)
  21. # Creates: resources/views/pages/⚡create-post.blade.php
  22. {{ $assist->artisanCommand('make:livewire pages::create-post') }}
  23. # Multi-file component (MFC)
  24. # Creates: resources/views/components/⚡create-post/create-post.php
  25. # resources/views/components/⚡create-post/create-post.blade.php
  26. {{ $assist->artisanCommand('make:livewire create-post --mfc') }}
  27. # Class-based component (v3 style)
  28. # Creates: app/Livewire/CreatePost.php AND resources/views/livewire/create-post.blade.php
  29. {{ $assist->artisanCommand('make:livewire create-post --class') }}
  30. # With namespace
  31. {{ $assist->artisanCommand('make:livewire Posts/CreatePost') }}
  32. ```
  33. ### Converting Between Formats
  34. Use `{{ $assist->artisanCommand('livewire:convert create-post') }}` to convert between single-file, multi-file, and class-based formats.
  35. ### Choosing a Component Format
  36. > **Always follow the project's existing conventions first.** Before creating any component, inspect the project's existing Livewire components to determine the established format (SFC, MFC, or class-based) and directory structure. Check `{{ $assist->appPath('Livewire/') }}`, `resources/views/components/`, and `resources/views/livewire/` for existing components. If the project already uses a consistent format, **use that same format** — even if it differs from the Livewire v4 defaults below. Only fall back to the v4 defaults (SFC in `resources/views/components/`) when no existing convention is established.
  37. Also check `config/livewire.php` for `make_command.type`, `make_command.emoji`, `component_locations`, and `component_namespaces` overrides, which change the default format and where files are stored.
  38. ### Component Format Reference
  39. | Format | Flag | Class Path | View Path |
  40. |--------|------|------------|-----------|
  41. | Single-file (SFC) | default | — | `resources/views/components/⚡create-post.blade.php` (PHP + Blade in one file) |
  42. | Full Page SFC | `pages::name` | — | `resources/views/pages/⚡create-post.blade.php` |
  43. | Multi-file (MFC) | `--mfc` | `resources/views/components/⚡create-post/create-post.php` | `resources/views/components/⚡create-post/create-post.blade.php` |
  44. | Class-based | `--class` | `{{ $assist->appPath('Livewire/CreatePost.php') }}` | `resources/views/livewire/create-post.blade.php` |
  45. | View-based | default (Blade-only) | — | `resources/views/components/⚡create-post.blade.php` (Blade-only with functional state) |
  46. > **Important:** The ⚡ prefix shown above is the **default** behavior in Livewire v4 — it is **configurable**. Check `config/livewire.php` for the `make_command.emoji` setting. When `true` (default), always include the ⚡ prefix in filenames you create. When `false`, omit the ⚡ prefix from all paths above.
  47. Namespaced components map to subdirectories: `make:livewire Posts/CreatePost` creates `resources/views/components/posts/⚡create-post.blade.php` (single-file by default). Use `make:livewire Posts/CreatePost --mfc` for multi-file output at `resources/views/components/posts/⚡create-post/create-post.php` and `resources/views/components/posts/⚡create-post/create-post.blade.php`.
  48. ### Single-File Component Example
  49. @boostsnippet("Single-File Component Example", "php")
  50. <?php
  51. use Livewire\Component;
  52. new class extends Component {
  53. public int $count = 0;
  54. public function increment(): void
  55. {
  56. $this->count++;
  57. }
  58. };
  59. ?>
  60. <div>
  61. <button wire:click="increment">Count: @{{ $count }}</button>
  62. </div>
  63. @endboostsnippet
  64. ## Livewire 4 Specifics
  65. ### Key Changes From Livewire 3
  66. These things changed in Livewire 4, but may not have been updated in this application. Verify this application's setup to ensure you follow existing conventions.
  67. - Use `Route::livewire()` for full-page components (e.g., `Route::livewire('/posts/create', CreatePost::class)`); config keys renamed: `layout` → `component_layout`, `lazy_placeholder` → `component_placeholder`.
  68. - `wire:model` now ignores child events by default (use `wire:model.deep` for old behavior); `wire:scroll` renamed to `wire:navigate:scroll`.
  69. - Component tags must be properly closed; `wire:transition` now uses View Transitions API (modifiers removed).
  70. - JavaScript: `$wire.$js('name', fn)` → `$wire.$js.name = fn`; `commit`/`request` hooks → `interceptMessage()`/`interceptRequest()`.
  71. ### New Features
  72. - Component formats: single-file (SFC), multi-file (MFC), view-based components.
  73. - Islands (`@island`) for isolated updates; async actions (`wire:click.async`, `#[Async]`) for parallel execution.
  74. - Deferred/bundled loading: `defer`, `lazy.bundle` for optimized component loading.
  75. | Feature | Usage | Purpose |
  76. |---------|-------|---------|
  77. | Islands | `@island(name: 'stats')` | Isolated update regions |
  78. | Async | `wire:click.async` or `#[Async]` | Non-blocking actions |
  79. | Deferred | `defer` attribute | Load after page render |
  80. | Bundled | `lazy.bundle` | Load multiple together |
  81. ### New Directives
  82. - `wire:sort`, `wire:intersect`, `wire:ref`, `.renderless`, `.preserve-scroll` are available for use.
  83. - `data-loading` attribute automatically added to elements triggering network requests.
  84. | Directive | Purpose |
  85. |-----------|---------|
  86. | `wire:sort` | Drag-and-drop sorting |
  87. | `wire:intersect` | Viewport intersection detection |
  88. | `wire:ref` | Element references for JS |
  89. | `.renderless` | Component without rendering |
  90. | `.preserve-scroll` | Preserve scroll position |
  91. ## Best Practices
  92. - Always use `wire:key` in loops
  93. - Use `wire:loading` for loading states
  94. - Use `wire:model.live` for instant updates (default is debounced)
  95. - Validate and authorize in actions (treat like HTTP requests)
  96. ## Configuration
  97. - `smart_wire_keys` defaults to `true`; new configs: `component_locations`, `component_namespaces`, `make_command`, `csp_safe`.
  98. ## Alpine & JavaScript
  99. - `wire:transition` uses browser View Transitions API; `$errors` and `$intercept` magic properties available.
  100. - Non-blocking `wire:poll` and parallel `wire:model.live` updates improve performance.
  101. For interceptors and hooks, see [reference/javascript-hooks.md](reference/javascript-hooks.md).
  102. ## Testing
  103. @boostsnippet("Testing Example", "php")
  104. Livewire::test(Counter::class)
  105. ->assertSet('count', 0)
  106. ->call('increment')
  107. ->assertSet('count', 1);
  108. @endboostsnippet
  109. ## Verification
  110. 1. Browser console: Check for JS errors
  111. 2. Network tab: Verify Livewire requests return 200
  112. 3. Ensure `wire:key` on all `@foreach` loops
  113. ## Common Pitfalls
  114. - Missing `wire:key` in loops → unexpected re-rendering
  115. - Expecting `wire:model` real-time → use `wire:model.live`
  116. - Unclosed component tags → syntax errors in v4
  117. - Using deprecated config keys or JS hooks
  118. - Including Alpine.js separately (already bundled in Livewire 4)