Skip to content

Commit 3caa69c

Browse files
committed
fix(seo): prefix sitemap ignorePatterns with /docs/, validate HowTo steps
baseUrl is /docs/, so Docusaurus emits sitemap routes as /docs/tags/... and /docs/1.0.0/.../docs/2.0.0/... . The previous bare patterns (/tags/**, /1.0.0/**, /2.0.0/**) couldn't match those, so tag indexes and the legacy doc versions were quietly slipping into the generated sitemap despite the noIndex headers elsewhere. Add the prefixed patterns; keep the bare ones as defence-in-depth in case baseUrl is ever flattened. HowTo.js was emitting steps with empty `text` and auto-generated "Step N" names whenever authors omitted those fields, producing low-quality HowTo structured data the rich-results test flags. Filter to entries that carry both `name` and `text`; drop the schema entirely if none qualify, and render the visible <ol> from the same filtered list so the markup and JSON-LD stay in sync. Signed-off-by: Neha Gupta <gneha21@yahoo.in>
1 parent b4a077f commit 3caa69c

2 files changed

Lines changed: 29 additions & 6 deletions

File tree

docusaurus.config.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,17 @@ module.exports = {
472472
// additionally carry `noIndex: true` via their `versions` config
473473
// above; excluding from the sitemap signals that they should not
474474
// be ranked at all.
475+
//
476+
// Docusaurus matches `ignorePatterns` against the full route path
477+
// including `baseUrl` (`/docs/`), so the patterns must carry that
478+
// prefix — bare `/tags/**` and `/1.0.0/**` would never match the
479+
// emitted `/docs/tags/...` and `/docs/1.0.0/...` routes. Bare
480+
// patterns are kept as defence-in-depth in case `baseUrl` is ever
481+
// flattened to `/`.
475482
ignorePatterns: [
483+
"/docs/tags/**",
484+
"/docs/1.0.0/**",
485+
"/docs/2.0.0/**",
476486
"/tags/**",
477487
"/1.0.0/**",
478488
"/2.0.0/**",

src/components/HowTo.js

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,29 @@ export default function HowTo({
4242
return null;
4343
}
4444

45+
// Filter to steps that carry both `name` and `text` per Google's HowTo
46+
// requirements. Auto-generating "Step N" placeholders or emitting empty
47+
// `text` produces low-quality structured data that the rich-results test
48+
// flags. If the author gave us nothing usable, drop the schema entirely
49+
// rather than ship a hollow HowTo.
50+
const validSteps = steps.filter(
51+
(s) => typeof s.name === "string" && s.name.trim() &&
52+
typeof s.text === "string" && s.text.trim(),
53+
);
54+
if (validSteps.length === 0) {
55+
return null;
56+
}
57+
4558
const schema = {
4659
"@context": "https://schema.org",
4760
"@type": "HowTo",
4861
name,
49-
step: steps.map((s, i) => {
62+
step: validSteps.map((s, i) => {
5063
const step = {
5164
"@type": "HowToStep",
5265
position: i + 1,
53-
name: s.name || `Step ${i + 1}`,
54-
text: s.text || "",
66+
name: s.name,
67+
text: s.text,
5568
};
5669
if (s.url) step.url = s.url;
5770
if (s.image) step.image = s.image;
@@ -105,10 +118,10 @@ export default function HowTo({
105118
would produce duplicate ids in the DOM whenever `visible`
106119
is enabled. The list is the readable view; `step.url` in
107120
the JSON-LD already covers the schema linkage. */}
108-
{steps.map((s, i) => (
121+
{validSteps.map((s, i) => (
109122
<li key={i}>
110-
<strong>{s.name || `Step ${i + 1}`}</strong>
111-
{s.text && <div>{s.text}</div>}
123+
<strong>{s.name}</strong>
124+
<div>{s.text}</div>
112125
</li>
113126
))}
114127
</ol>

0 commit comments

Comments
 (0)