Astro Repo

Astro Content Collections Pagination

5 min read

Pagination for Content Collections

Url structure is different than Wordpress, so if moving to Astro, you may need to do some redirects, if you want to keep /page/ folder structure.

/blog/page/[…page].astro
---
import { getCollection } from "astro:content";

export async function getStaticPaths({paginate}) {
  const allPosts  = (await getCollection("blog")).sort(
    (a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf()
  );

  return paginate(allPosts, {pageSize: 10});
}
const {page} = Astro.props;
---

page variable has all of the post data.

p.slug is automagically provided by Astro, either filename or slug variable in the frontmatter.

p.data is frontmatter data.

/blog/page/[…page].astro
...
{page.data.map(p => (
  <div class="post-list__item">
    <h2 class="post-list__title">
      <a href={`/${p.slug}`}>{p.data.title}</a>
    </h2>
    <div class="post-list__description">
      <p>{p.data.description}</p>
    </div>
  </div>
))}
...

Pagination variables:

/blog/page/[…page].astro
---
import Pagination from "@components/Pagination.astro"
---
...
<Pagination
  basePath="/blog/page"
  currentPage={page.currentPage}
  lastPage={page.lastPage}
  prevUrl={page.url.prev}
  nextUrl={page.url.next}
/>
...

For the pagination component:

Pagination.astro
---
const { basePath, currentPage, lastPage, prevUrl, nextUrl } = Astro.props;
const prevArrow = `<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16"><path d="m3.86 8.753 5.482 4.796c.646.566 1.658.106 1.658-.753V3.204a1 1 0 0 0-1.659-.753l-5.48 4.796a1 1 0 0 0 0 1.506z"></path></svg>`;
const nextArrow = `<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16"><path d="m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z"></path></svg>`;

let pageList = '';

for(let i=1; i<=lastPage; i++){
    if(i===currentPage){
        pageList += `<span title="Current Page" class="pagination__link pagination__link--current"><span class="navitext">Page: </span>${i}<span class="navitext"> of ${lastPage}</span></span>`;
    } else {
        pageList += `<a title="Page ${i}" class="pagination__link" href="${basePath}/${i}">${i}</a>`;
    }
}

const prev = (currentPage===1) ? `<span class="pagination__link">${prevArrow}</span>` : `<a title="Previous Page" class="pagination__link" href="${prevUrl}">${prevArrow}</a>`;
const next = (currentPage===lastPage) ? `<span class="pagination__link">${nextArrow}</span>` : `<a title="Next Page" class="pagination__link" href="${nextUrl}">${nextArrow}</a>`;
---
<nav>
  <div class="pagination">
    <Fragment set:html={`${prev}${pageList}${next}`}></Fragment>
  </div>
</nav>