emaia/laravel-hotwire 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

emaia/laravel-hotwire

最新稳定版本:0.21.0

Composer 安装命令:

composer require emaia/laravel-hotwire

包简介

The complete Hotwire stack for Laravel — Turbo Drive, Turbo Streams, Stimulus controllers and Blade components out of the box.

README 文档

README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

Laravel Hotwire

The complete Hotwire stack for Laravel — Turbo Drive, Turbo Streams, Stimulus controllers, and Blade components out of the box.

Table of Contents

Requirements

Installation

composer require emaia/laravel-hotwire

Publish the configuration file (optional):

php artisan vendor:publish --tag=hotwire-config

Quick Start

The installation command scaffolds the Hotwire setup in your Laravel application — JS entry points, Stimulus loader, Turbo imports, and CSS custom variants:

php artisan hotwire:install

This will:

  1. Copy JS and CSS scaffolding to resources/
  2. Add @hotwired/stimulus, @hotwired/turbo and @emaia/stimulus-dynamic-loader to your package.json
  3. Show instructions for the next steps

Only the three core dependencies above are added at installation time. Extra npm packages required by specific components (e.g. tippy.js, @emaia/sonner) are published on demand by hotwire:check once you actually use a component that depends on them.

Options:

# Overwrite existing files without prompting
php artisan hotwire:install --force

# Install only JS or CSS scaffolding
php artisan hotwire:install --only=js
php artisan hotwire:install --only=css

If a target file already exists and is identical, it is skipped. If it differs, the command asks for confirmation before overwriting (unless --force is used).

After installation, a good next step is:

  1. Browse the package docs in the terminal to see what is available
  2. Publish the Stimulus controllers you actually want to use
  3. Run hotwire:check to verify controllers and npm dependencies used by your views

Explore the Docs

You can browse the package docs directly in the terminal:

php artisan hotwire:docs
Interactive search, reading a single doc, and listing everything

This opens an interactive search across all controllers and components. Type a name, category, or keyword to filter:

 ┌ Search controllers and components ───────────────────────────────┐
 │ form                                                              │
 ├───────────────────────────────────────────────────────────────────┤
 │   auto-save           [forms]    Automatically saves a form…      │
 │ › auto-submit         [forms]    Submits a form automatically…    │
 │   clean-query-params  [forms]    Strips empty fields from the…    │
 │   optimistic--form    [turbo]    Dispatches optimistic UI…        │
 └───────────────────────────────────────────────────────────────────┘

Read a specific controller or component directly:

php artisan hotwire:docs auto-submit
php artisan hotwire:docs turbo/progress
php artisan hotwire:docs modal --component

List everything with category and description:

php artisan hotwire:docs --list
php artisan hotwire:docs --list --controller
php artisan hotwire:docs --list --component

Turbo

This package includes emaia/laravel-hotwire-turbo as a dependency, providing full Turbo integration for Laravel:

  • Turbo Streams — fluent builder for append, prepend, replace, update, remove, morph, refresh, and more
  • Turbo Frames<x-turbo::frame> Blade component with lazy loading support
  • DOM helpersdom_id() and dom_class() for consistent element identification
  • Request detectionwantsTurboStream() and wasFromTurboFrame() macros
  • Blade directives@turboNocache, @turboRefreshMethod('morph'), etc.
  • Testing utilitiesInteractsWithTurbo trait with assertTurboStream() assertions
// Example: return Turbo Streams
return turbo_stream()
    ->append('messages', view('messages.item', compact('message')))
    ->remove('modal');

See the full documentation at emaia/laravel-hotwire-turbo.

Stimulus Controllers (standalone)

Stimulus controllers without an associated Blade component. Used directly via data-controller and data-action.

Controllers live flat at the top level (resources/js/controllers/<name>_controller.{js,ts}). Substrate folders (turbo/, optimistic/, dev/) group controllers tied to a specific technical layer and use Stimulus' -- separator in the identifier.

php artisan hotwire:controllers auto-select auto-submit turbo/progress

Top-level controllers

Controller Identifier Category Dependencies Docs
Animated Number animated-number utility readme
Auto Save auto-save forms readme
Auto Resize auto-resize forms readme
Auto Select auto-select forms readme
Auto Submit auto-submit forms readme
Autofocus autofocus forms readme
Back to Top back-to-top utility readme
Carousel carousel utility embla-carousel readme
Char Counter char-counter forms readme
Checkbox Select All checkbox-select-all forms readme
Clean Query Params clean-query-params forms readme
Clear Input clear-input forms readme
Confirm Dialog confirm-dialog overlay readme
Copy To Clipboard copy-to-clipboard utility readme
Disclosure disclosure utility readme
Dropdown dropdown overlay readme
Error Scroll error-scroll forms readme
File Preserve file-preserve forms readme
GTM gtm utility readme
Hotkey hotkey utility readme
Input Mask input-mask forms maska readme
Lazy Image lazy-image utility readme
Modal modal overlay readme
Modal Auto Close modal-auto-close overlay readme
Money Input money-input forms readme
OEmbed oembed utility readme
Password Visibility password-visibility forms readme
Remote Form remote-form forms readme
Reset Files reset-files forms readme
Scroll Progress scroll-progress utility readme
Slug slug forms readme
Tabs tabs utility readme
Timeago timeago utility date-fns readme
Toast toast feedback @emaia/sonner readme
Toaster toaster feedback @emaia/sonner readme
Tooltip tooltip utility tippy.js readme
Unsaved Changes unsaved-changes forms readme

Turbo

Controllers tied to Turbo Drive / Turbo Frames.

Controller Identifier Dependencies Docs
Frame Src turbo--frame-src @hotwired/turbo readme
Polling turbo--polling @hotwired/turbo readme
Progress turbo--progress @hotwired/turbo readme
View Transition turbo--view-transition readme

Optimistic

Controller Identifier Dependencies Docs
Dispatch optimistic--dispatch @hotwired/turbo readme
Form optimistic--form @hotwired/turbo readme
Link optimistic--link @hotwired/turbo readme

Dev

Controller Identifier Dependencies Docs
Log dev--log readme

Publish Stimulus Controllers

Publish the controllers you want to use in your app so they can be discovered by the bundler (Vite).

Interactive — select which controllers to publish:

php artisan hotwire:controllers

By name — publish a specific controller:

php artisan hotwire:controllers auto-select

Substrate namespace — publish every controller under a substrate folder (turbo, optimistic, dev):

php artisan hotwire:controllers turbo

Multiple arguments — mix names and substrate namespaces:

php artisan hotwire:controllers modal turbo/progress auto-submit

All at once:

php artisan hotwire:controllers --all

List available controllers (with publication status):

php artisan hotwire:controllers --list

Update only controllers that are already published but differ from the package source:

php artisan hotwire:controllers --outdated

# Non-interactive — useful after composer update in CI or deploy scripts
php artisan hotwire:controllers --outdated --force

--outdated never installs controllers that haven't been published yet, and skips those that are already up to date.

Overwrite existing files:

php artisan hotwire:controllers auto-select --force

Top-level controllers are copied flat to resources/js/controllers/ (e.g. modalresources/js/controllers/modal_controller.js, identifier modal). Controllers under a substrate folder preserve that folder and use Stimulus' -- separator (e.g. turbo/progressresources/js/controllers/turbo/progress_controller.js, identifier turbo--progress). @emaia/stimulus-dynamic-loader discovers and loads them automatically via import.meta.glob.

If a controller already exists and is identical to the package version, the command reports it as up to date. If it differs, it asks for confirmation before overwriting.

Stimulus Attribute Helpers

Build Stimulus data-* attributes from Blade without hand-writing the verbose markup. The primary stimulus() entry point returns a fluent, chainable builder that is Htmlable (renders directly in {{ }}) and Arrayable (merges into a component's attribute bag):

<div {{ stimulus()
        ->controller('chart', ['name' => 'Likes', 'data' => [1, 2, 3, 4]])
        ->action('chart', 'refresh', 'click')
        ->target('chart', 'canvas') }}>
stimulus();
stimulus_controller($name, $values = [], $classes = [], $outlets = []);
stimulus_action($controller, $method, $event = null, $params = []);
stimulus_target($controller, $target);

stimulus_controller() is an alias for stimulus()->controller(...); stimulus_action() and stimulus_target() are shortcuts for stimulus()->action(...) and stimulus()->target(...).

See Stimulus attribute helpers for values/classes/outlets, action params, stacking multiple controllers, attribute-bag merging and the escaping rules.

Blade Components

Component Blade Category Stimulus Identifier(s) Docs
Form <x-hwc::form> forms auto-submit, unsaved-changes, error-scroll, clean-query-params readme
Field <x-hwc::field> forms readme
Input <x-hwc::input> forms auto-select, clear-input, input-mask readme
Label <x-hwc::label> forms readme
Select <x-hwc::select> forms readme
Textarea <x-hwc::textarea> forms auto-resize, char-counter readme
File <x-hwc::file> forms file-preserve, reset-files readme
Checkbox Group <x-hwc::checkbox-group> forms checkbox-select-all readme
Description <x-hwc::description> forms readme
Error <x-hwc::error> forms readme
Flash Container <x-hwc::flash-container> feedback toaster readme
Flash Message <x-hwc::flash-message> feedback toast readme
Spinner <x-hwc::spinner> feedback readme
Modal <x-hwc::modal> overlay modal readme
Confirm Dialog <x-hwc::confirm-dialog> overlay confirm-dialog readme
Dropdown <x-hwc::dropdown> overlay dropdown readme
Optimistic <x-hwc::optimistic> turbo readme
Carousel <x-hwc::carousel> utility carousel readme
Scroll Progress <x-hwc::scroll-progress> utility scroll-progress readme
Timeago <x-hwc::timeago> utility timeago readme

Verify Your Setup

List components and their required controllers:

php artisan hotwire:components

Shows each Blade component, its tag, and the Stimulus controllers it depends on — with publication status for each.

Check controllers used in your views (components and direct usage):

php artisan hotwire:check

Scans resources/views for Hotwire components and direct Stimulus controller usagedata-controller attributes and the stimulus_controller() / stimulus()->controller() / ->controllers() / stimulus_action() / stimulus_target() helpers — then verifies two things:

  1. Stimulus controllers — every controller required by a used component, or referenced directly, is published and up to date.
  2. npm dependencies — every external package imported by those controllers (e.g. @emaia/sonner, tippy.js) is declared in your package.json (dependencies or devDependencies).

Exits with code 1 if either has pending items (useful for CI).

Both the configured prefix (hwc by default) and the literal hotwire alias are recognized, so views like <x-hwc::flash-message /> and <x-hotwire::flash-message /> are detected equally. Only controllers shipped by the package are checked — your own controllers are ignored — and Blade comments and <script>/<style> blocks are stripped first, so commented-out code is skipped.

# Auto-publish missing/outdated controllers AND add missing npm deps to devDependencies
php artisan hotwire:check --fix

# Also run the detected package manager install command after adding deps
php artisan hotwire:check --fix --install

# Scan a custom path
php artisan hotwire:check --path=resources/views/app

Example output:

  ✓  toaster  up to date  (used by <x-hwc::flash-container>)
  ✓  toast    up to date  (used by <x-hwc::flash-message>)

Required npm dependencies:
  ✓  @emaia/sonner ^2.1.0  (used by toaster, toast)
  ✗  tippy.js ^6.3.7       missing from package.json (used by tooltip)

In interactive mode, hotwire:check asks whether to run the detected package manager install command after adding dependencies. In non-interactive scripts, use --fix --install to run it automatically.

Configuration

// config/hotwire.php

return [
    'prefix' => 'hwc', // <x-hwc::modal>
];

Change prefix to use a different prefix for Blade components. E.g. 'prefix' => 'hotwire'<x-hotwire::modal>.

View Customization

To customize the HTML/Tailwind of the components:

php artisan vendor:publish --tag=hotwire-views

Views published to resources/views/vendor/hotwire/ will take precedence over the package defaults.

Extending the package

Laravel Hotwire uses a single registry as the source of truth for:

  • Blade components
  • Stimulus controllers
  • external npm dependencies
  • docs paths
  • public categories

When adding a new component or controller to this package, update the registry entry in src/Registry/catalog.php.

Example component entry:

'modal' => [
    'class' => \Emaia\LaravelHotwire\Components\Modal::class,
    'view' => 'hotwire::component-views.modal',
    'docs' => 'docs/components/modal.md',
    'category' => 'overlay',
    'controllers' => ['modal'],
],

Example controller entry:

'tooltip' => [
    'source' => 'resources/js/controllers/tooltip_controller.js',
    'docs' => 'docs/controllers/tooltip.md',
    'category' => 'utility',
    'npm' => ['tippy.js' => '^6.3.7'],
],

More details: docs/registry.md

Testing

composer test

Manual Installation

If you prefer to set things up manually instead of using hotwire:install, follow the steps below.

Project setup (using Vite)

// resources/js/app.js
import "./libs";

// resources/js/libs/index.js
import "./turbo";
import "./stimulus";
import "../controllers";

// resources/js/libs/turbo.js
import * as Turbo from "@hotwired/turbo";

export default Turbo;

// resources/js/libs/stimulus.js
import {Application} from '@hotwired/stimulus'

const Stimulus = Application.start()
window.Stimulus = Stimulus
export {Stimulus}

// resources/js/controllers/index.js
import {Stimulus} from "../libs/stimulus";
import {registerControllers} from "@emaia/stimulus-dynamic-loader";

const controllers = import.meta.glob("./**/*_controller.{js,ts}", {
    eager: false,
});

registerControllers(Stimulus, controllers);

Install the required js dependencies:

bun add @hotwired/stimulus @hotwired/turbo @emaia/stimulus-dynamic-loader

TailwindCSS (v4)

Add these settings to your CSS entrypoint resources/css/app.css:

@source '../../vendor/emaia/laravel-hotwire/resources/views/**/*.blade.php';
@custom-variant turbo-preview (html[data-turbo-preview] &);
@custom-variant turbo-visit (html[aria-busy="true"] &);
@custom-variant form-busy (form[aria-busy="true"] &);
@custom-variant frame-busy (turbo-frame[busy] &);
@custom-variant in-turbo-frame (turbo-frame &);
@custom-variant in-remote-turbo-frame (turbo-frame[src] &);
@custom-variant modal ([data-modal-target="dialog"] &);

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Contributions are welcome via pull requests.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.

统计信息

  • 总下载量: 35
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 11
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-04-10

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固