Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel + Inertia + Vuejs: Pagination

When I get all the records it works:

    ...

    $items = Item::all();

    return Inertia::render('Rentals/Items', ['items' => $items]
);

But when I try to paginate, it breaks down:

    ...

    $items = Item::paginate(15);

    return Inertia::render('Rentals/Items', ['items' => $items]
);

I get this error:

Uncaught (in promise) TypeError: Cannot read property 'id' of null

What am I doing wrong?

like image 787
No One Avatar asked Sep 13 '25 04:09

No One


1 Answers

Creator of Inertia.js here. 👋

So, you can totally use the Laravel paginator with Inertia, you just need to setup your page components to be compatible.

First, make sure you're only returning the items data to the client that you actually need. You can use the new pagination through method for this.

$items = Item::paginate(15)->through(function ($item) {
    return [
        'id' => $item->id,
        'name' => $item->name,
        // etc
    ];
});

return Inertia::render('Rentals/Items', ['items' => $items]);

Next, client side, you'll need a pagination component to actually display the pagination links. Here is an example component from the Ping CRM demo app, built using Tailwind CSS.

<template>
  <div v-if="links.length > 3">
    <div class="flex flex-wrap -mb-1">
      <template v-for="(link, key) in links">
        <div v-if="link.url === null" :key="key" class="mr-1 mb-1 px-4 py-3 text-sm leading-4 text-gray-400 border rounded" v-html="link.label" />
        <inertia-link v-else :key="key" class="mr-1 mb-1 px-4 py-3 text-sm leading-4 border rounded hover:bg-white focus:border-indigo-500 focus:text-indigo-500" :class="{ 'bg-white': link.active }" :href="link.url" v-html="link.label" />
      </template>
    </div>
  </div>
</template>

<script>
import {InertiaLink} from "@inertiajs/inertia-vue3";

export default {
  props: {
    links: Array,
  },
  components : {
    InertiaLink
  }
}
</script>

Finally, to display the items and the pagination links in your page component, use the items.data and items.links props. Something like this:

<template>
  <div>
    <div v-for="item in items.data" :key="item.id">
      {{ item.name }}
    </div>
    <pagination :links="items.links" />
  </div>
</template>

<script>
import Pagination from '@/Shared/Pagination'

export default {
  components: {
    Pagination,
  },
  props: {
    items: Object,
  },
}
</script>

You can find a full working example of this in the Ping CRM demo app. 👍

like image 165
Jonathan Avatar answered Sep 15 '25 20:09

Jonathan