From e73bd3851c99ec93c3429507b5a5b5fc9f4895dc Mon Sep 17 00:00:00 2001 From: Helmi Pradita Date: Fri, 30 Oct 2026 10:32:40 +0700 Subject: [PATCH] fix(sitemap): skip the index entry when building page URLs --- .changeset/sitemap-skip-index.md | 5 +++ .../src/sitemap/__tests__/generate.test.mjs | 45 +++++++++++++++++++ packages/react/src/sitemap/generate.mjs | 2 +- 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 .changeset/sitemap-skip-index.md create mode 100644 packages/react/src/sitemap/__tests__/generate.test.mjs diff --git a/.changeset/sitemap-skip-index.md b/.changeset/sitemap-skip-index.md new file mode 100644 index 00000000..96721441 --- /dev/null +++ b/.changeset/sitemap-skip-index.md @@ -0,0 +1,5 @@ +--- +'@doc-kit/generator-react': patch +--- + +Skip the `index` entry when building page URLs in the `sitemap` generator so the index page is only listed once under `indexURL`. diff --git a/packages/react/src/sitemap/__tests__/generate.test.mjs b/packages/react/src/sitemap/__tests__/generate.test.mjs new file mode 100644 index 00000000..9f92e7b2 --- /dev/null +++ b/packages/react/src/sitemap/__tests__/generate.test.mjs @@ -0,0 +1,45 @@ +import assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; + +import { setConfig } from '@doc-kit/core/utils/configuration/index.mjs'; + +import { generate } from '../generate.mjs'; + +const config = await setConfig({ target: ['sitemap'] }); + +config.sitemap.output = undefined; +config.sitemap.baseURL = 'https://example.com'; + +const entry = (api, depth = 1) => ({ + api, + path: `/${api}`, + heading: { depth }, +}); + +const extractLocations = sitemap => + Array.from(sitemap.matchAll(/(.*?)<\/loc>/g), match => match[1]); + +describe('sitemap', () => { + it('lists depth-1 pages alongside the index URL', async () => { + const sitemap = await generate([ + entry('fs', 1), + entry('fs', 2), + entry('http', 1), + ]); + + assert.deepEqual(extractLocations(sitemap), [ + 'https://example.com/fs.html', + 'https://example.com/http.html', + 'https://example.com/', + ]); + }); + + it('does not list the index page twice when index.md is an input', async () => { + const sitemap = await generate([entry('index', 1), entry('foo', 1)]); + + assert.deepEqual(extractLocations(sitemap), [ + 'https://example.com/foo.html', + 'https://example.com/', + ]); + }); +}); diff --git a/packages/react/src/sitemap/generate.mjs b/packages/react/src/sitemap/generate.mjs index dc6695fd..eb2ddaf5 100644 --- a/packages/react/src/sitemap/generate.mjs +++ b/packages/react/src/sitemap/generate.mjs @@ -30,7 +30,7 @@ export async function generate(entries) { const lastmod = new Date().toISOString().split('T')[0]; const apiPages = entries - .filter(entry => entry.heading.depth === 1) + .filter(entry => entry.heading.depth === 1 && entry.api !== 'index') .map(entry => createPageSitemapEntry(entry, config, lastmod)); const loc = populate(config.indexURL, config);