This article covers implementing pagination in Laravel Blade.
The short answer: call paginate() in the controller and write {{ $items->links() }} in the Blade view. That is the whole thing. You only need to go further when the design has to change.
If the page has search filters or sorting, do not forget withQueryString(). Without it, the filters are dropped the moment someone opens page two. It is the most common thing to get wrong here.
Sponsored
Implementing pagination in Blade
Setting up pagination
Laravel provides pagination out of the box. In the controller, use paginate() on the query.
$items = DB::table('items')->paginate(10);
Rendering it in the Blade template
Loop over the results as normal, then call links() to render the page links.
@foreach ($items as $item)
<!-- render each item -->
@endforeach
<!-- the pagination links -->
{{ $items->links() }}
Customising the pagination
Changing the design
Pass the view you want to links().
{{ $items->links('pagination.custom') }}
Rather than writing one from scratch, publish Laravel’s own views and edit those.
php artisan vendor:publish --tag=laravel-pagination
The templates land in resources/views/vendor/pagination/, ready to edit.
If the project uses Bootstrap, you can switch without writing a view at all. Add this to boot() in AppServiceProvider:
use Illuminate\Pagination\Paginator;
public function boot(): void
{
Paginator::useBootstrapFive();
}
Changing the number of items
Pass the count to paginate(). The default is 15.
$items = DB::table('items')->paginate(20);
Sponsored
Preserving search filters
Use withQueryString() to carry the current query string onto the pagination links.
$items = DB::table('items')
->where('category', $request->category)
->paginate(10)
->withQueryString();
Without it, opening page two of a filtered list returns the unfiltered set. To the user it looks as though the search stopped working, which makes the cause hard to spot from a bug report.
For very large tables, consider simplePaginate():
$items = DB::table('items')->simplePaginate(10);
paginate() runs a COUNT query to work out the total number of pages. simplePaginate() does not. If “previous” and “next” links are all you need, it is measurably faster — you lose the numbered page list in exchange.
Summary
Three things to remember:
paginate()in the controller,links()in the viewwithQueryString()whenever there are filters- Publish the views with
vendor:publishbefore customising the design
For setting up the Laravel environment, see building a Laravel and Blade environment with Docker. To put the finished site on a server, deploying Laravel to Xserver with git covers the steps.