Laravel pagination with custom views

Carlos Mendez Jan 2026
3 tabs
<?php

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    public function index(Request $request)
    {
        // Standard pagination
        $posts = Post::query()
            ->with('author')
            ->when($request->search, fn ($q, $search) =>
                $q->where('title', 'like', "%{$search}%")
            )
            ->latest()
            ->paginate(20)
            ->withQueryString(); // Preserve search params

        return view('posts.index', compact('posts'));
    }

    public function infinite(Request $request)
    {
        // Cursor pagination for infinite scroll
        $posts = Post::query()
            ->latest('id')
            ->cursorPaginate(20);

        return response()->json($posts);
    }

    public function simple()
    {
        // Simple pagination (next/prev only, no page numbers)
        $posts = Post::latest()->simplePaginate(20);

        return view('posts.simple', compact('posts'));
    }

    public function api(Request $request)
    {
        // API pagination with custom meta
        $posts = Post::paginate(20);

        return response()->json([
            'data' => $posts->items(),
            'meta' => [
                'current_page' => $posts->currentPage(),
                'last_page' => $posts->lastPage(),
                'per_page' => $posts->perPage(),
                'total' => $posts->total(),
            ],
            'links' => [
                'first' => $posts->url(1),
                'last' => $posts->url($posts->lastPage()),
                'prev' => $posts->previousPageUrl(),
                'next' => $posts->nextPageUrl(),
            ],
        ]);
    }
}
3 files · php, blade Explain with highlit

Pagination divides large datasets into pages, improving performance and UX. Eloquent's paginate() method returns a paginator with data and metadata. The links() method renders pagination UI. I customize per-page counts with paginate(50). Simple pagination uses simplePaginate() for next/prev only. Cursor pagination with cursorPaginate() handles infinite scrolling efficiently. Custom pagination views override default Blade templates. API pagination returns JSON with meta and links. The onEachSide() method controls visible page numbers. Pagination preserves query strings via withQueryString(). For complex queries, paginateResults() calculates totals manually. This handles millions of records efficiently.