How to add Pagination to @nuxt/content

Last updated at April 24, 2021

💬

Every blog website need a pagination feature to display content efficiently. Lets start to add pagination feature to blog.

I'll use /articles url to display 9 articles at start, and use /articles/page/2, ..., /articles/page/999 url to pagination.

Create Pagination.vue component in /components folder

/components/Pagination.vue
<template>
  <section id="prev-next" class="flex justify-center mt-4 space-x-2">
    <nuxt-link v-if="prevPage" :to="prevLink" class="py-2 px-4 bg-white text-gray-700 border border-gray-200 font-medium rounded hover:bg-gray-200">Prev page</nuxt-link>
    <nuxt-link v-if="nextPage" :to="`${urlPrefix}/page/${pageNo + 1}`" class="py-2 px-4 bg-white text-gray-700 border border-gray-200 font-medium rounded hover:bg-gray-200">Next page</nuxt-link>
  </section>
</template>

<script>
export default {
  props: ['prevPage', 'nextPage', 'pageNo', 'urlPrefix'],
  computed: {
    prevLink() {
      return this.pageNo === 2 ? this.urlPrefix : `${this.urlPrefix}/page/${this.pageNo - 1}`
    }
  }
}
</script>

<style>

</style>

Query data and set to <Pagination /> component in your list vue

/pages/articles/index.vue
<template>
  <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
    <!-- Your html code here -->
    <Pagination :nextPage="nextPage" :pageNo="1" urlPrefix="/articles" />
  </div>
</template>

<script>
export default {
  async asyncData({ $content, params }) {
    const tenArticles = await $content('articles')
      .only(['title', 'description', 'img', 'slug', 'tags', 'createdAt'])
      .sortBy('createdAt', 'desc')
      .limit(10)
      .fetch()

    const nextPage = tenArticles.length === 10
    const articles = nextPage ? tenArticles.slice(0, -1) : tenArticles

    return {
      nextPage,
      articles
    }
  }
}
</script>

Query data and set to <Pagination /> component in your page vue

/pages/articles/page/_number.vue
<template>
  <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
    <!-- Your html code here -->
    <Pagination :prevPage="pageNo > 1" :nextPage="nextPage" :pageNo="pageNo" urlPrefix="/articles" />
  </div>
</template>

<script>
export default {
  async asyncData({ $content, params, error }) {
    const pageNo = parseInt(params.number)
    const tenArticles = await $content('articles')
      .only(['title', 'description', 'img', 'slug', 'tags'])
      .sortBy('createdAt', 'desc')
      .limit(10)
      .skip(9 * (pageNo - 1))
      .fetch()

    if (!tenArticles.length) {
      return error({ statusCode: 404, message: 'No articles found!' })
    }

    const nextPage = tenArticles.length === 10
    const articles = nextPage ? tenArticles.slice(0, -1) : tenArticles

    return {
      nextPage,
      articles,
      pageNo
    }
  },
}
</script>