livewire: Fixing "Livewire is not defined" on various hosting environments
Please bear with me – I know this is a giant wall of text, but I felt it is necessary to address the concerns that I will mention with absolute clarity.
Problem:
The /livewire/livewire.js Laravel route causes issues with certain hosting environments that (by default) route all file based requests to the hosts filesystem. This is due to the .js file suffix – as there is not actually a file residing in the users public/ directory (without publishing Livewire’s assets).
Description:
Currently in all versions of Livewire, the recommended approach is to leave livewire.js file unpublished, and to simply use the @livewireScripts Blade directive to include the <script> tag to the /livewire/livewire.js route that is registered inside the LivewireServiceProvider:
Ex:
<!-- Directive: -->
@livewireScripts
<!-- Produces: -->
<script src="/livewire/livewire.js?id=936e5d0fb0b76b631ba7" data-turbo-eval="false" data-turbolinks-eval="false"></script>
The problem with this, is that most Nginx configs that I’ve seen, and the built-in PHP development server, will not proxy the .js file request through Laravel itself. It will instead attempt to look for an actual file on the server in the public/livewire/livewire.js path, but return a 404, because the server says the file does not actually exist.
For example, the below screenshots were taken using the built-in PHP web server (cd public && php -S localhost:8000):
Console:

PHP Server Error:

PHP Server Console Error:
We can resolve this specific issue for all hosting environments by simply removing the .js suffix on the route (if the user has not published their assets). The request will then be treated as a normal application request, and the proper livewire.js file contents will be returned from the web server. Livewire does not need to specify the .js extension for the script to be properly loaded.
However, while this will actually make Livewire work, we will also need to adjust how Livewire routes messages from components.
Livewire will attempt to communicate with components with the URL /livewire/message/{name} route defined here:
Though this introduces the same issue as above, since the Livewire attempts to use the URL convention below, which includes an unescaped period (.), which the server will infer as a file request:
http://localhost/livewire/message/{component}.{method}

I can submit a PR to resolve these issues – but before I do that, I wanted to get another set of eyes on this in case I’m not seeing something that could cause BC breaks.
Please let me know if any further clarity is needed, or if you’d like me to just submit the PR and you can accept/deny it there 👍
Thanks for your time! ❤️
Related issues:
- https://github.com/livewire/livewire/issues/794
- https://github.com/laravel/jetstream/issues/112
- https://github.com/laravel/jetstream/issues/236 (and more on the Jetstream repo)
Exact steps to reproduce:
laravel new livewire-test --jet- Select
livewire(0) - Run
npm i && npm run dev - Change
DB_CONNECTIONtosqlitein.env - Run
php artisan migrate - Run
cd public && php -S localhost:8000 - Open the browser console and attempt to use Jetstream normally
Environment Context:
- Livewire version: All
- Laravel version: N/A
- Alpine version: N/A
- Browser: All
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 16 (7 by maintainers)
SOLVED/WORKAROUND: In my case the public/.htaccess file of my Laravel installation was not recognized. I had to change a setting of the apache2.conf (apache config file on Ubuntu). I edited the
to
As a result the standard Laravel .htaccess can finally do its job and Livewire works as expected. (ref.: https://stackoverflow.com/questions/18740419/how-to-set-allowoverride-all).
@devutoo in the thread that you copied in it seems like it was an issue with their Nginx configuration. This happens to be in the Laravel docs https://laravel.com/docs/7.x/installation#pretty-urls. It also includes an example for Apache. This assumes you’re using mod_php and not something like php-fpm.
Have you tried that?