Backend Development 10 min read

Laravel Pagination: Using Query Builder, Eloquent, Simple Pagination, and Custom Views

This guide explains how Laravel's paginator integrates with the query builder and Eloquent ORM, shows basic and simple pagination methods, demonstrates manual paginator creation, customizing URIs, appending parameters, converting results to JSON, and customizing pagination views, all with code examples compatible with Bootstrap.

Laravel Tech Community
Laravel Tech Community
Laravel Tech Community
Laravel Pagination: Using Query Builder, Eloquent, Simple Pagination, and Custom Views

Introduction

In most frameworks pagination can be painful. Laravel's paginator integrates with the query builder and Eloquent ORM, providing an easy‑to‑use, Bootstrap‑compatible HTML result set pagination.

Basic Usage

Query Builder Pagination

There are several ways to paginate data. The simplest is to call the paginate method on a query builder or Eloquent query. paginate automatically sets the limit and offset based on the current page detected from the page query string.

In the following example the only argument passed to paginate is the number of items per page (15):

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
    /**
     * Display all users.
     *
     * @return Response
     */
    public function index()
    {
        $users = DB::table('users')->paginate(15);

        return view('user.index', ['users' => $users]);
    }
}
Note: Currently Laravel cannot efficiently paginate queries that contain a groupBy clause. If you need groupBy , query the database manually and create a paginator yourself.

Simple Pagination

If you only need simple "previous" and "next" links, use the simplePaginate method for a more efficient query on large data sets:

$users = DB::table('users')->simplePaginate(15);

Eloquent Model Pagination

You can also paginate an Eloquent query. The example below paginates the User model with 15 items per page, using the same syntax as the query builder:

$users = App\User::paginate(15);

You may add additional constraints before calling paginate , for example:

$users = User::where('votes', '>', 100)->paginate(15);

You can also use simplePaginate on an Eloquent model:

$users = User::where('votes', '>', 100)->simplePaginate(15);

Manual Pagination

If you want to create a paginator instance manually and obtain an array result, you can use Illuminate\Pagination\Paginator or Illuminate\Pagination\LengthAwarePaginator .

The Paginator class does not need to know the total number of items, so it cannot generate a last‑page index. The LengthAwarePaginator receives almost the same arguments as Paginator but must calculate the total number of items.

In short, Paginator corresponds to the simplePaginate method, while LengthAwarePaginator corresponds to the paginate method.

Note: When creating a paginator manually you must slice the result array yourself; see PHP's array_slice function.

Displaying Pagination Results

Calling paginate returns an Illuminate\Pagination\LengthAwarePaginator instance; calling simplePaginate returns an Illuminate\Pagination\Paginator instance. These objects provide methods for rendering links that are compatible with Bootstrap. In a Blade view you can display the items and render the pagination links as follows:

<div class="container"
    @foreach ($users as $user)
        {{ $user->name }}
    @endforeach
</div>

{{ $users->links() }}

The links method generates HTML with the correct page query string and works with Bootstrap.

Customizing the Paginator URI

The withPath method lets you set a custom base URI for generated links. For example, to produce links like http://example.com/custom/url?page=N :

Route::get('users', function () {
    $users = App\User::paginate(15);
    $users->withPath('custom/url');
    // ...
});

Appending Parameters to Pagination Links

Use appends to add query parameters to each pagination link, e.g., adding sort=votes :

{{ $users->appends(['sort' => 'votes'])->links() }}

Use fragment to add an anchor to the links, e.g., #foo :

{{ $users->fragment('foo')->links() }}

Converting Results to JSON

The paginator implements Illuminate\Contracts\Support\Jsonable and provides a toJson method, making it easy to return JSON from a route or controller:

Route::get('users', function () {
    return App\User::paginate();
});

The JSON includes meta information such as total , current_page , last_page , and a data array with the result set. Example:

{
   "total": 50,
   "per_page": 15,
   "current_page": 1,
   "last_page": 4,
   "first_page_url": "http://laravel.app?page=1",
   "last_page_url": "http://laravel.app?page=4",
   "next_page_url": "http://laravel.app?page=2",
   "prev_page_url": null,
   "path": "http://laravel.app",
   "from": 1,
   "to": 15,
   "data": [
        { /* result */ },
        { /* result */ }
   ]
}

Custom Pagination Views

By default the pagination view is compatible with Bootstrap. If you are not using Bootstrap you can publish the view files and edit them. Run:

php artisan vendor:publish --tag=laravel-pagination

The command places the view files in resources/views/vendor/pagination . The bootstrap-4.blade.php file is the default view and can be edited to change the generated HTML.

Paginator Instance Methods

Each paginator instance provides additional methods such as:

$results->count()

$results->currentPage()

$results->firstItem()

$results->hasMorePages()

$results->lastItem()

$results->lastPage() (not available with simplePaginate )

$results->nextPageUrl()

$results->perPage()

$results->previousPageUrl()

$results->total() (not available with simplePaginate )

$results->url($page)

Backend DevelopmentpaginationphpBootstrapLaravelEloquentquery-builder
Laravel Tech Community
Written by

Laravel Tech Community

Specializing in Laravel development, we continuously publish fresh content and grow alongside the elegant, stable Laravel framework.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.