Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Paginator Bundle Laravel Package

nadialabs/paginator-bundle

NadiaLabs PaginatorBundle provides pagination support for PHP applications, helping split large result sets into manageable pages. It offers configurable page navigation and template-friendly controls, making long lists easier to browse and navigate in web interfaces.

View on GitHub
Deep Wiki
Context7

Getting Started

First: confirm what you're actually holding. Despite the "paginator" name, nadialabs/paginator-bundle is a Symfony bundle, not a Laravel package. There is no service provider, no config publish, no Blade views, and no LengthAwarePaginator compatibility. A Laravel developer's day-to-day use of this package is therefore almost always "read it as a reference, don't composer require it". If you try to install it into a Laravel app you will either get a Composer constraint conflict on symfony/* or a bundle class that Laravel's container never boots.

Verify before you spend time. Open composer.json and check the require block. You are looking for symfony/framework-bundle, symfony/dependency-injection, and a type: "symfony-bundle" entry. If those are present, you are done evaluating for Laravel — the integration cost (bridging Symfony's kernel/config tree into a Laravel service provider) is disproportionate to a concern Laravel already solves.

If you are in a Symfony service (or evaluating to port the logic), the setup is the standard bundle dance:

composer require nadialabs/paginator-bundle
// config/bundles.php
return [
    // ...
    NadiaLabs\PaginatorBundle\NadiaLabsPaginatorBundle::class => ['all' => true],
];

Confirm the real class name from autoload.psr-4 — with 2 stars, expect the namespace guess to be wrong.

Where to look first, in this order:

  1. README.md — usually the only usage example that exists.
  2. src/DependencyInjection/ and src/Resources/config/services.* — gives you the service ID, constructor arguments, and configurable defaults (page size, page query-parameter name).
  3. src/ for the paginator class and any Twig/ extension — this is the actual public API surface.
  4. composer.json require — PHP and symfony/* constraints. A 2-star bundle is unlikely to track current Symfony LTS.

First use case (Symfony): paginate a Doctrine QueryBuilder in a controller and hand the result to Twig.

#[Route('/articles', name: 'article_index')]
public function index(Request $request, PaginatorInterface $paginator): Response
{
    $qb = $this->getDoctrine()
        ->getRepository(Article::class)
        ->createQueryBuilder('a')
        ->orderBy('a.createdAt', 'DESC');

    $pager = $paginator->paginate($qb, $request->query->getInt('page', 1));

    return $this->render('article/index.html.twig', ['pager' => $pager]);
}

Equivalent day-to-day Laravel use case — this is the code you would actually write instead:

$articles = Article::query()
    ->orderByDesc('created_at')
    ->paginate(perPage: 20)
    ->withQueryString();

return view('article.index', compact('articles'));
// or: return ArticleResource::collection($articles);

The rest of this assessment is written for a Laravel developer who has to evaluate or translate this bundle, because that is the realistic daily interaction.

Implementation Patterns

Pattern 1 — Treat it as a reference implementation, not a dependency. Extract ideas, reimplement behind Laravel-native contracts. If you like the bundle's paginate($qb, $page) call shape, wrap Laravel's paginator in a thin service so controllers read the same way:

namespace App\Pagination;

use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Builder;

class Paginator
{
    public function paginate(Builder $query, int $page = 1, int $perPage = 20): LengthAwarePaginator
    {
        return $query->paginate(perPage: $perPage, page: $page);
    }
}

This gives you the "single call, read items/count/metadata" ergonomics the bundle advertises, without the Symfony baggage.

Pattern 2 — Keep the pagination metadata envelope as your own contract. The most valuable thing the bundle demonstrates is that pagination metadata should be a first-class, reusable output. Do this with API Resources:

class ArticleCollection extends ResourceCollection
{
    public function toArray($request): array
    {
        return [
            'data' => ArticleResource::collection($this->collection),
            'meta' => [
                'current_page' => $this->currentPage(),
                'per_page'     => $this->perPage(),
                'total'        => $this->total(),
                'last_page'    => $this->lastPage(),
            ],
            'links' => [
                'next' => $this->nextPageUrl(),
                'prev' => $this->previousPageUrl(),
            ],
        ];
    }
}

You own this shape; you do not let a third-party bundle impose it.

Pattern 3 — Swap in cursor pagination where offset fails. The bundle is offset-based (page number + page size). For feeds, activity streams, or fast-changing tables, use Laravel's cursor paginator — the bundle has no equivalent:

$articles = Article::orderByDesc('id')->cursorPaginate(20);

Pattern 4 — If you must bridge across to a Symfony service, do not share the bundle. Expose paginated data over an API and let the Laravel side consume it. Sharing a Symfony bundle into a Laravel app is the anti-pattern the TPM assessment calls out; the anti-corruption layer costs more than reimplementation.

Workflow integration tips:

  • Pin per-page defaults at the application boundary (config or a form request), not inside a controller — the bundle's config-driven defaults are the pattern worth copying, not the implementation.
  • Validate the page query parameter; both this bundle and Laravel's native paginator will happily accept a nonsense page number and either 404 or silently return an empty set. Decide your behavior explicitly.
  • Always pair pagination with a stable ORDER BY including a unique tiebreaker (ORDER BY created_at DESC, id DESC). Without it, offset pagination produces duplicated/skipped rows under concurrent writes — a bug class the bundle does not solve for you.

Gotchas and Tips

  • The framework mismatch is the headline gotcha. Do not composer require this into Laravel. The -Bundle suffix, Symfony DI assumptions, and Twig coupling mean any "integration" is a fork. Confirm via composer.json before investing further.
  • Maintenance risk is the second gotcha. 2 stars, 0 dependents, no visible changelog or release cadence. You are on the hook for PHP/Symfony version bumps. If you fork, pin the commit, add a CHANGELOG, add tests, and assign an owner — otherwise the fork rots silently.
  • Offset performance hides in plain sight. Large OFFSET values and COUNT(*) over big tables are slow regardless of which paginator wraps them. The bundle does not document its count strategy — assume one count query per page. If this is your bottleneck, the fix is cursor pagination and indexes, not a library swap.
  • Deep-page UX is unaddressed. The bundle renders page links; it does not answer SEO (rel="next"/"prev"), empty states, "load more" vs numbered, or accessibility. Those are your product decisions either way — do not expect the bundle to save you that work.
  • Twig extension is the extension point — but it's Twig, not Blade. Any rendering customization has to be rewritten for your Laravel views or API links. Budget for that explicitly in the port.
  • Debugging a Symfony bundle inside Laravel is a dead end. Service IDs are not registered in Laravel's container, so you will spend time on container wiring instead of the actual bug. If it errors, stop — the diagnosis is usually "wrong framework."
  • Config quirks: the bundle's default page-size and query-param name live in the DI extension and can only be overridden through Symfony's config tree. Laravel has no equivalent hook; replicate the idea (config-driven defaults) via config/pagination.php and a form request, not by mirroring the bundle's mechanism.
  • Invalid/out-of-range pages: test page 0, negative pages, pages beyond last_page, and pages with filters applied. Both this bundle and Laravel's need a deliberate decision (clamp vs. 404 vs. empty result) — pick one and cover it with a test.
  • License is fine, maintenance is not. MIT permits forking and vendoring; it does not give you an upstream responder when a CVE lands in a transitive Symfony dependency. If adopted anywhere, put it on your dependency-review list.

Bottom line for a Laravel developer: do not add this as a dependency. Read its README and service definitions for the pagination pattern (single-call paginate, config-driven page size, metadata-first output), then implement that pattern with Laravel's native LengthAwarePaginator / CursorPaginator and your own API Resource envelope. The one-hour investment in reading it is the entire leverage you get.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle