HomeAbout UsWhy Choose UsGet in Touch

How to integrate Bootstrap pagination in Laravel 12

Streamlining Data Presentation with Laravel and Bootstrap Pagination

Pagination is essential for managing large datasets in web applications, enhancing user experience by breaking content into manageable pages. Laravel 12 offers robust pagination tools, and when paired with Bootstrap 5, you can create responsive, visually appealing pagination controls with minimal effort. This guide provides a step-by-step walkthrough for integrating Bootstrap pagination in Laravel 12, complete with code examples.

Why Use Bootstrap Pagination in Laravel?

  • Enhanced User Experience: Pagination divides large datasets into smaller, navigable chunks, improving readability.
  • Improved Performance: Loading only a subset of data reduces server load and speeds up page rendering.
  • Responsive Design: Bootstrap 5’s classes ensure pagination controls adapt to various screen sizes.
  • Easy Styling: Predefined Bootstrap classes simplify styling pagination links.
  • Accessibility: Bootstrap 5 includes ARIA attributes for accessible navigation, such as aria-label="Page navigation".

Prerequisites

Before starting, ensure you have:

  • A Laravel 12 project set up and running.
  • Bootstrap 5 integrated via CDN or npm.
  • A configured database with data for pagination.

To include Bootstrap 5 CSS, add this to your layout file (e.g., resources/views/layouts/app.blade.php):

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">

Alternatively, install via npm:

npm install bootstrap

Then import in resources/js/app.js:

import 'bootstrap/dist/css/bootstrap.min.css';

Compile with: npm run build.

Step 1: Set Up the Database and Model

Create a posts table and corresponding Eloquent model to store sample data.

Create the Migration

Generate a migration file:

php artisan make:migration create_posts_table

Edit the migration file (e.g., database/migrations/xxxx_xx_xx_create_posts_table.php):

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('posts');
}
};

Run the migration:

php artisan migrate

Create the Model and Factory

Generate the Post model with a factory:

php artisan make:model Post -f

The model (app/Models/Post.php) is:

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
}

Define the factory (database/factories/PostFactory.php):

<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
class PostFactory extends Factory
{
public function definition(): array
{
return [
'title' => $this->faker->sentence,
'content' => $this->faker->paragraph,
];
}
}

Seed the Database

Create a seeder:

php artisan make:seeder PostsTableSeeder

Edit the seeder (database/seeders/PostsTableSeeder.php):

<?php
namespace Database\Seeders;
use App\Models\Post;
use Illuminate\Database\Seeder;
class PostsTableSeeder extends Seeder
{
public function run(): void
{
Post::factory()->count(50)->create();
}
}

Update database/seeders/DatabaseSeeder.php:

<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run(): void
{
$this->call(PostsTableSeeder::class);
}
}

Run the seeder:

php artisan db:seed

Step 2: Fetch Paginated Data in the Controller

Use the paginate() method to retrieve paginated posts. Create or edit a controller:

php artisan make:controller PostController

Edit app/Http/Controllers/PostController.php:

<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function index()
{
$posts = Post::paginate(10); // 10 posts per page
return view('posts.index', compact('posts'));
}
}

Define a route in routes/web.php:

<?php
use App\Http\Controllers\PostController;
use Illuminate\Support\Facades\Route;
Route::get('/posts', [PostController::class, 'index'])->name('posts.index');

Step 3: Display Paginated Data in the View

Create a Blade view (resources/views/posts/index.blade.php) to display posts and pagination links:

<div class="container">
<h1>Posts</h1>
<ul class="list-group">
@foreach ($posts as $post)
<li class="list-group-item">
<h5>{{ $post->title }}</h5>
<p>{{ $post->content }}</p>
</li>
@endforeach
</ul>
<nav aria-label="Page navigation" class="mt-3">
{!! $posts->links('pagination::bootstrap-5') !!}
</nav>
</div>

Note: Ensure Bootstrap 5 CSS is included in your layout file. The pagination::bootstrap-5 view provides Bootstrap 5-styled links with ARIA attributes.

Alternatively, set Bootstrap 5 globally in app/Providers/AppServiceProvider.php:

<?php
namespace App\Providers;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot(): void
{
Paginator::useBootstrapFive();
}
}

Then use {!! $posts->links() !!} without specifying the view.

Step 4: Handle Query Parameters

Preserve search parameters across pagination links using appends(). Update the controller:

<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function index(Request $request)
{
$search = $request->input('search');
$posts = Post::when($search, function ($query, $search) {
return $query->where('title', 'like', '%' . $search . '%');
})->paginate(10)->appends(['search' => $search]);
return view('posts.index', compact('posts', 'search'));
}
}

Add a search form to the view (resources/views/posts/index.blade.php):

<div class="container">
<h1>Posts</h1>
<form method="GET" action="{{ route('posts.index') }}" class="mb-3">
<div class="input-group">
<input type="text" name="search" value="{{ $search ?? '' }}" class="form-control" placeholder="Search posts...">
<button type="submit" class="btn btn-primary">Search</button>
</div>
</form>
@if($search)
<p>Search results for: {{ $search }}</p>
@endif
<ul class="list-group">
@foreach ($posts as $post)
<li class="list-group-item">
<h5>{{ $post->title }}</h5>
<p>{{ $post->content }}</p>
</li>
@endforeach
</ul>
<nav aria-label="Page navigation" class="mt-3">
{!! $posts->links('pagination::bootstrap-5') !!}
</nav>
</div>

Step 5: Customize Pagination Views (Optional)

Publish pagination views for customization:

php artisan vendor:publish --tag=laravel-pagination

Edit resources/views/vendor/pagination/bootstrap-5.blade.php to modify the HTML or CSS classes, ensuring ARIA attributes are preserved for accessibility.

Advanced Tips

Custom Pagination URLs

Use withPath() to set a custom URL:

$posts = Post::paginate(10)->withPath('/custom/posts');

Ensure the route exists in routes/web.php.

Simple Pagination

For lightweight pagination, use simplePaginate():

$posts = Post::simplePaginate(10);

Render with: {!! $posts->links('pagination::simple-bootstrap-5') !!}.

Performance Optimization

Add indexes to columns used in queries (e.g., title):

CREATE INDEX idx_posts_title ON posts (title);

Use eager loading for relationships:

$posts = Post::with('author')->paginate(10);

Troubleshooting

  • Links Not Displaying: Ensure >10 records exist, $posts is passed to the view, and links() is called.
  • Links Not Working: Verify routes and query parameters with appends().
  • Styling Issues: Confirm Bootstrap 5 CSS is included and Vite is compiled (npm run build).

Conclusion

Integrating Bootstrap 5 pagination in Laravel 12 is straightforward, enhancing user experience and performance. Use pagination::bootstrap-5 or Paginator::useBootstrapFive() for styling, ensure Bootstrap CSS is included, and maintain accessibility with ARIA attributes. This guide equips you to build efficient, user-friendly paginated interfaces.

Ready to Transform Your Ideas into Reality?

Let's discuss how our expert development services can help bring your project to life.

RELATED

You Might Also Like

Explore more tutorials on similar topics.

Codimate Solutions

Codimate Solutions

Online | Typically responds in minutes

Hi there! 👋

Just now

Get 30% discount on your first project with us!

Just now
Wait! Grab This Limited Offer

Get 30% Off Your First Project!

We'd love to help launch or boost your digital presence. Book a free strategy call now and claim your discount.

Limited time only. No commitment required.