From adab863f997d4f96b371ad54a58c03cd9ad9aa79 Mon Sep 17 00:00:00 2001 From: Tanner Linsley Date: Sat, 31 Oct 2026 22:47:24 -0600 Subject: [PATCH] fix(seo): exclude documentation artifacts from the sitemap --- src/utils/sitemap-docs.ts | 20 ++++++++++++++++++++ src/utils/sitemap.ts | 19 +------------------ tests/sitemap-docs.test.ts | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 18 deletions(-) create mode 100644 src/utils/sitemap-docs.ts create mode 100644 tests/sitemap-docs.test.ts diff --git a/src/utils/sitemap-docs.ts b/src/utils/sitemap-docs.ts new file mode 100644 index 000000000..e8b5516e6 --- /dev/null +++ b/src/utils/sitemap-docs.ts @@ -0,0 +1,20 @@ +const LOW_VALUE_DOCS_SITEMAP_SEGMENTS = new Set(['examples', 'community']) + +const LOW_VALUE_DOCS_SITEMAP_SLUGS = new Set([ + 'community-resources', + 'contributors', + 'npm-stats', +]) + +export function isHighValueDocsSlug(slug: string) { + const segments = slug.split('/').filter(Boolean) + + return ( + segments.length > 0 && + !segments.some((segment) => + /^(?:drafts|readme)$|\.draft$/i.test(segment), + ) && + !segments.some((segment) => LOW_VALUE_DOCS_SITEMAP_SEGMENTS.has(segment)) && + !LOW_VALUE_DOCS_SITEMAP_SLUGS.has(slug) + ) +} diff --git a/src/utils/sitemap.ts b/src/utils/sitemap.ts index f818b1740..e395216c3 100644 --- a/src/utils/sitemap.ts +++ b/src/utils/sitemap.ts @@ -1,3 +1,4 @@ +import { isHighValueDocsSlug } from './sitemap-docs' import { getStartExampleSitemapEntries } from './start-example-pages' import { getBranch, libraries } from '~/libraries' import type { LibrarySlim } from '~/libraries/types' @@ -23,14 +24,6 @@ const HIGH_VALUE_NON_DOC_PAGES = [ '/paid-support', ] as const satisfies ReadonlyArray -const LOW_VALUE_DOCS_SITEMAP_SEGMENTS = new Set(['examples', 'community']) - -const LOW_VALUE_DOCS_SITEMAP_SLUGS = new Set([ - 'community-resources', - 'contributors', - 'npm-stats', -]) - function trimTrailingSlash(url: string) { return url.replace(/\/$/, '') } @@ -62,16 +55,6 @@ function getLibraryEntries(): Array { }) } -function isHighValueDocsSlug(slug: string) { - const segments = slug.split('/').filter(Boolean) - - return ( - segments.length > 0 && - !segments.some((segment) => LOW_VALUE_DOCS_SITEMAP_SEGMENTS.has(segment)) && - !LOW_VALUE_DOCS_SITEMAP_SLUGS.has(slug) - ) -} - async function getLibraryDocsEntries( library: LibrarySlim, ): Promise> { diff --git a/tests/sitemap-docs.test.ts b/tests/sitemap-docs.test.ts new file mode 100644 index 000000000..21a7eb1cd --- /dev/null +++ b/tests/sitemap-docs.test.ts @@ -0,0 +1,36 @@ +import assert from 'node:assert/strict' +import test from 'node:test' +import { isHighValueDocsSlug } from '../src/utils/sitemap-docs' + +test('sitemap excludes repository artifacts while retaining public guides', () => { + for (const slug of [ + 'how-to/drafts/README', + 'how-to/drafts/search-params-in-forms.draft', + 'how-to/README', + 'contributing/designs/source-failure/README', + 'guide.draft', + 'guides/readme', + ]) { + assert.equal(isHighValueDocsSlug(slug), false, slug) + } + for (const slug of [ + 'overview', + 'framework/react/guides/query-keys', + 'guides/draft', + 'guides/readme-format', + ]) { + assert.equal(isHighValueDocsSlug(slug), true, slug) + } +}) +test('existing sitemap exclusions remain excluded', () => { + for (const slug of [ + '', + 'examples/basic', + 'community/resources', + 'community-resources', + 'contributors', + 'npm-stats', + ]) { + assert.equal(isHighValueDocsSlug(slug), false, slug) + } +})