Change pagination link count in Laravel with onEachSide

November 12th, 2024 • 3 minutes read time

Laravel's paginator allows you to control the amount of numbered links rendered for pagination. Here's how to adjust it, and how it works.

Here's an example of a UserController which passes paginated users to the view, with 50 items per page.

class UserController extends Controller
{
    public function __invoke()
    {
        return view('users', [
            'users' => User::latest()->paginate(50),
        ]);
    }
}

And here's how it's rendered in Blade:

{{ $users->links() }}

Assuming we've got 1000 users in the database, here's what our pagination looks like by default:

blog/p3avoRTmXxHpp2N1IiLq9Ktigcpz6pXuUPqe1sMR.webp

Now, let's use the onEachSide method to control the amount of amount of page numbers. This can either be done within the controller, like this:

public function __invoke()
{
    return view('users', [
        'users' => User::latest()
            ->paginate(50)
            ->onEachSide(5)
    ]);
}

Or within your Blade template, like this:

{{ $users->onEachSide(5)->links() }}

And here's the result, showing more than the default 3 per side.

blog/J6Lc0no3siMd1esyPzKRz3HNmZIlQtR9BoexWqcF.webp

You're may wondering how this logic works, since we've specified 5 on each side, but it looks like a lot more than that!

Here's how onEachSide actually fits into the rendered pagination links, assuming we're currently on page 14 with onEachSide(5):

blog/J0R4ro7B9NPW21WvKRV5U11zYcDoVMrIJZtSAUOk.webp

  • The 2 leading and trailing pages are always present (4 in total)
  • The 1 page before the ... separator is always present
  • Assuming we're showing onEachSide(5), that's 10 numbered links each side
  • We always show the current page

So in total, with onEachSide(5), that's 16 items (excluding the ellipses) always shown.

If you were to reduce it to onEachSide(1) for minimal pagination size, here's what that looks like:

blog/AjSe1DUXs4922rXn6G8jkr4iEBunvgLFD1myAPEP.webp

The logic here differs slightly and doesn't show an additional page number before the ellipses — and this is as low as you can push the link count down without breaking pagination navigation.

If you're trying to minimise the footprint of your pagination, you have a couple of options:

  1. Customise the pagination view and change the render logic.
  2. Use simplePaginate instead of paginate within your controller. This only shows next/previous links

Here's what simplePaginate looks like:

public function __invoke()
{
    return view('users', [
        'users' => User::latest()
            ->simplePaginate(50)
    ]);
}

And here's what's rendered:

blog/8TRRbDzEB2dcgPvx4NlmgwiLEEk3yBWWE2BYiyyE.webp

If you're building an API or using Inertia, you're still able to take advantage of onEachSide. Here's an example of a controller returning an API response with paginated data. All you have to do is invoke onEachSide in your controller.

public function __invoke()
{
    return response()->json([
        'users' => User::latest()
            ->paginate(50)
            ->onEachSide(5)
    ]);
}

This will render the pagination links within the links property of the response based on how many you've chosen to display each side.

Using onEachSide gives you some control over the amount of page numbers you render when using Laravel's pagination.

It's not suitable for all cases, so as already mentioned, customising the pagination view probably works best if you need to modify the pagination beyond the defaults.

If you found this article helpful, you'll love our practical screencasts.
Author
Alex Garrett-Smith
Share :

Comments

No comments, yet. Be the first!