In this article, you'll learn how to add pagination to your Inertia apps with a simple, custom, re-usable pagination component.
The first step is to send paginated data down to your page component. If you're not using API resources to structure this data, here's what it looks like.
class UserIndexController extends Controller
{
public function __invoke()
{
return inertia()->render('User/Index', [
'users' => UserResource::collection(
User::latest()->paginate(10)
),
]);
}
}
The UserResource
just contains a bunch of information about the user. Since we're calling the paginate
method on our query builder, we'll get some nicely structured data (wrapped in a data
property) and some meta
, which contains our pagination data.
Here's what that data looks like. I've slimmed it down a little so it's easier to grasp.
{
"data": [],
"meta": {
"current_page": 2,
"from": 11,
"last_page": 101,
"links": [
{
"url": "http://inertia-pagination.test/users?page=1",
"label": "Previous",
"active": false
},
{
"url": "http://inertia-pagination.test/users?page=1",
"label": "1",
"active": false
},
{
"url": "http://inertia-pagination.test/users?page=3",
"label": "Next",
"active": false
}
],
"path": "http://inertia-pagination.test/users",
"per_page": 10,
"to": 20,
"total": 1001
}
}
Well, technically, it's a Vue component... but it will be Inertia-specific since we'll need to rely on Inertia's router to fetch the chosen page.
Here's an example of iterating over the data from our controller.
<script setup>
defineProps({
users: Object
})
</script>
<template>
<div v-if="users.data.length">
<div v-for="user in users.data" :key="user.id">
#{{ user.id }}: {{ user.name }}
</div>
<Pagination :pagination="users.meta" />
</div>
</template>
And here's what that Pagination
component looks like.
<script setup>
import { Link } from '@inertiajs/vue3'
defineProps({
pagination: Object
})
</script>
<template>
<nav class="relative flex justify-center">
<template v-for="link in pagination.links" :key="link.label">
<Link
preserve-scroll
:href="link.url ?? ''"
v-html="link.label"
class="flex items-center justify-center px-3 py-2 text-sm rounded-lg text-gray-600"
:class="{ 'bg-gray-200': link.active, '!text-gray-300': !link.url }"
/>
</template>
</nav>
</template>
Due to the structure of the meta
we get back from Laravel's pagination, it's straightforward to iterate over and show every pagination element needed.
Here's the result of the pagination component in action.
If you don't need the complexity of numbered pagination, here's how to implement simple pagination with Inertia.
First, switch your paginate
method to simplePaginate
.
public function __invoke()
{
return inertia()->render('User/Index', [
'users' => UserResource::collection(
User::latest()->simplePaginate(10)
),
]);
}
This provides the following structure to our Vue components.
{
"data": [],
"links": {
"first": "http://inertia-pagination.test/users?page=1",
"last": null,
"prev": null,
"next": "http://inertia-pagination.test/users?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"path": "http://inertia-pagination.test/users",
"per_page": 10,
"to": 10
}
}
Create a new SimplePagination
component and pass down the link
from our pagination response to this component.
<SimplePagination :pagination="users.links" />
And here's what the SimplePagination
component looks like. Since we're just showing two links, there's no need to iterate over anything.
<script setup>
import { Link } from '@inertiajs/vue3'
defineProps({
pagination: Object,
})
</script>
<template>
<nav class="relative flex items-center justify-between">
<Link
preserve-scroll
:href="pagination.prev ?? ''"
class="flex items-center justify-center px-3 py-2 text-sm rounded-lg text-gray-600"
:class="{ 'bg-gray-200': pagination.prev, '!text-gray-300': !pagination.prev }"
>
Previous
</Link>
<Link
preserve-scroll
:href="pagination.next ?? ''"
class="flex items-center justify-center px-3 py-2 text-sm rounded-lg text-gray-600"
:class="{ 'bg-gray-200': pagination.next, '!text-gray-300': !pagination.next }"
>
Next
</Link>
</nav>
</template>
Now that we're done, feel free to grab the code above and customise it for your needs. The Laravel paginator returns useful data, so you should have plenty to play with!
Happy paginating.