summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/eight-humans-push.md5
-rw-r--r--packages/astro/src/core/render/paginate.ts41
-rw-r--r--packages/astro/test/astro-pagination.test.js22
-rw-r--r--packages/astro/test/fixtures/astro-pagination/src/pages/posts/[slug]/[page].astro6
4 files changed, 54 insertions, 20 deletions
diff --git a/.changeset/eight-humans-push.md b/.changeset/eight-humans-push.md
new file mode 100644
index 000000000..bb37e6a3a
--- /dev/null
+++ b/.changeset/eight-humans-push.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Fix next and previous links for index routes when using pagination
diff --git a/packages/astro/src/core/render/paginate.ts b/packages/astro/src/core/render/paginate.ts
index 7c9d06e0d..dffabe178 100644
--- a/packages/astro/src/core/render/paginate.ts
+++ b/packages/astro/src/core/render/paginate.ts
@@ -39,6 +39,21 @@ export function generatePaginateFunction(routeMatch: RouteData): PaginateFunctio
...additionalParams,
[paramName]: includesFirstPageNumber || pageNum > 1 ? String(pageNum) : undefined,
};
+ const current = correctIndexRoute(routeMatch.generate({ ...params }));
+ const next =
+ pageNum === lastPage
+ ? undefined
+ : correctIndexRoute(routeMatch.generate({ ...params, page: String(pageNum + 1) }));
+ const prev =
+ pageNum === 1
+ ? undefined
+ : correctIndexRoute(
+ routeMatch.generate({
+ ...params,
+ page:
+ !includesFirstPageNumber && pageNum - 1 === 1 ? undefined : String(pageNum - 1),
+ })
+ );
return {
params,
props: {
@@ -51,21 +66,7 @@ export function generatePaginateFunction(routeMatch: RouteData): PaginateFunctio
total: data.length,
currentPage: pageNum,
lastPage: lastPage,
- url: {
- current: routeMatch.generate({ ...params }),
- next:
- pageNum === lastPage
- ? undefined
- : routeMatch.generate({ ...params, page: String(pageNum + 1) }),
- prev:
- pageNum === 1
- ? undefined
- : routeMatch.generate({
- ...params,
- page:
- !includesFirstPageNumber && pageNum - 1 === 1 ? '' : String(pageNum - 1),
- }),
- },
+ url: { current, next, prev },
} as Page,
},
};
@@ -73,3 +74,13 @@ export function generatePaginateFunction(routeMatch: RouteData): PaginateFunctio
return result;
};
}
+
+function correctIndexRoute(route: string) {
+ // `routeMatch.generate` avoids appending `/`
+ // unless `trailingSlash: 'always'` is configured.
+ // This means an empty string is possible for the index route.
+ if (route === '') {
+ return '/';
+ }
+ return route;
+}
diff --git a/packages/astro/test/astro-pagination.test.js b/packages/astro/test/astro-pagination.test.js
index 563b66492..994f8e0ac 100644
--- a/packages/astro/test/astro-pagination.test.js
+++ b/packages/astro/test/astro-pagination.test.js
@@ -41,12 +41,28 @@ describe('Pagination', () => {
{ color: 'blue', p: '2' },
];
await Promise.all(
- params.map(async ({ color, p }) => {
+ params.map(async ({ color, p }, idx) => {
const html = await fixture.readFile(`/posts/${color}/${p}/index.html`);
const $ = cheerio.load(html);
- expect($('#page-a').text()).to.equal(p);
- expect($('#page-b').text()).to.equal(p);
+ expect($('#page-param').text()).to.equal(p);
+ expect($('#currentPage').text()).to.equal(p);
expect($('#filter').text()).to.equal(color);
+
+ const prevHref = $('#prev').attr('href');
+ const nextHref = $('#next').attr('href');
+
+ if (color === 'red') {
+ expect(prevHref).to.be.undefined;
+ expect(nextHref).to.be.undefined;
+ }
+ if (color === 'blue' && p === '1') {
+ expect(prevHref).to.be.undefined;
+ expect(nextHref).to.equal('/posts/blue/2');
+ }
+ if (color === 'blue' && p === '2') {
+ expect(prevHref).to.equal('/posts/blue/1');
+ expect(nextHref).to.be.undefined;
+ }
})
);
});
diff --git a/packages/astro/test/fixtures/astro-pagination/src/pages/posts/[slug]/[page].astro b/packages/astro/test/fixtures/astro-pagination/src/pages/posts/[slug]/[page].astro
index 49a2f702e..c4cc39739 100644
--- a/packages/astro/test/fixtures/astro-pagination/src/pages/posts/[slug]/[page].astro
+++ b/packages/astro/test/fixtures/astro-pagination/src/pages/posts/[slug]/[page].astro
@@ -21,8 +21,10 @@ const canonicalURL = new URL(Astro.url.pathname, Astro.site);
<link rel="canonical" href={canonicalURL.href} />
</head>
<body>
- <div id="page-a">{params.page}</div>
- <div id="page-b">{page.currentPage}</div>
+ <div id="page-param">{params.page}</div>
+ <div id="currentPage">{page.currentPage}</div>
<div id="filter">{filter}</div>
+ <a href={page.url.prev} id="prev">Previous</a>
+ <a href={page.url.next} id="next">Next</a>
</body>
</html>