Mastering Laravel Pagination Updated on May 22, 2024 by Derrell 6 Minutes, 53 Seconds to Read Pagination is a critical feature for web applications, enhancing user experience by breaking down large data sets into manageable chunks. Laravel simplifies the implementation of pagination through its built-in paginate() method. This article will guide you through the process of setting up and customizing pagination in Laravel, ensuring a smooth and efficient user experience. Setting Up Pagination in Laravel Basic Usage of paginate() Customizing Pagination Links Advanced Pagination Features Pagination with Relationships Handling Large Datasets Customizing URL Parameters Error Handling in Pagination Testing Pagination Conclusion Setting Up Pagination in Laravel Installing Laravel Before diving into pagination, ensure you have Laravel installed. If not, you can install it using Composer: composer create-project --prefer-dist laravel/laravel myApp Check out our How to Install Laravel article for more in-depth instructions! Setting Up a Database and Creating a Model Configure your .env file with your database details: DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=your_database DB_USERNAME=your_username DB_PASSWORD=your_password Our How to Configure the Laravel .env for a Database article explains the process more in-depth. Run the migration to create a table: php artisan make:migration create_posts_table --create=posts Edit the migration file to include the necessary columns: Schema::create('posts', function (Blueprint $table) { $table->id(); $table->string('title'); $table->text('body'); $table->timestamps(); }); Run the migration: php artisan migrate Create a model for the posts table: php artisan make:model Post Basic Usage of paginate() Explanation of the paginate() Method The paginate() method is part of Laravel’s Eloquent ORM. It simplifies fetching a limited set of records from the database and automatically generates links for navigating through the pages. It works seamlessly with Eloquent models and queries, making it easy to implement pagination in your application. The method accepts an integer parameter, which specifies the number of records to be displayed per page. For instance, Post::paginate(10) will fetch 10 records per page from the posts table. Example: Paginating a List of Records Let’s go through a step-by-step example of paginating a list of records. Step 1: Create a Controller First, create a controller to handle the logic. You can use the Artisan command to generate the controller: php artisan make:controller PostController Open the newly created PostController and add the following code to the index method: namespace App\Http\Controllers; use App\Models\Post; use Illuminate\Http\Request; class PostController extends Controller { public function index() { $posts = Post::paginate(10); return view('posts.index', compact('posts')); } } In this code, Post::paginate(10) fetches 10 records from the posts table. The resulting Paginator instance is passed to the view named posts.index. Step 2: Create a Route Next, define a route that maps to the index method of the PostController. Open the routes/web.php file and add the following line: use App\Http\Controllers\PostController; Route::get('/posts', [PostController::class, 'index']); This route will handle GET requests to /posts and invoke the index method of PostController. Step 3: Create a Blade Template Create a Blade template to display the paginated results. Create a new file named index.blade.php inside the resources/views/posts directory: <!DOCTYPE html> <html> <head> <title>Laravel Pagination</title> <link rel="stylesheet" href="" /> <script src="https://cdn.tailwindcss.com" ></script> </head> <body> <div class="container mt-5"> <h1>Laravel Pagination Example</h1> <table class="table table-bordered"> <thead> <tr> <th>ID</th> <th>Title</th> <th>Body</th> </tr> </thead> <tbody> @foreach($posts as $post) <tr> <td>{{ $post->id }}</td> <td>{{ $post->title }}</td> <td>{{ $post->body }}</td> </tr> @endforeach </tbody> </table> {!! $posts->links() !!} </div> </body> </html> Step 4: Displaying Paginated Results In the Blade template, we loop through the $posts collection and display each post’s ID, title, and body in a table. The {!! $posts->links() !!} directive renders the pagination links, which are automatically generated by Laravel. Example Breakdown Controller: Fetches paginated data from the database using paginate(). Route: Defines a URL that triggers the controller method. Blade Template: Displays the paginated data and renders the pagination links. Customizing Pagination Links Laravel uses the Tailwind CSS framework by default for pagination styling. If you’re using a different CSS framework or want to customize the appearance of pagination links, you can publish the pagination views and modify them. Publish the pagination views: php artisan vendor:publish --tag=laravel-pagination This command copies the pagination views to resources/views/vendor/pagination, where you can edit them as needed. Changing the Number of Items Per Page You can easily change the number of items displayed per page by passing a different value to the paginate() method: $posts = Post::paginate(20); Customizing the Pagination View Laravel allows you to customize the appearance of pagination links by using different views. You can specify the view to be used with the links() method: {!! $posts->links('vendor.pagination.bootstrap-4') !!} You can create your custom pagination view in the resources/views/vendor/pagination directory if needed. Advanced Pagination Features Using simplePaginate() The simplePaginate() method is a lightweight alternative to paginate(), providing a simple “Next” and “Previous” navigation without calculating the total number of pages. It’s useful for large datasets where performance is a concern. $posts = Post::simplePaginate(10); Adding Filters to Paginated Results You can add filters to your paginated results by modifying the query before calling the paginate() method: $posts = Post::where('category', 'Tech')->paginate(10); Pagination with Relationships Paginating Related Models Paginating related models is straightforward with Laravel. For example, to paginate comments for a post: $post = Post::find($id); $comments = $post->comments()->paginate(10); return view('posts.comments', compact('post', 'comments')); In your Blade template, display the comments and pagination links: @foreach($comments as $comment) <p>{{ $comment->body }}</p> @endforeach {!! $comments->links() !!} Handling Large Datasets Efficient Pagination Strategies for Large Datasets For very large datasets, cursorPaginate() offers a more efficient approach by using database cursors instead of offset/limit pagination. $posts = Post::cursorPaginate(10); This method reduces the overhead of counting the total number of records. Customizing URL Parameters Customizing Query String Parameters for Pagination You can customize the query string parameters used in pagination links. For example, to append custom parameters: $posts = Post::paginate(10)->appends(['sort' => 'title']); Customizing the Page Parameter You can also customize the page parameter if needed: $posts = Post::paginate(10)->withPath('custom-page'); Error Handling in Pagination Handling Empty Pages When dealing with pagination, you might encounter empty pages. Redirecting users to a valid page or displaying a custom message can enhance the user experience: public function index(Request $request) { $page = $request->input('page', 1); $posts = Post::paginate(10); if ($posts->isEmpty() && $page > 1) { return redirect()->route('posts.index', ['page' => $posts->lastPage()]); } return view('posts.index', compact('posts')); } Handling Invalid Page Numbers Handling invalid page numbers ensures users are not stuck on a non-existent page: public function index(Request $request) { $page = $request->input('page', 1); $posts = Post::paginate(10); if ($page > $posts->lastPage()) { abort(404); } return view('posts.index', compact('posts')); } Testing Pagination Testing pagination ensures your implementation works as expected. Here’s how to write tests for pagination: public function testPaginationDisplaysCorrectNumberOfItems() { $response = $this->get('/posts?page=1'); $response->assertStatus(200); $response->assertSeeText('10 items'); } public function testPaginationLinks() { $response = $this->get('/posts?page=1'); $response->assertStatus(200); $response->assertSee('<nav>'); } Conclusion In this article, we’ve explored how to use Laravel’s paginate() method to efficiently handle large datasets and enhance user experience. By understanding the basics and advanced features of pagination, you can customize and optimize it for your application’s needs. For further reading, check out Laravel’s official documentation and explore additional customization options. Implementing pagination ensures your users can navigate through data effortlessly, providing a smooth and engaging experience. Happy coding! Boost your Laravel apps with our specialized Laravel Hosting. Experience faster speeds for your Laravel applications and websites thanks to NVMe storage, server protection, dedicated resources, and optimization tools. 99.99% Uptime Free SSL Dedicated IP Address Developer Tools Laravel Hosting Share this Article Derrell Willis Manager, Developer Relations More Articles by Derrell Related Articles How to Check the Laravel Version of Your Project Laravel Blade Basics Troubleshooting 500 Error in Laravel Database Seeding in Laravel Understanding the Laravel env File How to Use Controllers in Laravel Form Validation in Laravel Understanding CSRF Protection in Laravel Creating Laravel Database Model Factories Mastering Laravel Pagination