Laravel 11 Pagination: How to Add Query Strings for Better Navigation

author

By Freecoderteam

Aug 22, 2024

35

image

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 the page 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

  1. Query String Not Appearing in Pagination Links:

    • Ensure that you’re using the appends() method in the controller.
  2. Pagination Links Not Reflecting Filters:

    • Double-check that you’re including the query string parameters in your Blade view’s form.
  3. 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?

Subscribe to Receive Future Updates

Stay informed about our latest updates, services, and special offers. Subscribe now to receive valuable insights and news directly to your inbox.

No spam guaranteed, So please don’t send any spam mail.