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:
- Setup a listener for the scroll event
- 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.
- Make sure you use lodash’s
debounce
method to avoid making the same request multiple times. - Use
axios
orfetch
or anything else to make a regularxhr
request to the server. - Make sure the server endpoint knows when to return an inertia response and when to return a regular json response.
- 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));
}
}