Fixes #5462, #5467, #5471, #5466, #5470, #5464 and comments on PR #4570.
The original bug
This issue originally started when the persistant middleware feature was added to Livewire.
When this was added, Livewire support for locale prefixes broke, as it was trying to match routes based on the /
root path. But localised applications may have a prefix like /en
in the path.
A 404 is triggered when the route cannot be matched.
This was fixed in v2.3.14, by first trying to match the root route, and if that doesn't work then it gets the locale from the fingerprint, removes it from the path and tries again.
The bug that was recently fixed
But it still didn't completely fix the issue, due to a bug with the Str::replaceFirst()
parameter order, causing it to always return a URL of an empty string "" which is essentially the root URL.
If the root route has authentication on it, and the user isn't logged in, it actually triggers a redirect to the login page, causing Livewire to break completely, as the response is the HTML for the login page.
If there is no authentication though, there are other instances where a NotFoundHttpException
can occur (such as if there is no root route), triggering the 404 modal.
You can see an example of this bug in the below screenshot (see ReplaceFirst with bug
output).
It takes the current url http://livewire-httpconnectionhandler-demo.test/en/welcome
and returns an empty URL.
A fix was recently merged for this in PR #4570 that swapped the order of the parameters in Str::replaceFirst()
and the result is shown above (see ReplaceFirst with fix
), where the URL correctly has the locale removed.
The above fix works great for anyone using packages like mcamara/laravel-localization so that localisation is handled correctly.
The latest bugs
The fix which corrected the parameter order of Str::ReplaceFirst
has uncovered two new bugs, one of which is when running a Laravel/Livewire app in a sub directory, and the other is when using localisation on the root route.
Localisation on the root route
For an app that uses localisation on the root route, it would have a URL like http://livewire-httpconnectionhandler-demo.test/en
. This URL currently triggers a 404 with the fix from PR#4570 due to it trying to match the locale and then a forward slash.
This can be fixed by ensuring the forward slash is before the locale instead of after, as noted here.
Hosting in a subdirectory
In the scenario where a Laravel/Livewire application is hosted in a subdirectory, currently the latest release of Livewire (v2.10.8) breaks all Livewire components when a subsequent request is triggered.
First question is, why are people hosting them in subdirectories? As it turns out, there are quite a lot of people who still use Apache, and only have a single web root folder configured on their local machines. Therefore then run all they're apps out of subdirectories. So this issue is mainly impacting their local development environment. But when the deploy their app to a proper domain, it is fine.
So what is happening is, if running an application using a URL such as http://localhost/myapp/mycomponent
, any subsequent Livewire requests return a 404, as the route that is trying to be matched is /myapp/mycomponent
instead of the path relative to the project of /mycomponent
.
Now as to why this bug has started happening.
The reason for this is, now that the Str::replaceFirst()
is actually returning a full URL (instead of an empty string), Livewire is making use of this URL to match it against any available routes to try and find the original route (for the persistent middleware feature).
To determine the original route and its assigned middleware, Livewire generates a fake request using the URL and method provided. This request is then used to match against routes in Laravel's router.
But the faked request that gets generated isn't aware of the projects true base path being inside a subdirectory in the main web root folder, as such believes it's base path is the web root folder, causing to try and match the full URI (/myapp/mycomponent
) as explained above.
To fix this, we can make use of the real request to Livewire's endpoint to determine the projects actual path and pass these details into the faked request, allowing it to run the match correctly.
Conclusion
This PR fixes both of the above issues. I have tested it locally using a repo that has localisation and another repo being hosted in a subdirectory, ensuring that the bugs do actually occur and that applying this PR fixes them.
I've also made sure persistent middleware still all works as expected.
These issues are related but also distinct, so if required, I can split into two PRs, but felt it was easier just to give all the context in one PR.
I have no idea how to test this, as such haven't added tests to this PR.
Hope this helps!