Skip to content

Commit cefeadf

Browse files
adrianlyjakbholmesdevflorian-lefebvre
authoredMay 21, 2024··
Make status code check more strict for sitemap plugin (#10779)
Co-authored-by: Ben Holmes <hey@bholmes.dev> Co-authored-by: Florian Lefebvre <contact@florian-lefebvre.dev>
1 parent 026f50a commit cefeadf

File tree

5 files changed

+50
-12
lines changed

5 files changed

+50
-12
lines changed
 

‎.changeset/nasty-turtles-obey.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@astrojs/sitemap": patch
3+
---
4+
5+
Fixes false positives for status code routes like `404` and `500` when generating sitemaps.

‎packages/integrations/sitemap/src/index.ts

+20-11
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,23 @@ const PKG_NAME = '@astrojs/sitemap';
4747
const OUTFILE = 'sitemap-index.xml';
4848
const STATUS_CODE_PAGES = new Set(['404', '500']);
4949

50-
function isStatusCodePage(pathname: string): boolean {
51-
if (pathname.endsWith('/')) {
52-
pathname = pathname.slice(0, -1);
53-
}
54-
const end = pathname.split('/').pop() ?? '';
55-
return STATUS_CODE_PAGES.has(end);
56-
}
57-
50+
const isStatusCodePage = (locales: string[]) => {
51+
const statusPathNames = new Set(
52+
locales
53+
.flatMap((locale) => [...STATUS_CODE_PAGES].map((page) => `${locale}/${page}`))
54+
.concat([...STATUS_CODE_PAGES])
55+
);
56+
57+
return (pathname: string): boolean => {
58+
if (pathname.endsWith('/')) {
59+
pathname = pathname.slice(0, -1);
60+
}
61+
if (pathname.startsWith('/')) {
62+
pathname = pathname.slice(1);
63+
}
64+
return statusPathNames.has(pathname);
65+
};
66+
};
5867
const createPlugin = (options?: SitemapOptions): AstroIntegration => {
5968
let config: AstroConfig;
6069

@@ -88,9 +97,9 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
8897
);
8998
return;
9099
}
91-
100+
const shouldIgnoreStatus = isStatusCodePage(Object.keys(opts.i18n?.locales ?? {}));
92101
let pageUrls = pages
93-
.filter((p) => !isStatusCodePage(p.pathname))
102+
.filter((p) => !shouldIgnoreStatus(p.pathname))
94103
.map((p) => {
95104
if (p.pathname !== '' && !finalSiteUrl.pathname.endsWith('/'))
96105
finalSiteUrl.pathname += '/';
@@ -107,7 +116,7 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
107116
* Dynamic URLs have entries with `undefined` pathnames
108117
*/
109118
if (r.pathname) {
110-
if (isStatusCodePage(r.pathname ?? r.route)) return urls;
119+
if (shouldIgnoreStatus(r.pathname ?? r.route)) return urls;
111120

112121
// `finalSiteUrl` may end with a trailing slash
113122
// or not because of base paths.

‎packages/integrations/sitemap/test/fixtures/static/astro.config.mjs

+9-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,15 @@ import sitemap from '@astrojs/sitemap';
22
import { defineConfig } from 'astro/config';
33

44
export default defineConfig({
5-
integrations: [sitemap()],
5+
integrations: [sitemap({
6+
i18n: {
7+
defaultLocale: 'it',
8+
locales: {
9+
it: 'it-IT',
10+
de: 'de-DE',
11+
}
12+
}
13+
})],
614
site: 'http://example.com',
715
redirects: {
816
'/redirect': '/'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
export async function getStaticPaths() {
3+
return [
4+
{ params: { id: '404' } },
5+
{ params: { id: '405' } },
6+
]
7+
}
8+
9+
const { id } = Astro.params
10+
---
11+
<!DOCTYPE html><html> <head><title>Product #{id}</title></head> <body> <h1>Product #404</h1> <p>This is a product that just happens to have an ID of {id}. It is found!</p></body></html>

‎packages/integrations/sitemap/test/staticPaths.test.js

+5
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ describe('getStaticPaths support', () => {
3636
assert.equal(urls.includes('http://example.com/123/'), true);
3737
});
3838

39+
it('includes numerical 404 pages if not for i18n', () => {
40+
assert.equal(urls.includes('http://example.com/products-by-id/405/'), true);
41+
assert.equal(urls.includes('http://example.com/products-by-id/404/'), true);
42+
});
43+
3944
it('should render the endpoint', async () => {
4045
const page = await fixture.readFile('./it/manifest');
4146
assert.match(page, /I'm a route in the "it" language./);

0 commit comments

Comments
 (0)
Please sign in to comment.