In this episode, we're tackling the sometimes-tricky topic of global modals in Laravel Livewire and making it way simpler. Rather than tying modals to specific components (which gets repetitive and messy fast), you'll see how to create a truly global modal system you can trigger from anywhere in your app—even from multiple links in totally different places.
We start from scratch: with a fresh Laravel project (using Breeze as scaffolding), Livewire installed, and of course, Alpine.js for interactivity. The first example is a contact modal, and we walk through creating it, making sure it only shows up when triggered, and connecting it to your UI with a simple Alpine.js trigger. We even add a second modal to spot areas of repeated code, leading us to abstract the common logic into a base modal component using Livewire's inheritance, making future modals super quick to spin up.
To keep modals reusable and manageable, you'll see how to pull the shared Livewire state and show/hide functionality into a base component, then extend it for each different modal you want. On the frontend, we use a Blade component for the modal's actual structure and style, showing you how to slot in custom content and style it with Tailwind CSS. The visibility is linked between Alpine and Livewire with @entangle
, so the two stay in sync without extra requests or weird flickers.
For dismissal, both clicking outside and escape key closing are covered. Plus, we optimize network requests so hiding a modal doesn’t always hit your server. The final result: you can drop modal triggers literally anywhere (header, footer, wherever!) without worrying about where the modal lives. If you need more powerful modals (like forms inside), the episode suggests checking out Laravel Jetstream's modal code for inspiration.
All in all, you’ll walk away knowing exactly how to set up flexible, global modals in Livewire that are easy to maintain and extend. No more hacky or component-tied solutions—just global, easily-triggered, and stylish modals throughout your app!