Pagination di Laravel
Bagi data besar jadi halaman: paginate, simplePaginate, cursor, dan kustomisasi link Blade.
paginate(): yang paling sering dipakai
// app/Http/Controllers/PostController.php
public function index()
{
$posts = Post::latest()->paginate(15);
return view('posts.index', compact('posts'));
}{{-- resources/views/posts/index.blade.php --}}
@foreach ($posts as $post)
<article>{{ $post->judul }}</article>
@endforeach
{{ $posts->links() }}links() merender navigasi halaman otomatis dengan styling Tailwind bawaan. Query string ?page=2 ditangani otomatis. Variabel $posts tetap bisa di-loop seperti collection biasa.
simplePaginate vs paginate
paginate() menjalankan query COUNT tambahan untuk tahu total halaman. Untuk tabel raksasa, COUNT bisa lambat. Solusinya simplePaginate() yang hanya menampilkan tombol Previous/Next tanpa nomor halaman:
$posts = Post::latest()->simplePaginate(15);cursorPaginate: untuk data yang terus bertambah
Pagination berbasis offset (?page=50) bermasalah kalau data disisipkan saat user menjelajah: baris bisa muncul ganda atau terlewat. cursorPaginate() memakai posisi kursor, stabil untuk feed dan timeline:
$posts = Post::latest()->cursorPaginate(15);Syaratnya: query harus punya orderBy yang unik (biasanya primary key atau created_at).
Mempertahankan filter di link halaman
Kalau halaman punya filter pencarian, pastikan query string ikut terbawa saat pindah halaman:
$posts = Post::when($request->q, fn ($q) => $q->where('judul', 'like', "%{$request->q}%"))
->paginate(15)
->withQueryString();Atau tambahkan manual: ->appends(['q' => $request->q]).
Catatan teknis: Jangan paginasi collection yang sudah di-load penuh (
Post::all()->paginate()tidak ada, dan memotong manual denganforPagetetap me-load semua data ke memory). Selalu paginasi di level query builder supaya LIMIT diterapkan di database.