InertiaJS infinite scrolling example

I just published a new video on how to do infinite scrolling in an InertiaJS and Laravel application – using a twitter-like feed as an example.

The gist of it is:

  1. Setup a listener for the scroll event
  2. Inside the listener calculate the remaining pixels until the bottom of the page so you can make additional requests to load new items before the user hits the bottom of the page.
  3. Make sure you use lodash’s debounce method to avoid making the same request multiple times.
  4. Use axios or fetch or anything else to make a regular xhr request to the server.
  5. Make sure the server endpoint knows when to return an inertia response and when to return a regular json response.
  6. Put your items in a local state property so you can add the new ones when you make the additional requests. The reason for this is because VueJs props shouldn’t be mutated.

Backend snippet:

// UserTweetsController
public function index(User $user, Request $request)
{
    $tweets = $user->tweets()->with('user')->paginate();

    if ($request->wantsJson()) {
        return $tweets;
    }

    return Inertia::render('UserTweets', [
        'user' => $user,
        'tweets' => $tweets
    ]);
}

Scroll event listener snippet:

// UserTweets.vue
import AppLayout from './../Layouts/AppLayout'
import {debounce} from "lodash/function";

export default {
  props: {
    user: Object,
    tweets: Object
  },
  data() {
    return {
      userTweets: this.tweets
    }
  },
  components: {
    AppLayout,
  },
  mounted() {
    window.addEventListener('scroll', debounce((e) => {
      let pixelsFromBottom = document.documentElement.offsetHeight - document.documentElement.scrollTop - window.innerHeight;

      if (pixelsFromBottom < 200) {
        axios.get(this.userTweets.next_page_url).then(response => {
          this.userTweets = {
            ...response.data,
            data: [...this.userTweets.data, ...response.data.data]
          }
        });
      }
    }, 100));
  }
}

Watch the full video here.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.