emaia/laravel-hotwire
Laravel Hotwire brings Turbo and Stimulus to your Laravel app, trimming JavaScript while keeping pages fast and reactive. Integrates seamlessly with Blade, delivering SPA-like navigation with minimal setup.
composer require emaia/laravel-hotwire, then run the package installer/publish step so config/hotwire.php, the component bundle, and the Stimulus/Turbo assets land in your app. Commit the generated bundle immediately — it becomes the baseline for hotwire:check.docs/components/ (start with Sidebar and Video Embed, then Modal/Sheet/Drawer), docs/recipes/overlay-responses.md, docs/presets.md, then docs/commands.md. Skim docs/upgrade.md before touching an existing install; this package moves quickly and the upgrade notes carry the real breaking-change weight.<hw:video-embed url="https://www.youtube.com/watch?v=..." /> — and confirm it renders server-side with no JS. It's the lowest-risk way to verify the component pipeline, asset publishing, and config are all wired correctly.<hw:modal> (or Sheet/Drawer) host in your layout, add an <hw:overlay-return> region, and open a form into it via response()->modal()->open(...). That single flow exercises the response macros, overlay-return, and the bundled controllers together.php artisan hotwire:check on day one. It gives you a clean/dirty report on package drift before you've written any app code, so later failures are unambiguous.Video embeds. Prefer the component for any known YouTube/Vimeo URL: it renders without JavaScript and falls back to a plain link for unsupported providers, which means content stays accessible and indexable even if your JS bundle fails. Set the responsive ratio, loading strategy (lazy for below-the-fold), accessible title, and YouTube privacy mode via component attributes rather than per-call markup. Keep the standalone OEmbed controller for editor-generated HTML where the URL arrives at runtime from user content and you need application-owned styling — that's the intended split, not a duplication.
One overlay host, many openings. Declare a single Modal/Sheet/Drawer host in the layout and open several instances from it — no application-authored clone ids, no extra host per form. Set size and side per opening: response metadata takes precedence over the loading hint and only affects that instance. Navigation and validation stay inside the current instance, so parent drafts, focus, and unrelated errors survive. Reach for a second host only when you genuinely want separate lifecycles, not to work around id collisions.
Server-driven open, return, close. Open with response()->modal()/sheet()/drawer()->open(...), composed with ->update() and toasts in the same response. Return field HTML with returnFromOverlay($origin, $content) — the content is the complete contents of the parent region captured by <hw:overlay-return> and the opener's overlay-return prop. Close with closeOverlay($origin), which is instance-scoped: a late response cannot affect a later opening, and a replaced return destination fails safely rather than writing into the wrong place. Keep controllers that serve both page and overlay requests null-guarded on $request->overlayOrigin().
Nested and streamed overlays. Stream openings pass an explicit origin: so children are scoped to the right instance, and require source: when the fragment contains a form. For rich or contextual fields, compose application-owned fragments or native Turbo Frames — there is deliberately no package-managed renderer or retry flow.
Validation and focus. Opt into error-focus on <hw:form> to focus the first eligible invalid control after validation, including delayed Rich Text initialization. When an overlay's original opener is no longer focusable, the autofocus controller falls back to the active Dropdown or Popover trigger — so don't hand-roll focus restoration for that case.
Selective bundles and drift. Generate a preset bundle with hotwire:bundle-preset, then commit the recorded plan alongside the output. Replay the same selection on other branches or fresh checkouts with hotwire:bundle-preset --from <plan>. In CI or a pre-commit hook, run hotwire:check --fix — it regenerates untouched package drift while leaving your application edits alone, and reports a focused diff of what it changed.
Component authoring. Use hw: short tags freely in Blade templates. Compose UI from package components (Sidebar groups, Video Embed, overlay hosts) and keep your own CSS in application stylesheets rather than editing the generated bundle, so --fix stays a no-op for you.
Diagnostics as a workflow. Treat hotwire:check output as part of the dev loop, not a post-deploy chore. Owner-required warnings now point at the specific attribute or public property shadowing component context, so resolve them at the call site rather than by clearing state inside the component.
modal-auto-close is gone. Replace any marker-appending close with closeOverlay(), delete published copies of the controller, and rebuild assets. Old marker-append code won't just warn — it silently does nothing useful.$request->overlayOrigin() rather than the canonical host id, and guard null for actions that also serve ordinary page requests. Static overlays close by their root id.returnFromOverlay() supplies the complete region contents; host:, result:, and package-managed return renderers are not supported. If you were relying on the old renderer, build the fragment yourself.source: when they contain a form, and origin: on children — omission is the most common cause of a form posting to the wrong instance.hotwire:bundle-preset before relying on --from or --fix. Invalid plans and removed presets now fail with recovery paths — read them, they usually name the exact preset to restore or regenerate.--fix is deliberately conservative. It only regenerates untouched package drift. If you've hand-edited a generated file, it will not silently overwrite it — you'll get a focused diff. That's the safety feature, not a bug; resolve by moving your edits into application CSS/JS instead of the bundle.hw: tags compile only in genuine Blade markup; literals inside PHP strings, heredocs, and component attributes are left alone. If you were generating Blade dynamically or had hw: in a string as a workaround, verify it still behaves as intended — it will no longer be expanded.pointer-events-none or z-index hacks to fix menu buttons under collapsed groups, remove them — they're redundant now and may cause their own regressions.hotwire:check first (read-only), then the upgrade, then hotwire:bundle-preset for plan regeneration, then hotwire:check --fix as a separate commit so regenerated bundle diffs are reviewable in isolation from your app changes. For 0.83.0 specifically, also grep your app for modal-auto-close, published overlay controllers, and any host:/result: response arguments before rebuilding assets.How can I help you explore Laravel packages today?