laravel-localization icon indicating copy to clipboard operation
laravel-localization copied to clipboard

Route Trans Caching is broken with Livewire 3

Open relaypilot opened this issue 1 year ago • 17 comments

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:

  1. Require Livewire 3 and update the Livewire update route (as recommended in the official Livewire documentation)
  2. Cache localized routes using: php artisan route:trans:cache
  3. Browse your website using a Laravel Localization locale (EN in my example)
  4. Open the browser console and click on a Livewire button (or any Livewire action)
  5. 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

relaypilot avatar Aug 10 '23 08:08 relaypilot

Having the same issue

ArtMin96 avatar Aug 19 '23 20:08 ArtMin96

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

greggh avatar Aug 29 '23 21:08 greggh

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);
    });
});

dennisvandalen avatar Sep 02 '23 09:09 dennisvandalen

Experiencing the same. In my case it works after clearing cache, but once cached, it fails.

mperezsc avatar Sep 03 '23 07:09 mperezsc

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

core45 avatar Sep 06 '23 10:09 core45

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?

dennisvandalen avatar Sep 06 '23 10:09 dennisvandalen

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('/');
    }

RikoDEV avatar Sep 07 '23 12:09 RikoDEV

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.

core45 avatar Sep 07 '23 16:09 core45

Did anybody found a workaround?

poldixd avatar Sep 26 '23 10:09 poldixd

Did anybody found a workaround?

https://github.com/mcamara/laravel-localization/issues/880#issuecomment-1703773314

ArtMin96 avatar Sep 26 '23 10:09 ArtMin96

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.

core45 avatar Sep 26 '23 11:09 core45

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.

poldixd avatar Sep 27 '23 12:09 poldixd

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.

Awesome, this works perfectly!

dennisvandalen avatar Sep 28 '23 07:09 dennisvandalen

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.

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.

mperezsc avatar Oct 08 '23 15:10 mperezsc

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.

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

BarionTechnology avatar Dec 27 '23 22:12 BarionTechnology

Thank you so much! You saved my day!

kevinaswind avatar Feb 23 '24 06:02 kevinaswind

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 :)

inalto avatar Apr 22 '24 17:04 inalto