Pagination
Pagination splits a long list into pages of a few entries each: /posts/page/1, /posts/page/2 and so on. Astro has the paginate() function for this. It arrives as an argument of getStaticPaths() and works out by itself how many pages are needed.
A numbered page
Create src/pages/posts/page/[page].astro. The parameter is called page and holds the page number:
---
import { getCollection } from 'astro:content';
import BaseLayout from '../../../layouts/BaseLayout.astro';
import PostCard from '../../../components/PostCard.astro';
export async function getStaticPaths({ paginate }) {
const posts = (await getCollection('blog'))
.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
return paginate(posts, { pageSize: 5 });
}
const { page } = Astro.props;
---
<BaseLayout title={`Posts, page ${page.currentPage}`}>
<h1>Posts</h1>
{page.data.map((post) => (
<PostCard title={post.data.title} url={`/posts/${post.id}`} />
))}
</BaseLayout>With 12 posts the build creates three pages: /posts/page/1 with five posts, /posts/page/2 with five and /posts/page/3 with two. Open /posts/page/1 to check.
The page object
paginate() passes each page a page prop:
| Field | What it holds |
|---|---|
page.data | Entries of the current page |
page.currentPage | Current page number, starting at 1 |
page.lastPage | Last page number |
page.total | Total number of entries |
page.url.prev | Previous page address or undefined |
page.url.next | Next page address or undefined |
Previous and next links
Add navigation below the list of posts in the same file:
<nav>
{page.url.prev && <a href={page.url.prev}>Newer</a>}
<span>Page {page.currentPage} of {page.lastPage}</span>
{page.url.next && <a href={page.url.next}>Older</a>}
</nav>The first page has no "Newer" link, the last one has no "Older" link. The && condition renders a link only when the address exists.
Linking to the list
The first page of the list now lives at /posts/page/1. Put it in the header navigation instead of /posts; the old src/pages/posts/index.astro can be deleted or kept as a short list of recent posts.
Common mistake
People name the file src/pages/posts/[page].astro, next to src/pages/posts/[id].astro. Both files claim addresses like /posts/something, and a post named 2 would clash with the second page of the list. Keep pagination in a separate folder, such as posts/page/, so the addresses do not overlap.