Infinite Scroll in Nuxt.js

Sabbir Ahmed
4 min readSep 26, 2019

Because of better UX, you can see Infinite Scroll everywhere. Depending on the context it’s a wonderful solutions for adding new content to the page.

There are basically two ways you can implement the Infinite Scroll in your project.

  1. Vanilla JS
  2. Plugins.

After searching for a while, there wasn’t any easy way to do it with pure JS code.

So I used a plug in called Vue-infinite-loading, it’s great to use and has nice animations.
Implementing wasn’t smooth for me, so I decided to write an article to save time for others.

Edit on 10/19: If you are using Vuetify, it’s easiest with v-intersect. Available from the Vuetify version 2.1 or more.

Here’s the demo :

This article will be divided in two parts.

  1. Set up a Nuxt.js page with the json:api (optional)
  2. Implement the Infinite Scroll

Part 1

(This part is optional. If you have already an existing project, you can jump to the next part)

Let’s create a Nuxt.js project as written in the official document. Here’s a quick GIF:

Creating a Nuxtjs project

Here’s some basic codes to set up a working page. I’m not explaining the code because this should make sense if you know Nuxt.js. (And if you don’t, you should follow a beginner tutorial to create a basic app and then come here :) )

1.1

Delete all the files in the pages except the index.vue and change the code into the following ones:

<template>
<v-flex>
<v-container fluid grid-list-lg class="mt-5">
<posts/>
</v-container>
</v-flex>
</template>
<script>
import posts from "~/components/Posts.vue";
export default {
components: { posts }
};
</script>

(I am using Vuetify framework for design. So that’s why you are seeing the <v-something> tags. The “ v” is for Vuetify components.)

1.2

Now, Delete all the files in the componentsfolder and create a new component named Posts.vue and paste the following codes:

<template> 
<v-card flat>
<v-layout row wrap>
<v-flex v-for="(title, index) in titles" :key="index">
<v-card flat hover class="white pb-2 mb-1 pl-2">
<v-layout>
<v-flex xs10>
<div class="py-2">{{ title.body }}</div>
</v-flex>
</v-layout>
</v-card>
</v-flex>
</v-layout>
</v-card>
</template>

<script>
import axios from "axios";
export default {
name: "Posts",
data() { return {
titles: [], page: 1 };
},

computed: {
url() { return "https://jsonplaceholder.typicode.com/posts?_page=" + this.page; } },

created() {
this.fetchData(); },
methods: {
async fetchData() { const response = await axios.get(this.url); this.titles = response.data; } }
};
</script>
<style scoped>
.theme--light.v-card { background-color: #f5f5f5; }
</style>

1.3

In the layouts/default.vue file paste the following code:

<template>
<v-app>
<nuxt class="mb-5"/>
</v-app>
</template>

If you followed all the steps correctly your project will look like this:

The basic project which is fetching data from an API

You can see in the sandbox that there are a few posts in the page which I am calling from an API. And right now there are no Infinite Scroll.

The basic part is complete. Now with that out of the way.

Part 2

Next, install the Vue-infinite-loading here with npm.

npm install vue-infinite-loading -S

Then in the pluginsfolder , create a blank file named infiniteloading.js and paste the following code:

import Vue from 'vue'
import InfiniteLoading from 'vue-infinite-loading'

Vue.component('infinite-loading', InfiniteLoading)

Now let’s add the plugin file in the nuxt.config.js .

plugins: [
{ src: '~/plugins/infiniteloading', ssr: false }
]

The infinite loading component set up is finished. Yay.

2.1

Now let’s add the following Infinite Scroll component at the bottom of the posts.vue component.

<infinite-loading 
spinner="spiral"
@infinite="infiniteScroll"
></infinite-loading>

Bottom of the page because whenever this component will be visible in the browser, it will trigger the selected method. In this case, the method is infiniteScroll which we will write soon below.

So if it is in the upper side of the page , it will trigger the method as soon as the page is created which we do not want because we haven’t scrolled yet.

I have selected the spinner type as spiral. You can change it to other type. Please check out the official documents of infinite loading component to choose other designs.

2.2

Add the following function in the methods: and you are done.

infiniteScroll($state) {setTimeout(() => {
this.page++
axios.get(this.url)
.then((response) => {
if (response.data.length > 1) {
response.data.forEach((item) => this.titles.push(item))
$state.loaded()
} else { $state.complete() } }).catch((err) => {console.log(err)})}, 500)

setTimeout is for to call the code a little bit late.

axios.get is getting the data from the api.

response.data.length is to check whether it’s getting data, if there is no data it will be false.

response.data.forEach((item) => this.title.push(item)) is adding every new item from array to the title

$state.loaded(),$state.complete() is the animation of loading the component.

The complete code is available in this GitHub repository. Originally published here.

My twitter.

--

--

Sabbir Ahmed

Follow me to read about GO, Nuxt.js, GraphQL and Blockchain.