AJAX pagination with Laravel
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Title: AJAX Pagination with Laravel: A Comprehensive Approach
Body:
AJAX pagination is an essential technique for creating seamless user experiences in web applications where content is dynamic and requires page-by-page navigation. In this blog post, we will demonstrate how to implement AJAX pagination using Laravel as the backend framework. We assume that you have a basic understanding of Laravel and jQuery.
Firstly, let's review the code provided in the initial response:
This JavaScript code listens to clicks on pagination links and sends relevant information (including the page number) to a server-side route. The problem with this is that, in order for Laravel's pagination helper to work properly, you need to pass it through the query string as "page" parameter. To do so, let's modify your code as follows:
Now the code handles both cases, either passing the "page" value from the URL or assigning a default value of 1 if it's not a number. We need to modify your route as well:
The controller's
Finally, change the HTML in your view:
Now when you click on a pagination link, your view will reload with the corresponding page of results. The next step is to avoid the full page refresh by using AJAX:
Note that we used a separate route for paginating results (
javascript
$('#posts').on('click', '.pagination a', function(e) {
e.preventDefault();
var url = $(this).attr('href'),
page = url.split('page=')[1],
data = $('#search').serializeArray();
// Adding the new 'page' variable to post data
data.push({page: page});
console.log(data);
$.post($('#search').attr('action'), data, function(data) {
$('#posts').html(data['posts']);
});
});php
$('#posts').on('click', '.pagination a', function(e) {
e.preventDefault();
var url = $(this).attr('href'),
page = url.split('page=')[1]; // Assigning just the value of 'page' from URL
if (isNaN(page)) {
page = 1; // Setting default page to 1 in case 'page' is not a number
}
data = $('#search').serializeArray();
$.post($('#search').attr('action'), data, function(data) {
$('#posts').html(data['posts']);
});
});php
@if (Request::ajax())
return Response::json(View::make('includes.posts', ['posts' => Post::search($search)->paginate()])->render()); // Paginating the results with Laravel's paginator helper
@elseif ($request->isMethod('post'))
return ['success' => true, 'message' => 'Search performed']; // If it's a POST request without AJAX, redirect to another view or show success message
@endiffind() method should be changed to include the pagination logic:
php
function find($search) {
// ... Previous code
$posts = Post::search($search)->paginate(5);
return View::make('includes.posts', ['posts' => $posts]);
}php
<div id="posts">
@foreach ($posts as $post)
<div class="list-item clearfix">
<div class="content">
<img src="{{ URL::to($post->thumbnail) }}" alt="" />
<h1>{{{ $post->title }}}</h1>
</div>
<div class="score">{{ $post->rating }}</div>
</div>
@endforeach
<div id="pagination">{{{ $posts->links() }}}</div>
</div>php
$('#posts').on('click', '.pagination a', function(e) {
e.preventDefault();
var url = $(this).attr('href'),
page = url.split('page=')[1];
if (isNaN(page)) {
// Handle invalid 'page' values: show default value of 1 or redirect to another view
} else {
$.post($('#search').attr('action'), $('#search').serializeArray(), function(data) {
$('#posts').html(data['posts']);
// After updating the posts, reload the pagination links using AJAX as well. This will keep the URL consistent and provide a seamless browsing experience:
$.get('{{ route('paginate', ['page' => page]) }}', function(response) {
$('#pagination').html(response);
});
});
}
});Route::get('paginate', function($page) { return Post::search($search)->paginate($page); })) instead of mixing it with other search-related routes. This keeps things clean and organized.
With this implementation, you will have a smooth AJAX pagination experience on your Laravel application without losing any functionality or performance.