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

dmytroshved's avatar

Reusable sorting & pagination logic for multiple Livewire components. Livewire 3

Hello everyone

Goal: Create reusable sorting and pagination logic for multiple Livewire components.

Description of the problem:

RecipeList.php is responsible for filtering recipes based on URI parameters, as well as sorting and paginating them.

After creating RecipeList.php, I needed to create 2 more components to display lists of recipes for liked & saved recipes. Each recipe list should have sorting and pagination logic, and I'm wondering: is it possible to reuse the sorting and pagination logic to avoid repetition in these three components?

Which logic do the components have in common?

  • sorting
  • pagination

What's different about the components?

  • different recipe lists

Code:

RecipeList.php (short version):

recipe-list.blade.php:

{{-- Dropdown filter --}}
<span>Sort by:</span>
<select name="sorting" wire:model.live="sort">
    <option value="popularity">By Popularity</option>
    <option value="newest">Newest</option>
    <option value="oldest">Oldest</option>
</select>

{{-- Pagination --}}
<div>
    {{ $recipes->links(data: ['scrollTo' => false]) }}
</div>

{{-- Recipes--}}
@forelse($recipes as $recipe)
    <div wire:key="recipe-{{ $recipe->id }}">
        <x-recipe-card :recipe="$recipe"/>
    </div>
@empty
    <span>empty</span>
@endforelse

What options do I have to avoid repeating myself & re-writing the same code for sorting & pagination?

Would be grateful for your help

0 likes
3 replies
dmytroshved's avatar

@jlrdw

Thanks for your reply. Hmm...Im thinking about using Trait instead of custom paginate logic, what do you think about this?

AlbertoC1's avatar

@jlrdw Nice, that makes sense. I’ve used LengthAwarePaginator before but never thought to wrap it in a service for Livewire. Might give that a try and see how clean I can keep the component logic.

Please or to participate in this conversation.