Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

mvpop's avatar
Level 9

Livewire Pagination Error - The GET method is not supported for this route.

So I have the following route:

Route::get('produse/', 'ProduseController@index')->name('arataProduse');

And I return a blade view return view('produse.index'); from ProduseController@index

Now in my blade view I load a Livewire component <livewire:component-name />

The component is basically a datatable with some crud functionality taken care by Livewire.

THE PROBLEM

Once I delete a record from my table and I try to go to any page of the table, I get a 404 Not found error. This happens only after performing the delete() on the model. It doesn't happen after the create or edit methods being called, just on delete.

This is the code for the delete method:

$produse = Produse::whereKey($this->selectate);
        $produse->delete();
        $this->arataModalStergere = false;

What can get wrong ?

After the not found error is produced, I have another error in the console saying Failed to load resource: the server responded with a status of 404 (Not Found) and if I click on the link in the console this is what I get The GET method is not supported for this route. Supported methods: POST.

If I hit refresh everything works just fine.

Any idea why I get this behavior?

Thanks.

0 likes
21 replies
CorvS's avatar

@mvpop What exactly does you Livewire component look like? Especially the delete button, did you use a <a> tag there or wrapped it inside a form that is submitted?

1 like
mvpop's avatar
Level 9

I toggle a modal and this is what I have in the modal

<form wire:submit.prevent="stergeProduseSelectate">
        <x-modal.confirmation wire:model.defer="arataModalStergere">
            <x-slot name="title">Șterge Produs</x-slot>

            <x-slot name="content" >
                <div class="py-8 text-cool-gray-700 text-sm">
                    Esti sigur că vrei să continui ? Această acțiune este
                    ireversibilă.
                </div>
            </x-slot>

            <x-slot name="footer">
                <x-button.secondary wire:click="$set('arataModalStergere', false)">Anulează</x-button.secondary>
                <x-button.danger type="submit">Șterge</x-button.danger>
            </x-slot>
        </x-modal.confirmation>
    </form>

Now the form is calling the stergeProduseSeletate (eng: deleteSelectedProducts) and the Șterge (eng: Delete) buton is of a type=submit

I have similar logic for adding a new product and there seems to be everything just fine.

mvpop's avatar
Level 9

I think the error occurs because the pagination submits data to a get route. Using Livewire I submit data as Ajax post request so I cannot call a post route via default get Call. If I delete a product from page 2 and I manually type page=1 in the URL it works because it is causing a full page refresh. So I am guessing this is a pagination issue. However, not sure what to do about it.

frankielee's avatar

Check the URL of your webpage after the full page refreshed/form submitted.

Check the href attribute of the pagination button

1 like
frankielee's avatar

Can you show your livewire.php?

Have these codes added?

use Livewire\WithPagination;

class foo{
use WithPagination;


    protected $queryString = [
        'query' => ['except' => ''],
        'page' => ['except' => 1],
    ];
}
1 like
mvpop's avatar
Level 9
<?php

namespace App\Http\Livewire;

use Livewire\WithPagination;
use Livewire\Component;
use App\Produse;


class CatalogProduse extends Component
{
    use WithPagination;

    public $arataModalStergere = false;
    public $arataFormularEditare = false;
    public $sortField = 'denumire';
    public $sortDirection = 'asc';
    public $selecteazaToataPagina = false;
    public $selecteazaTot = false;
    public $selectate= [];
    public $search = '';
    public Produse $editeazaProdus;

    protected $queryString = ['sortField', 'sortDirection'];
    
    protected $rules = [
        'editeazaProdus.denumire' => 'required',
    ];

    public function sortBy($field)
    {
        if ($this->sortField === $field) {
            $this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
        } else {
            $this->sortDirection = 'asc';
        }

        $this->sortField = $field;
    }

    public function mount() { $this->editeazaProdus = Produse::make(['created_at' => now()]); }

    public function selecteazaTot()
    {
        $this->selecteazaTot = true;
    }

    public function selecteazaToataPagina()
    {
        $this->selectate = $this->produse->pluck('id')->map(fn($id) => (string) $id);
    }

    /**
     *  CRUD
     */

    public function editeaza(Produse $produs)
    {
        if ($this->editeazaProdus->isNot($produs)) $this->editeazaProdus = $produs;
        $this->arataFormularEditare = true;
    }

    public function adaugaProdus()
    {
        if ($this->editeazaProdus->getKey()) $this->editeazaProdus = Produse::make(['created_at' => now()]);
        $this->arataFormularEditare = true;
    }

    public function salveazaProdusul()
    {
        $this->validate();
        $this->editeazaProdus->save();
        $this->arataFormularEditare = false;
    }

    public function stergeProduseSelectate()
    {
        $produse = Produse::whereKey($this->selectate);
        $produse->delete();
        $this->arataModalStergere = false;
    }

    /**
     *  --------------
     */

    public function getProduseQueryProperty()
    {

        return Produse::query()
            ->search('denumire', $this->search)
            ->orderBy($this->sortField, $this->sortDirection);

    }

    public function getProduseProperty()
    {
       return $this->produseQuery->paginate(5);
    }

    public function render()
    {
        if ($this->selecteazaTot) $this->selectate= $this->produse->pluck('id')->map(fn($id) => (string) $id);

        return view('livewire.catalog-produse', [
            'produse' => $this->produse,
        ]);
    }

     /**
     *  Livewire Lifecycle Hook
     */


     public function updatedSelectate()
     {
        $this->selecteazaTot = false;
        $this->selecteazaToataPagina = false;
     }

     public function updatedSelecteazaToataPagina($value)
     {

         $this->selecteazaTot = false;
         $this->selectate = [];

        if ($value) {
            $this->selectate = $this->produse->pluck('id')->map(fn($id) => (string) $id);
        } else {
            $this->selectate = [];
        }
     }

    public function updatingSearch(): void
    {
        $this->gotoPage(1);
    }

}
frankielee's avatar
Level 29

I was able to trigger the issue by calling the pagination links like below

{{ $data->links() }}

I fixed that by adding withQueryString(), hope this help

{{ $data->withQueryString()->links() }}

Edit: The URL that brought this error

http://127.0.0.1:8000/livewire/message/users?page=7
3 likes
mvpop's avatar
Level 9

Awesome, works now. Thanks.

frankielee's avatar

No problem, I just remembered facing this issue before.

1 like
mvpop's avatar
Level 9

The problem was not from the conditional logic I have previously posted but because I had to php artisan vendor:publish --force --tag=livewire:assets

Working just fine now.

mvpop's avatar
Level 9

worked, once, back to square one again.

1 like
mvpop's avatar
Level 9

I still have that error tho. I will make it a package once I sort it out.

mvpop's avatar
Level 9

Ok, so I'm back with the fix. The editing attribute in my Livewire component still remains indicating an already deleted model which causes a 404 response for each next request.

So on the delete method, I reset the editing attribute like so:

$this->editing = Products:make();

ahmedkandil's avatar

firstly you should use WithPagination in components like that

 use WithPagination;

and don't forget to load the namespace

use Livewire\WithPagination;

now you can use links method like

 {{$data->links()}}

if pagination numbers are hidden use themes in component classes like

protected $paginationTheme = 'bootstrap';
1 like

Please or to participate in this conversation.