Introduction
Pagination is a key feature in web applications, allowing data to be presented in a user-friendly manner without overwhelming the user with large datasets. Laravel makes pagination straightforward with built-in support. However, when building applications, there are scenarios where you need to preserve query strings across paginated results, such as filter parameters or search criteria. In this blog, we’ll cover how to add query strings to paginated URLs in Laravel 11.
Why Use Query Strings in Pagination?
When users interact with filtered or sorted data, preserving those filters while navigating through paginated results enhances the user experience. For instance, if a user searches for a keyword or applies filters, they expect to see the results maintained even when they move from page to page. This is where adding query strings to pagination URLs becomes essential.
Setting Up Pagination in Laravel 11
Before diving into query strings, let’s quickly set up pagination in Laravel 11.
Assume we have a Post
model and want to paginate a list of blog posts:
use App\Models\Post;
class PostController extends Controller
{
public function index(Request $request)
{
$posts = Post::paginate(10); // Paginate 10 posts per page
return view('posts.index', compact('posts'));
}
}
In your Blade view (resources/views/posts/index.blade.php
), you can display the pagination links like this:
@foreach ($posts as $post)
<h2>{{ $post->title }}</h2>
<p>{{ $post->body }}</p>
@endforeach
{{ $posts->links() }} <!-- Display pagination links -->
Adding Query Strings to Pagination
Now, let’s say you want to preserve a search query or filters across paginated results.
Step 1: Capturing Query Parameters
Modify your controller to capture query parameters:
use App\Models\Post;
class PostController extends Controller
{
public function index(Request $request)
{
$query = Post::query();
// Check for search input
if ($request->has('search')) {
$query->where('title', 'like', '%' . $request->input('search') . '%');
}
$posts = $query->paginate(10)->appends($request->except('page'));
return view('posts.index', compact('posts'));
}
}
Explanation:
- The
appends()
method adds the current query string parameters to pagination links. -
except('page')
ensures that thepage
query parameter is automatically handled by the paginator.
Step 2: Updating the Blade View
In your view, add a search form:
<form action="{{ route('posts.index') }}" method="GET">
<input type="text" name="search" placeholder="Search..." value="{{ request('search') }}">
<button type="submit">Search</button>
</form>
Now, when you search for a post, the search query will be preserved while navigating through paginated results.
For example:
-
Page 1 URL:
https://yourapp.com/posts?search=laravel
-
Page 2 URL:
https://yourapp.com/posts?search=laravel&page=2
Adding Multiple Query Parameters
Let’s extend this further by adding multiple filters, such as category and date range:
Step 1: Controller Logic
use App\Models\Post;
class PostController extends Controller
{
public function index(Request $request)
{
$query = Post::query();
if ($request->has('search')) {
$query->where('title', 'like', '%' . $request->input('search') . '%');
}
if ($request->has('category')) {
$query->where('category_id', $request->input('category'));
}
if ($request->has('date_from') && $request->has('date_to')) {
$query->whereBetween('created_at', [$request->input('date_from'), $request->input('date_to')]);
}
$posts = $query->paginate(10)->appends($request->except('page'));
return view('posts.index', compact('posts'));
}
}
Step 2: Updating the Blade View
<form action="{{ route('posts.index') }}" method="GET">
<input type="text" name="search" placeholder="Search..." value="{{ request('search') }}">
<select name="category">
<option value="">Select Category</option>
<!-- Loop through categories -->
@foreach ($categories as $category)
<option value="{{ $category->id }}" {{ request('category') == $category->id ? 'selected' : '' }}>
{{ $category->name }}
</option>
@endforeach
</select>
<input type="date" name="date_from" value="{{ request('date_from') }}">
<input type="date" name="date_to" value="{{ request('date_to') }}">
<button type="submit">Filter</button>
</form>
{{ $posts->links() }} <!-- Pagination links -->
In this scenario, all selected filters (search, category, date range) will be maintained as you navigate through paginated results.
Troubleshooting Common Issues
-
Query String Not Appearing in Pagination Links:
- Ensure that you’re using the
appends()
method in the controller.
- Ensure that you’re using the
-
Pagination Links Not Reflecting Filters:
- Double-check that you’re including the query string parameters in your Blade view’s form.
-
Complex Filtering and Query Parameters:
- For more complex scenarios, consider using a custom pagination solution or packages like Spatie's Query Builder to manage complex filtering and query strings.
Conclusion
Adding query strings to pagination in Laravel 11 significantly enhances the user experience by preserving filters and search criteria. Whether you’re dealing with simple search queries or complex multi-parameter filtering, Laravel provides an easy way to handle query strings during pagination.
This guide covered the essential steps, practical code examples, and best practices for managing query strings in Laravel pagination. If you found this guide helpful, be sure to check out more Laravel tips and tricks on the freecoderteam website.
Would you like me to generate an image for this blog post as well?