Laravel - How to Create a Laravel Livewire Modal

Published by Theodoros Kafantaris

Jan 06, 2025

Introduction

Modals are a common feature in web applications, providing a way to display content in a focused view while dimming the rest of the page. Using Laravel Livewire, you can create dynamic modals that respond to user interactions without requiring a full-page reload.

In this guide, we will walk through creating a Livewire modal using a simple example.

Code Example

Below is the complete code for creating a Livewire modal component.

Here is the Livewire component code:

<?php

use Livewire\Volt\Component;

new class extends Component {
    public $isOpen = false;

    public function toggleModal()
    {
        $this->isOpen = !$this->isOpen;
    }
};
<div>
    <div class="max-w-[85rem]   mx-auto">
        <div class="flex flex-col items-center">
            <p class="mt-1 mb-2 text-gray-600 dark:text-gray-400">You can control the modal</p>
            <button wire:click="toggleModal" class="px-4 py-2 text-sm font-semibold text-white bg-green-600 rounded-lg shadow-md hover:bg-green-700 focus:outline-none focus:ring focus:ring-green-300">
                {{ $isOpen ? 'Hide Modal' : 'Show Modal' }}
            </button>

        </div>
    </div>
    @if($isOpen)
    <div x-data="{ isOpen: @entangle('isOpen') }"
        x-on:keydown.escape.window="$wire.set('isOpen', !isOpen)"
        class="relative z-10" aria-labelledby="modal-title" role="dialog" aria-modal="true">
        <!-- Background backdrop -->
        <div class="fixed inset-0 bg-gray-500/75 transition-opacity" aria-hidden="true"></div>
        <div class="fixed inset-0 z-10 w-screen overflow-y-auto">
            <div class="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
                <!-- Modal panel -->
                <div class="relative transform overflow-hidden rounded-lg bg-white px-6 pb-6 pt-7 text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-2xl sm:p-8"
                    x-show="isOpen"
                    x-transition:enter="ease-out duration-300"
                    x-transition:enter-start="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
                    x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100"
                    x-transition:leave="ease-in duration-200"
                    x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
                    x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
                    @click.away="$wire.set('isOpen', !isOpen)">

                    <div class="text-center sm:mt-5">
                        <h3 class="text-xl font-semibold text-gray-900" id="modal-title">Modal Details</h3>
                        <div class="mt-2">
                            <p class="text-sm text-gray-500">Fill the details of the modal</p>
                        </div>
                        <div class="mt-5">
                            Modal Details
                        </div>
                    </div>
                </div>
            </div>
            @endif
        </div>
    </div>
</div>


Explanation of the Code

Toggle Button

  • The button toggles the modal by calling the toggleModal method in the Livewire component.
  • It dynamically changes its label between "Show Modal" and "Hide Modal" based on the $isOpen state.

Conditional Rendering

  • The modal is only rendered when $isOpen is true using the @if($isOpen) directive.

Alpine.js for Interactivity

  • Alpine.js is used for additional interactivity, such as closing the modal when clicking outside it or pressing the Escape key.
  • The @entangle('isOpen') directive keeps the $isOpen state in sync between Livewire and Alpine.js.

Transitions

  • Smooth transitions are added using Alpine.js directives like x-transition:enter and x-transition:leave.

Accessibility

  • ARIA attributes like aria-labelledby and aria-modal are included to make the modal accessible.

Conclusion

This example demonstrates how to create a responsive and accessible modal using Laravel Livewire and Alpine.js. The dynamic state management provided by Livewire makes it easy to build interactive components without writing custom JavaScript code.

You can extend this example by adding forms or other content to the modal, depending on your application's needs.

Happy coding!

Ⓒ 2025. All rights reserved by atomic