laravel-localization
laravel-localization copied to clipboard
Route Trans Caching is broken with Livewire 3
Describe the bug
When using Livewire 3, it is not possible to cache the localized routes with php artisan route:trans:cache
.
Livewire 2 automatically preserved the URL prefix when making component updates via https://example.com/en/livewire/update
Livewire 3 has stopped supporting this behavior automatically.
See official Livewire documentation mentioning Laravel Localization: https://livewire.laravel.com/docs/upgrading#localization
To Reproduce Steps to reproduce the behavior:
- Require Livewire 3 and update the Livewire update route (as recommended in the official Livewire documentation)
- Cache localized routes using:
php artisan route:trans:cache
- Browse your website using a Laravel Localization locale (EN in my example)
- Open the browser console and click on a Livewire button (or any Livewire action)
- Console logs a call to
/livewire/update instead
of/en/livewire/update
and returns a 404
Expected behavior
When browing the FR locale (or any other locales), you would expect Livewire to call /en/livewire/update
instead of the non-localized route /livewire/update
This only fails when php artisan route:trans:cache
has been run previously.
If you run php artisan route:trans:clear
, it works correctly.
So something is broken in caching the route.
More info:
- Version of Laravel: 10
- Version of the Laravel-localization package: 1.8
- Which middleware is used in
Route::groups
: setLocale
Having the same issue
I am having this issue without the route:trans:cache. I can clear it and still get the error. It is posting to /livewire/update instead of /en/livewire/update
Same here. Cache is broken.
I does work without caching while adding the new setUpdateRoute
method to the route group.
Route::group(['prefix' => LaravelLocalization::setLocale()], function ()
{
// Your other localized routes...
Livewire::setUpdateRoute(function ($handle) {
return Route::post('/livewire/update', $handle);
});
});
Experiencing the same. In my case it works after clearing cache, but once cached, it fails.
In my case no Livewire 3 component placed on localized route works properly when it comes to update. Routes cached or not.
The solution mentioned by dennisvandalen helped though. Still it should be mentioned in the documentation at least, or better, dealt with
I guess someone needs to review the caching meganism of this package. But I’m not sure how actively maintained it is, looking at the PRs that haven’t been merged or commented on.
@mcamara are you still actively maintaining this package?
It looks like a livewire problem, when I manually edited the https://github.com/livewire/livewire/blob/daa88b5a6203c0e60f0a9bf8a8b5ac1394708ddc/src/Mechanisms/HandleRequests/HandleRequests.php#L29C12-L29C12 line by adding before $this->updateRoute->uri
the current language the update request was executed correctly.
LaravelLocalization correctly registers the route with the prefix, but livewire tries to send the request to the route without prefix.
Working code inside HandleRequests:
function getUpdateUri()
{
return (string) str(app()->getLocale() . "/{$this->updateRoute->uri}")->start('/');
}
or more universal:
function getUpdateUri()
{
return (string) str(route('livewire.update', null, false))->start('/');
}
Whatever the culprit is both Livewire 3 and LaravelLocalization are quite popular packages. But I'd say it's easier to fix LaravelLocalization. Or at least put the info in the docs how fix it for now.
Did anybody found a workaround?
Did anybody found a workaround?
https://github.com/mcamara/laravel-localization/issues/880#issuecomment-1703773314
The workaround is on the top of this thread.
Route::group(['prefix' => LaravelLocalization::setLocale()], function () { // Your other localized routes...
Livewire::setUpdateRoute(function ($handle) {
return Route::post('/livewire/update', $handle);
});
});
What is needed is a permanent solution and a bit of attention by the package owner.
Maybe I found a solution inspired by this file.
Remove this block from the web.php
…
Livewire::setUpdateRoute(function ($handle) {
return Route::post('/livewire/update', $handle);
});
… and put it in the RouteServiceProvider.php
. Don't forget the middleware()
and prefix()
method.
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
use Livewire\Livewire;
// ...
/**
* Define your route model bindings, pattern filters, and other route configuration.
*
* @return void
*/
public function boot()
{
Livewire::setUpdateRoute(function ($handle) {
return Route::post('/livewire/update', $handle)
->middleware('web')
->prefix(LaravelLocalization::setLocale());
});
// ...
}
Now Livewire::setUpdateRoute
will not be cached if you run php artisan route:trans:cache
.
Maybe I found a solution inspired by this file.
Remove this block from the
web.php
…Livewire::setUpdateRoute(function ($handle) { return Route::post('/livewire/update', $handle); });
… and put it in the
RouteServiceProvider.php
. Don't forget themiddleware()
andprefix()
method.use Mcamara\LaravelLocalization\Facades\LaravelLocalization; use Livewire\Livewire; // ... /** * Define your route model bindings, pattern filters, and other route configuration. * * @return void */ public function boot() { Livewire::setUpdateRoute(function ($handle) { return Route::post('/livewire/update', $handle) ->middleware('web') ->prefix(LaravelLocalization::setLocale()); }); // ... }
Now
Livewire::setUpdateRoute
will not be cached if you runphp artisan route:trans:cache
.
Awesome, this works perfectly!
Maybe I found a solution inspired by this file.
Remove this block from the
web.php
…Livewire::setUpdateRoute(function ($handle) { return Route::post('/livewire/update', $handle); });
… and put it in the
RouteServiceProvider.php
. Don't forget themiddleware()
andprefix()
method.use Mcamara\LaravelLocalization\Facades\LaravelLocalization; use Livewire\Livewire; // ... /** * Define your route model bindings, pattern filters, and other route configuration. * * @return void */ public function boot() { Livewire::setUpdateRoute(function ($handle) { return Route::post('/livewire/update', $handle) ->middleware('web') ->prefix(LaravelLocalization::setLocale()); }); // ... }
Now
Livewire::setUpdateRoute
will not be cached if you runphp artisan route:trans:cache
.
Do you consider this a defenitive solution, or should this be temporary until either livewire or this package updates something? Thanks a lot, I really appreciate it.
Maybe I found a solution inspired by this file. Remove this block from the
web.php
…Livewire::setUpdateRoute(function ($handle) { return Route::post('/livewire/update', $handle); });
… and put it in the
RouteServiceProvider.php
. Don't forget themiddleware()
andprefix()
method.use Mcamara\LaravelLocalization\Facades\LaravelLocalization; use Livewire\Livewire; // ... /** * Define your route model bindings, pattern filters, and other route configuration. * * @return void */ public function boot() { Livewire::setUpdateRoute(function ($handle) { return Route::post('/livewire/update', $handle) ->middleware('web') ->prefix(LaravelLocalization::setLocale()); }); // ... }
Now
Livewire::setUpdateRoute
will not be cached if you runphp artisan route:trans:cache
.Awesome, this works perfectly!
This works perfect to me, I have a different error on my website. When I make a searching by wire:model.live, my website redirects to my login. But this solved my issue
Thank you so much! You saved my day!
genius, thankyou it saves to put the hands in livewire.
//Livewire\Mechanisms\PersistentMiddleware\PersistentMiddleware::getRouteFromRequest($request)
$route = app('router')->getRoutes()->match($request);
the getRoutes function was failing to find the route in livewire even if i put livewire/update in the ignore list.
your solution is simple and elegant (after you know how :)