Skip to content

Commit

Permalink
Make status code check more strict for sitemap plugin (#10779)
Browse files Browse the repository at this point in the history
Co-authored-by: Ben Holmes <hey@bholmes.dev>
Co-authored-by: Florian Lefebvre <contact@florian-lefebvre.dev>
  • Loading branch information
3 people committed May 21, 2024
1 parent 026f50a commit cefeadf
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changeset/nasty-turtles-obey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@astrojs/sitemap": patch
---

Fixes false positives for status code routes like `404` and `500` when generating sitemaps.
31 changes: 20 additions & 11 deletions packages/integrations/sitemap/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,23 @@ const PKG_NAME = '@astrojs/sitemap';
const OUTFILE = 'sitemap-index.xml';
const STATUS_CODE_PAGES = new Set(['404', '500']);

function isStatusCodePage(pathname: string): boolean {
if (pathname.endsWith('/')) {
pathname = pathname.slice(0, -1);
}
const end = pathname.split('/').pop() ?? '';
return STATUS_CODE_PAGES.has(end);
}

const isStatusCodePage = (locales: string[]) => {
const statusPathNames = new Set(
locales
.flatMap((locale) => [...STATUS_CODE_PAGES].map((page) => `${locale}/${page}`))
.concat([...STATUS_CODE_PAGES])
);

return (pathname: string): boolean => {
if (pathname.endsWith('/')) {
pathname = pathname.slice(0, -1);
}
if (pathname.startsWith('/')) {
pathname = pathname.slice(1);
}
return statusPathNames.has(pathname);
};
};
const createPlugin = (options?: SitemapOptions): AstroIntegration => {
let config: AstroConfig;

Expand Down Expand Up @@ -88,9 +97,9 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
);
return;
}

const shouldIgnoreStatus = isStatusCodePage(Object.keys(opts.i18n?.locales ?? {}));
let pageUrls = pages
.filter((p) => !isStatusCodePage(p.pathname))
.filter((p) => !shouldIgnoreStatus(p.pathname))
.map((p) => {
if (p.pathname !== '' && !finalSiteUrl.pathname.endsWith('/'))
finalSiteUrl.pathname += '/';
Expand All @@ -107,7 +116,7 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
* Dynamic URLs have entries with `undefined` pathnames
*/
if (r.pathname) {
if (isStatusCodePage(r.pathname ?? r.route)) return urls;
if (shouldIgnoreStatus(r.pathname ?? r.route)) return urls;

// `finalSiteUrl` may end with a trailing slash
// or not because of base paths.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@ import sitemap from '@astrojs/sitemap';
import { defineConfig } from 'astro/config';

export default defineConfig({
integrations: [sitemap()],
integrations: [sitemap({
i18n: {
defaultLocale: 'it',
locales: {
it: 'it-IT',
de: 'de-DE',
}
}
})],
site: 'http://example.com',
redirects: {
'/redirect': '/'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
export async function getStaticPaths() {
return [
{ params: { id: '404' } },
{ params: { id: '405' } },
]
}
const { id } = Astro.params
---
<!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>
5 changes: 5 additions & 0 deletions packages/integrations/sitemap/test/staticPaths.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ describe('getStaticPaths support', () => {
assert.equal(urls.includes('http://example.com/123/'), true);
});

it('includes numerical 404 pages if not for i18n', () => {
assert.equal(urls.includes('http://example.com/products-by-id/405/'), true);
assert.equal(urls.includes('http://example.com/products-by-id/404/'), true);
});

it('should render the endpoint', async () => {
const page = await fixture.readFile('./it/manifest');
assert.match(page, /I'm a route in the "it" language./);
Expand Down

0 comments on commit cefeadf

Please sign in to comment.