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:

https://github.com/livewire/livewire/blob/8663232c198ef12964b62559e9bb2023eb86701d/src/LivewireServiceProvider.php#L129-L130

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:

Screen Shot 2021-01-11 at 5 58 29 PM


PHP Server Error:

Screen Shot 2021-01-11 at 5 58 53 PM


PHP Server Console Error:

Screen Shot 2021-01-11 at 6 04 20 PM

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:

https://github.com/livewire/livewire/blob/8663232c198ef12964b62559e9bb2023eb86701d/src/LivewireServiceProvider.php#L132-L133

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}

Screen Shot 2021-01-11 at 6 18 18 PM

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:

Exact steps to reproduce:

  1. laravel new livewire-test --jet
  2. Select livewire (0)
  3. Run npm i && npm run dev
  4. Change DB_CONNECTION to sqlite in .env
  5. Run php artisan migrate
  6. Run cd public && php -S localhost:8000
  7. 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)

Most upvoted comments

Thank you @ju5t . I am using mod_php. And I changed the .htaccess according to the docs section, that you proposed. Unfortunately it didn’t solve the problem.

Edit: I tried it on a fresh VM with Ubuntu Server. Via putty I created a new Laravel project, installed Livewire and recreated the counter example. It didn’t work neither.

Edit2: I tried different Livewire versions (from 2.2.0 to latest) and it didn’t matter.

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

<Directory /var/www/>
AllowOverride None
</Directory\>

to

<Directory /var/www/>
AllowOverride All
</Directory>

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?