What do you need vite for when it comes to livewire? Do you mean alpinejs ?
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?
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.
@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'])
@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.
@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 :)
and, you also have the livewire scripts at the end of your layout?
....
@livewireScripts
</body>
...
@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
@viappio are you getting any errors in the browser console?
@Sinnbeck no, not a single warning..
@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
@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?
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>
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>
...
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.