Muhammad Yasir Amin

Loading website…

More from Muhammad Yasir Amin

Build Along With Me

Practical walkthroughs on Laravel, React, APIs and deployment workflows.

Subscribe on YouTube

Laravel 13 Livewire 4 Pagination Tutorial with Search

🛠️ Laravel Tutorials4 min read

Laravel 13 Livewire 4 Pagination Tutorial with Search

Muhammad Yasir Amin

Muhammad Yasir Amin

Senior Full Stack Engineer•Nov 12, 2026
Laravel 13 Livewire 4 Pagination Tutorial with Search

To paginate data in Livewire 4, add the WithPagination trait to your component, return a paginator from a computed property and print the links with $this->posts->links(). Livewire then changes pages without a full reload. This tutorial builds a paginated post list with live search for Laravel 13, and shows how to reset the page when the search text changes.

Targets: Laravel 13 (PHP 8.3 to 8.5) and Livewire 4. In Livewire 4 the documented component style is a single file: PHP class and Blade markup together in one file.

Step 1: Install Livewire

Code
composer require livewire/livewire

Livewire needs a layout that loads its assets. If your layout does not include them automatically, follow the installation page of the Livewire documentation.

Step 2: Prepare a Post model with sample data

Code
php artisan make:model Post -mf
Shell
Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->string('title');
    $table->text('body');
    $table->timestamps();
});
JavaScript
// database/factories/PostFactory.php
public function definition(): array
{
    return [
        'title' => fake()->sentence(6),
        'body' => fake()->paragraph(),
    ];
}
Code
php artisan migrate
php artisan tinker --execute="App\Models\Post::factory()->count(50)->create();"

Step 3: Create the paginated component

Create the file resources/views/components/⚡post-list.blade.php (you can also generate it with php artisan make:livewire post-list). It uses the same structure as the pagination examples in the Livewire 4 documentation:

JavaScript
<?php

use App\Models\Post;
use Livewire\Attributes\Computed;
use Livewire\Component;
use Livewire\WithPagination;

new class extends Component {
    use WithPagination;

    public string $search = '';

    public function updatedSearch(): void
    {
        $this->resetPage();
    }

    #[Computed]
    public function posts()
    {
        return Post::query()
            ->when($this->search !== '', fn ($query) => $query->where('title', 'like', '%'.$this->search.'%'))
            ->latest()
            ->paginate(10);
    }
};
?>

<div>
    <input type="search" wire:model.live.debounce.300ms="search" placeholder="Search posts...">

    <ul>
        @forelse ($this->posts as $post)
            <li wire:key="post-{{ $post->id }}">{{ $post->title }}</li>
        @empty
            <li>No posts found.</li>
        @endforelse
    </ul>

    {{ $this->posts->links() }}
</div>

How does this code work?

  • WithPagination makes Livewire read and write the current page and update the list without a browser reload.
  • #[Computed] turns the posts() method into a property you read as $this->posts. The query result is cached for the single request, so the template can use it several times without extra queries.
  • paginate(10) returns a normal Laravel paginator, so links() renders the usual page links.
  • updatedSearch() is a lifecycle hook that runs when $search changes. Calling resetPage() there sends the user back to page 1.
  • wire:model.live.debounce.300ms updates the search property while typing, waiting 300 milliseconds after the last key press so you do not query on every letter.
  • wire:key gives each list item a stable identity, which helps Livewire update the DOM correctly.

Step 4: Show the component on a page

Code
<livewire:post-list />

Put the tag in any Blade view, for example resources/views/posts.blade.php, and add a route:

CSS
Route::view('/posts', 'posts');

Why reset the page on search?

Suppose you are on page 5 and type a search that returns only two pages. Without resetPage() Livewire asks for page 5 of the filtered results, which is empty. Resetting makes the first matching results appear immediately.

How do I change the pagination style?

Livewire uses Laravel's pagination views. To use simple Previous/Next links call simplePaginate(10) and render with links(). To edit the generated markup, publish Laravel's pagination views with php artisan vendor:publish --tag=laravel-pagination.

How do I check that it works?

  1. Open /posts and confirm 10 posts and page links appear.
  2. Click page 2 and verify that the page does not reload (the network tab shows a Livewire request).
  3. Type a word from a title and confirm the list filters and returns to page 1.

Common mistakes

  • Forgetting the WithPagination trait: page links render but clicking them does nothing useful.
  • Not resetting the page after a filter changes: users see empty pages.
  • Querying inside the Blade template: it runs on every render. Use a computed property.
  • Using a public property to hold the paginator: paginators should not be stored on the component. Return them from a computed property or render().
  • Missing wire:key in loops: lists can show stale rows after updates.

FAQ

Does this work with Livewire 3 too?

The ideas are the same (trait, paginator, resetPage). Livewire 3 uses class-based components in app/Livewire with a separate view, so the file layout differs.

Can I have two paginators on one component?

Yes. Give the second one a custom page name, for example paginate(10, pageName: 'commentsPage'), and use the matching name in resetPage('commentsPage').

Can I keep the page in the URL?

Livewire can sync the page number with the query string so a reload keeps the user on the same page. See the pagination page of the Livewire documentation for the current option.

References

Article Index & Topic Tags
LaravelPaginationLivewire

YouTube Channel

Build Along With Me

Practical walkthroughs on Laravel, React, APIs and deployment workflows.

Muhammad Yasir Amin
Available for Contracts
Author & Solutions Architect

Senior Full Stack Engineer

Independent Senior Full Stack Engineer working on Laravel, React and Next.js applications, APIs and delivery workflows.

Laravel & PHP ApplicationsReact & Next.js InterfacesREST APIs & IntegrationsDatabase Queries & DebuggingDocker Development WorkflowsClear Scope & Handover
Discuss Your Next Step

What Does Your Application Need Next?

Share your current system, the problem you want to solve and what a useful result looks like. We can identify the right starting point and agree on a practical scope.

Technical Audit

Find the Next Useful Fix

Application Development

Scoped, Reviewable Milestones

Ongoing Support

Agreed Capacity and Priorities

Share your goals, current stack and requirements before the call.