reactjstypescriptstrapiastrojs

Implementing pagination using Astrojs and Strapi CMS


I'm trying to implement pagination in my Astro project, and am using Strapi as a backend. I can control the pagination response by sending the needed items per page:

strapi meta/pagination response

NOTE: I'm using SSR so I'm not using the getStaticPaths function and therefore can't use the inbuilt pagination function of Astro

My problem is that I couldn't change the values of the pages (pages numbers) in Astro. What is the correct way to navigate and change the current page number in Astro?

Data fetch function:

export const fetchArticles = async (page = 1, pageSize = 5, sort = 'createdAt:desc') => {
    const articles = await fetchApi<Article>({
        endpoint: 'articles',
        query: {
            populate: ['category', 'cover'].join(','),
            'pagination[page]': String(page),
            'pagination[pageSize]': String(pageSize),
            sort: sort
        }
    })
    return articles
}

Using the function:

const articles = await fetchArticles(currentPage, 5)

Navigation compoenent (currentPage is increased and that can be seen in the console log since it's a tsx component, but the value of the currentPage in the parent component doesn't change - meaning it doesn't update to the second page for fetching)

import { useState } from 'react'
interface Props {
    metaData: Pagination
    currentPage: number
}
export default function NewPagination(props: Props) {
    let { metaData, currentPage } = props

    const increaseCurrentPage = () => {
        currentPage++
        console.log(currentPage)
    }

    return (
        <div>
            <nav className='text-center'>
                <ul className='inline-flex -space-x-px text-base h-10'>
                    <li>
                        <a className='flex items-center justify-center px-4 h-10 ms-0 leading-tight text-gray-500 bg-white border border-e-0 border-gray-300 rounded-s-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white'>
                            Previous 
                        </a>
                    </li>

                    <li>{currentPage}</li>

                    <li>
                        <a
                            onClick={increaseCurrentPage}
                            className='flex items-center justify-center px-4 h-10 leading-tight text-gray-500 bg-white border border-gray-300 rounded-e-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white'
                        >
                            Next
                        </a>
                    </li>
                </ul>
            </nav>
            <script></script>
        </div>
    )
}

Clicking on "next" does't update the fetch parameter to fetch the second page of the results

Edit: The thing I need to know is how to update the currentPage value so it changes in the fetch function

index component:

---
import ListCategories from '@/components/ListCategories'
import ListPosts from '@/components/ListPosts'
import NewPagination from '@/components/NewPagination'
import TitlePage from '@/components/TitlePage'
import BaseLayout from '@/layouts/BaseLayout'
import Swiper from 'src/components/swiper/Swiper'
import { fetchArticles } from 'src/utils/fetchApiData'

let currentPage = 1

const articles = await fetchArticles(currentPage, 5)

const allArticles = articles.data.map((article) => article)
const swiperContent = allArticles.slice(0, 4)
// const metaData = articles.meta.pagination
---

<BaseLayout title=''>
    <Swiper client:load swiperContent={swiperContent} />
    <TitlePage title={'All Articles'} />

    <ListCategories />

    <ListPosts FirstBig={true} allArticles={allArticles} />
    <NewPagination />
</BaseLayout>

<script>
    import { animate } from 'motion'
    const showAnimations = localStorage.getItem('animations') === 'true'

    if (showAnimations) {
        animate(
            '.title',
            { y: [80, 0], opacity: [0, 1] },
            {
                duration: 2.5,
                opacity: { duration: 3 },

                offset: [0, 0.55, 0.75]
            }
        )
    }
</script>


Solution

  • I was able to fix this by changing the pathname (using query params)