Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

viappio's avatar

Livewire and vite not working together

Hi guys, i'm getting mad while using livewire combined with vite. It seems that Livewire isnt ready in the blade cause it is loaded as a deferred module by default by vite. I saw that someone asked for the feature of disabling this in vite forum but i couldn't a find a single line of documentation and i'm not familiar with vite at all. Someone said that i need to create a vite plugin to pass the whole html generated by laravel and replace "defer" with blank but i don't know how to do it, especially in the Laravel environment. I'm using the latest laravel version 9.X that have only vite and not mixin. Any ideas on how to do it?

0 likes
15 replies
Sinnbeck's avatar

What do you need vite for when it comes to livewire? Do you mean alpinejs ?

viappio's avatar

Thanks for the reply! In the new Lavarel version there's this vite.config.js where i put js and css to be included in my laravel pages. Then in my app.blade i have this: @vite(['resources/css/app.css','resources/js/app.js',]) to include those files. I assumed (maybe im wrong) that vite was responsible for the inclusions, and it seems that the modules are included as deferred by default. Alpine is included in the app.js. I'm a bit confused to be honest.

Sinnbeck's avatar

@viappio Yeah that is correct. And alpine works fine with vite. I use it myself

In my app.js

import Alpine from 'alpinejs'

window.Alpine = Alpine
Alpine.start()

and vite.config.js

laravel({
            input: [
                'resources/css/app.css',
                'resources/js/app.js', //loading it
            ],
        }),

and then in my livewire layout

@livewireStyles
@vite(['resources/js/app.js', 'resources/css/app.css'])
2 likes
viappio's avatar

@Sinnbeck Same here but no luck. I think this is a race on the import generated by the defer option. Livewire component are generated but every wire: command are not. I think that Livewire simply isnt' there when the blade code are generated. If try to use Livewire (as js command) there, it is not loaded yet, but if I try to use it in the browser debug console, it works.

Sinnbeck's avatar

@viappio I will need to see how you are doing things and the code that isnt working. I use both alpine and livewire in a complete project and it works fine with vite :)

webrobert's avatar

@viappio

and, you also have the livewire scripts at the end of your layout?

....
     @livewireScripts
 </body>
...
2 likes
viappio's avatar

@Sinnbeck app.blade.php

...
        <!-- Styles -->
        @livewireStyles

        <!-- Scripts -->
        @vite(['resources/css/app.css', 'resources/css/crm.css', 'resources/css/inputs.css', 'resources/js/app.js'])

    </head>

here's the actual page using the app template

...
    @livewire('user-table')

    <button wire:click.prevent="$emit('showModal', 'deactivateUser')"
        class="float-bottom-right fab fab-transition button-accent-color">
        <svg viewBox="0 0 22 22" class="w-6 h-6 inline-block">
            <path d="M16,10c0,0.553-0.048,1-0.601,1H11v4.399C11,15.951,10.553,16,10,16c-0.553,0-1-0.049-1-0.601V11H4.601
                                    C4.049,11,4,10.553,4,10c0-0.553,0.049-1,0.601-1H9V4.601C9,4.048,9.447,4,10,4c0.553,0,1,0.048,1,0.601V9h4.399
                                    C15.952,9,16,9.447,16,10z" />
        </svg>
        <span>{{__('crm.nuovo')}}</span>
    </button>

</x-app-layout>
@push('modals')
    @livewire('modals.activate-user-modal',['data'=>''])
@endpush

the vite.config.js

import { defineConfig } from 'vite';
import laravel, { refreshPaths } from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel({
            input: [
                'resources/less/app.less',
                'resources/css/crm.css',
                'resources/css/inputs.css',
                'resources/js/app.js',
            ],

            refresh: [
                ...refreshPaths,
                'app/Http/Livewire/**',
            ],
        }),
    ],
});

the livewire components like user table are succesfully rendered but the button with the wire.click command is not firing anything. Even if i try to put a model using wire:model in the page, isn't working

Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

@viappio i dont see any alpine in the shown code? Livewire isn't compiled with vite so it just seems like a regular livewire problem

1 like
viappio's avatar

@Sinnbeck yeah i was about to reply you. I switched to mix from vite and the problem is the same. Do i have to change title and category?

viappio's avatar

It works if I replace the wire:click method with:

    <button onclick="Livewire.emit('showModal','content')"
        class="float-bottom-right fab fab-transition button-accent-color">
        <svg viewBox="0 0 22 22" class="w-6 h-6 inline-block">
            <path d="M16,10c0,0.553-0.048,1-0.601,1H11v4.399C11,15.951,10.553,16,10,16c-0.553,0-1-0.049-1-0.601V11H4.601
                                    C4.049,11,4,10.553,4,10c0-0.553,0.049-1,0.601-1H9V4.601C9,4.048,9.447,4,10,4c0.553,0,1,0.048,1,0.601V9h4.399
                                    C15.952,9,16,9.447,16,10z" />
        </svg>
        <span>{{__('crm.nuovo')}}</span>
    </button>
viappio's avatar

Also, if i put wire: commands into a livewire component, they works flawlessly... from activate-user-modal.blade.php

...
<div class="bg-gray-50 px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6">
                    <button wire:click.prevent="doClose()" type="button" class="inline-flex w-full justify-center rounded-md border border-transparent bg-red-600 px-4 py-2 text-base font-medium text-white shadow-sm hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 sm:ml-3 sm:w-auto sm:text-sm">Deactivate</button>
                    <button wire:click.prevent="doClose()" type="button" class="mt-3 inline-flex w-full justify-center rounded-md border border-gray-300 bg-white px-4 py-2 text-base font-medium text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">Cancel</button>
                </div>
...

Lokesh003Coding's avatar

I found a workaround but seems to be a kind of a hack, and there are 2 ways to solve that,

First Proper Method:

  • Modify Livewire Component: In your Livewire component's PHP code, dispatch a custom event after the livewire:load event is triggered.
$this->dispatchBrowserEvent('customLivewireLoaded');
  • Modify HTML and JavaScript: In your HTML, include the Livewire component and the JavaScript code to listen for the custom event.
<div>
    <!-- Your Livewire component -->
    <livewire:your-component />

    <!-- Your module script -->
    <script type="module">
		  window.addEventListener('customLivewireLoaded', (event) => {
                console.log('Custom Livewire event received in module script');
                // Your logic here
          });
    </script>
</div>

Second Hack Method:

<!-- Your Livewire component -->
<livewire:your-component />

<!-- Your module script -->
<script type="module">
    window.livewireEventCalls = () => {
        const elementData = $('#elementID'); // in this way Jquery also works

        window.addEventListener('customLivewireLoaded', (event) => {
            console.log('Custom Livewire event received in module script');
            // Your logic here
        });
    }
</script>

<script type="text/javascript">
    document.addEventListener('livewire:load', function () {
       setTimeout(() => livewireEventCalls(), 100);
    }); 
</script>

Please or to participate in this conversation.