kgilden/pager-bundle
A lightweight Symfony bundle that adds simple, reusable pagination support. It provides pager services and Twig helpers for splitting large result sets into pages with configurable page sizes and templates. Easy to integrate, though documentation and community support are limited.
composer require kgilden/pager-bundle:^2.0.1. That single release adds Symfony v3.0 support and nothing else — treat v2.0.0 → v2.0.1 as a no-op bump unless you are specifically targeting Symfony 3.extra.laravel block and no service provider, so Composer installs the code but Laravel will not auto-wire anything into the container. Plan for a small manual integration step rather than expecting php artisan vendor:publish to do anything.DependencyInjection/ extension and its pager service class — that is where the framework-agnostic logic lives. The Twig extension and templates are the Symfony-facing shell and will not be usable from Blade.(currentPage, perPage, totalCount), and render the output yourself:$pager = new Pager($page = max(1, (int) request('page', 1)), 25, $query->count());
$items = $query->forPage($pager->getCurrentPage(), 25)->get();
return view('items.index', compact('items', 'pager'));
Standalone pager in a Laravel controller. The bundle's real value is its pager object, so the cleanest day-to-day pattern is to instantiate it directly and let Laravel own routing and rendering. Fetch the total count, build the pager, then slice the query with forPage(). Avoid pulling in the Symfony kernel machinery just to page a list.
Bind it as a scoped service. Register a factory in a dedicated AppServiceProvider (or a small PagerServiceProvider) so the pager is resolved from config instead of constructed ad hoc. Keep per_page in config/pager.php so it is overridable per environment, and inject it where needed:
$this->app->bind(Pager::class, fn () => new Pager(
max(1, (int) request('page', 1)),
config('pager.per_page', 25),
$total
));
Port the Twig widget to a Blade partial. The bundle ships a Twig template for the page strip. Recreate it once as resources/views/partials/pager.blade.php and build URLs with request()->fullUrlWithQuery(['page' => $n]) so existing filters survive pagination. This is a one-time cost and is the single biggest piece of Symfony-to-Laravel translation you will do.
Adapter over Laravel's paginator when mixing paginators. If the rest of the app already uses LengthAwarePaginator, wrap it and only use the bundle's pager for the page-number window — or skip the bundle entirely and use LengthAwarePaginator::links(). Do not render both widgets in one view; they will fight over ?page=.
Full-stack Symfony branch. If the same codebase (or a sibling service) is on Symfony, register the bundle in AppKernel/bundles.php, configure it via container parameters, and use the Twig function as documented. v2.0.1 is exactly the version that makes that path work on Symfony 3.
Testing pagination edge cases. Because the pager is small and pure, unit-test the boundaries: page 1, last page, page beyond last, page 0/negative, and total = 0. Assert getCurrentPage(), getOffset(), and getLimit() rather than the rendered HTML.
Class not found from any tutorial that assumes Symfony's kernel, and from code relying on the bundle's DI aliases.{{ pager(...) }} or a @KgilPager namespace will not work. Only the PHP pager object transfers cleanly — port the template, do not try to load it.^2.0.1 constraint is safe either way.count($items) gives you the size of the current page, not the dataset. Use $query->count() (or the array length) for the third constructor argument.request()->query() into the URL builder, and clamp out-of-range pages (max(1, min($page, $lastPage))) before passing them to the pager.?page= produce contradictory links. Pick one owner of the parameter per route.vendor/.currentPage, perPage, total) at the point of construction. Nearly every "pager is off" report traces to one of those three values being wrong before the pager is involved.How can I help you explore Laravel packages today?