What Causes This Error?
This error occurs when you use the paginate() function but your route filename doesn’t include a [page] or [...page] parameter. Pagination requires this parameter to generate URLs like /blog/1, /blog/2, etc.
The Problem
---
// src/pages/blog.astro ❌ No page parameter in filename
import { getCollection } from 'astro:content';
export async function getStaticPaths({ paginate }) {
const posts = await getCollection('blog');
return paginate(posts, { pageSize: 10 });
}
---
The Fix
Add Page Parameter to Filename
# Rename your file to include [page] or [...page]
# Option 1: Required page number
src/pages/blog/[page].astro # /blog/1, /blog/2, etc.
# Option 2: Optional page number (recommended)
src/pages/blog/[...page].astro # /blog, /blog/2, /blog/3, etc.
---
// src/pages/blog/[...page].astro ✅
import { getCollection } from 'astro:content';
export async function getStaticPaths({ paginate }) {
const posts = await getCollection('blog');
return paginate(posts, { pageSize: 10 });
}
const { page } = Astro.props;
---
<h1>Blog Posts (Page {page.currentPage})</h1>
{page.data.map((post) => (
<article>
<h2>{post.data.title}</h2>
</article>
))}
<nav>
{page.url.prev && <a href={page.url.prev}>Previous</a>}
{page.url.next && <a href={page.url.next}>Next</a>}
</nav>
Common Scenarios
Basic Pagination
---
// src/pages/posts/[...page].astro
export async function getStaticPaths({ paginate }) {
const posts = await getCollection('blog');
// Sort by date
posts.sort((a, b) =>
new Date(b.data.date).getTime() - new Date(a.data.date).getTime()
);
return paginate(posts, { pageSize: 12 });
}
const { page } = Astro.props;
---
<ul>
{page.data.map((post) => (
<li>
<a href={`/posts/${post.slug}`}>{post.data.title}</a>
</li>
))}
</ul>
<div>
Page {page.currentPage} of {page.lastPage}
</div>
Pagination with Categories
---
// src/pages/category/[category]/[...page].astro
import { getCollection } from 'astro:content';
export async function getStaticPaths({ paginate }) {
const posts = await getCollection('blog');
const categories = [...new Set(posts.map((p) => p.data.category))];
return categories.flatMap((category) => {
const filtered = posts.filter((p) => p.data.category === category);
return paginate(filtered, {
params: { category },
pageSize: 10,
});
});
}
const { page } = Astro.props;
const { category } = Astro.params;
---
<h1>{category} Posts</h1>
Pagination with Tags
---
// src/pages/tag/[tag]/[...page].astro
export async function getStaticPaths({ paginate }) {
const posts = await getCollection('blog');
const tags = [...new Set(posts.flatMap((p) => p.data.tags || []))];
return tags.flatMap((tag) => {
const filtered = posts.filter((p) => p.data.tags?.includes(tag));
return paginate(filtered, {
params: { tag },
pageSize: 10,
});
});
}
---
Page vs …page
# [page].astro - Page number is REQUIRED
/blog/1 ✅
/blog/2 ✅
/blog ❌ 404
# [...page].astro - Page number is OPTIONAL
/blog ✅ (shows page 1)
/blog/2 ✅
/blog/3 ✅
Custom Page Size
---
export async function getStaticPaths({ paginate }) {
const items = await fetchItems();
return paginate(items, {
pageSize: 20, // Items per page
});
}
---
Quick Checklist
- Filename must include
[page]or[...page] - Use
[...page]for optional first page (recommended) - Access pagination via
Astro.props.page - Use
page.url.prevandpage.url.nextfor navigation - Combine with other params using
paramsoption