Usefull Laravel Artisan Commands with Examples
Read More
Have you ever tried loading thousands of records simultaneously, only to find your app slowing down to crawl? Pagination is the solution that breaks down enormous datasets into manageable chunks, keeping your app performant and user-friendly. We’ll explore why pagination is essential and dive deep into the pagination options Laravel offers, from traditional offset-based pagination to efficient cursor-based pagination for real-time data.
Pagination isn’t just a feature; it’s necessary for modern applications that handle substantial data volumes. Here’s why:
Laravel provides three types of pagination:
// Controller
use App\Models\Post;
public function index()
{
$posts = Post::paginate(10); // 10 items per page
return view('posts.index', ['posts' => $posts]);
}
<!-- Blade View -->
@foreach ($posts as $post)
<h2>{{ $post->title }}</h2>
<p>{{ $post->excerpt }}</p>
@endforeach
{{ $posts->links() }} <!-- Renders pagination links -->
The
paginate
method counts the total number of records matched by the query before retrieving the records from the database. This is done so that the paginator knows how many pages of records there are in total. However, if you do not plan to show the total number of pages in your application's UI, then the record count query is unnecessary.
Therefore, if you only need to display simple "Next" and "Previous" links in your application's UI, you may use the simplePaginate
method to perform a single, efficient query:
$posts = Post::simplePaginate(10); // No total count
Best for large datasets where counting all records is slow.
While paginate
and simplePaginate
create queries using the SQL "offset" clause, cursor pagination works by constructing "where" clauses that compare the values of the ordered columns contained in the query, providing the most efficient database performance available amongst all of Laravel's pagination methods. This method of pagination is particularly well-suited for large data-sets and "infinite" scrolling user interfaces.
Unlike offset based pagination, which includes a page number in the query string of the URLs generated by the paginator, cursor based pagination places a "cursor" string in the query string. The cursor is an encoded string containing the location that the next paginated query should start paginating and the direction that it should paginate:
http://localhost/users?cursor=eyJpZCI6MTUsIl9wb2ludHNUb05leHRJdGVtcyI6dHJ1ZX0
You may create a cursor based paginator instance via the cursorPaginate
method offered by the query builder. This method returns an instance of Illuminate\Pagination\CursorPaginator
:
$posts = Post::orderBy('created_at')->cursorPaginate(15);
Ideal for real-time feeds and infinite scroll implementations.
By default, the views rendered to display the pagination links are compatible with the Tailwind CSS framework. However, if you are not using Tailwind, you are free to define your own views to render these links. When calling the links
method on a paginator instance, you may pass the view name as the first argument to the method:
{{ $paginator->links('view.name') }}
<!-- Passing additional data to the view... -->
{{ $paginator->links('view.name', ['foo' => 'bar']) }}
However, the easiest way to customize the pagination views is by exporting them to your resources/views/vendor
directory using the vendor:publish
command:
php artisan vendor:publish --tag=laravel-pagination
{{ $posts->links('custom.pagination') }} <!-- Uses custom view -->
// Allow users to select items per page
$perPage = request('per_page', 10);
$posts = Post::paginate($perPage);
Each paginator instance provides additional pagination information via the following methods:
Method |
Description |
$paginator->count() |
Get the number of items for the current page. |
$paginator->currentPage() |
Get the current page number. |
$paginator->firstItem() |
Get the result number of the first item in the results. |
$paginator->getOptions() |
Get the paginator options. |
$paginator->getUrlRange($start, $end) |
Create a range of pagination URLs. |
$paginator->hasPages() |
Determine if there are enough items to split into multiple pages. |
$paginator->hasMorePages() |
Determine if there are more items in the data store. |
$paginator->items() |
Get the items for the current page. |
$paginator->lastItem() |
Get the result number of the last item in the results. |
$paginator->lastPage() |
Get the page number of the last available page. (Not available when using simplePaginate). |
$paginator->nextPageUrl() |
Get the URL for the next page. |
$paginator->onFirstPage() |
Determine if the paginator is on the first page. |
$paginator->perPage() |
The number of items to be shown per page. |
$paginator->previousPageUrl() |
Get the URL for the previous page. |
$paginator->total() |
Determine the total number of matching items in the data store. (Not available when using simplePaginate). |
$paginator->url($page) |
Get the URL for a given page number. |
$paginator->getPageName() |
Get the query string variable used to store the page. |
$paginator->setPageName($name) |
Set the query string variable used to store the page. |
$paginator->through($callback) |
Transform each item using a callback. |
Cursor Paginator Instance Methods
Each cursor paginator instance provides additional pagination information via the following methods:
Method |
Description |
$paginator->count() |
Get the number of items for the current page. |
$paginator->cursor() |
Get the current cursor instance. |
$paginator->getOptions() |
Get the paginator options. |
$paginator->hasPages() |
Determine if there are enough items to split into multiple pages. |
$paginator->hasMorePages() |
Determine if there are more items in the data store. |
$paginator->getCursorName() |
Get the query string variable used to store the cursor. |
$paginator->items() |
Get the items for the current page. |
$paginator->nextCursor() |
Get the cursor instance for the next set of items. |
$paginator->nextPageUrl() |
Get the URL for the next page. |
$paginator->onFirstPage() |
Determine if the paginator is on the first page. |
$paginator->onLastPage() |
Determine if the paginator is on the last page. |
$paginator->perPage() |
The number of items to be shown per page. |
$paginator->previousCursor() |
Get the cursor instance for the previous set of items. |
$paginator->previousPageUrl() |
Get the URL for the previous page. |
$paginator->setCursorName() |
Set the query string variable used to store the cursor. |
$paginator->url($cursor) |
Get the URL for a given cursor instance. |
Common Pagination Issues & Fixes
❌ Problem: Pagination links not working
✅ Fix: Ensure $items->links() is called in Blade.
❌ Problem: Duplicate content in Google
✅ Fix: Use rel="canonical" and rel="prev/next".
❌ Problem: Slow pagination on large tables
✅ Fix: Use simplePaginate() or cursorPaginate().
Laravel 11’s pagination system is powerful and flexible, allowing for efficient data handling while maintaining SEO best practices. By following this guide, you can implement:
Recent posts form our Blog
0 Comments
Like 0