Skip to content

fix(docs): stop sitemap listing the homepage twice - #2899

Open
Erol444 wants to merge 1 commit into
mainfrom
fix/sitemap-duplicate-homepage
Open

fix(docs): stop sitemap listing the homepage twice#2899
Erol444 wants to merge 1 commit into
mainfrom
fix/sitemap-duplicate-homepage

Conversation

@Erol444

@Erol444 Erol444 commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Already deployed/live, minor SEO fix

Problem

https://inference.roboflow.com/sitemap.xml is 361 bytes and has two <url> entries. Both are the same URL:

<loc>https:&#x2f;&#x2f;inference.roboflow.com&#x2f;</loc>   (changefreq weekly, priority 1.0)
<loc>https:&#x2f;&#x2f;inference.roboflow.com&#x2f;</loc>   (no other tags)

Cause

theme/sitemap.xml hard-coded the homepage first, then looped over pages and used page.is_homepage to skip it.

The site builds with zensical build --clean (see .github/workflows/docs.yml). Zensical is a compiled Rust engine and does not define the MkDocs page fields the template relied on: is_homepage, is_link, abs_url, build_date_utc, update_date. All were undefined, so not page.is_homepage was always true and the homepage was emitted a second time. The same undefined names are why no <lastmod> was ever written.

Fix

Guard on the page URL against config.site_url, which zensical does define, instead of is_homepage. Also drop the |e filter, which double-escaped / as &#x2f; inside <loc>.

Verification

zensical build --clean now produces valid XML with a single URL and clean escaping:

<url>
     <loc>https://inference.roboflow.com/</loc>
     <changefreq>weekly</changefreq>
     <priority>1.0</priority>
</url>

One URL is the correct result today. pages holds only nav pages, and the nav in mkdocs.yml is index.md plus external links to docs.roboflow.com. I checked the live site: /install/, /workflows/about/, and /api/ return 200 but serve a noindex meta-refresh to docs.roboflow.com, so the homepage is the only indexable page.

Out of scope

Those old paths redirect with meta-refresh, not HTTP 301. Google gives meta-refresh less weight and passes less link equity. If the old URLs still have backlinks, real 301s at the CDN would keep more of that value. Worth a separate look.

🤖 Generated with Claude Code

The sitemap template hard-coded the homepage, then looped over `pages`
and used `page.is_homepage` to skip it. The site builds with zensical,
a Rust engine that does not define `is_homepage`, `is_link`, `abs_url`,
`build_date_utc`, or `update_date`. Those names were undefined, so the
guard never matched and the homepage was emitted a second time.

The live sitemap was 361 bytes with two `<url>` entries, both
`https://inference.roboflow.com/`.

Guard on the page URL against `config.site_url` instead, which zensical
does define. Also drop the `|e` filter, which double-escaped `/` as
`&#x2f;` inside `<loc>`.

Verified with `zensical build --clean`: the sitemap is valid XML with a
single URL. One URL is correct today, because `pages` holds only nav
pages and the nav is `index.md` plus external links. Every other path
serves a `noindex` redirect to docs.roboflow.com.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

👋 Thanks for the pull request! Here is how automated Claude review works here, so you spend credits (and reviewer time) wisely.

🚦 This PR is marked Ready for review, so automated Claude review will run — and every pass spends real credits.

Warning

💸 The Claude reviewer bills in credits, not vibes

Automated review spins up a real agent that reads real code and spends real credits on every pass. It is glad to help — but it is not a rubber duck, a linter you poke in a loop, or a substitute for reading the contributing guide. Treat it like an expensive senior reviewer whose time you booked, and show up prepared.

Draft when unsure, Ready when you mean it:

  • 🌱 Not sure the PR is in good shape yet? Keep it (or set it back) as a draft — drafts pause review, so you can push and iterate without burning credits on a moving target.
  • 💪 Feel strong about the contents? Mark it Ready for review and the reviewer will take a look.

However you get there, arrive prepared:

  • 🧱 Bring a SOLID, thorough PR. Point your local agent at our skills/ to tune it to our guidelines first — or, if you are one of those fabled carbon-based contributors, read them yourself. A half-baked diff costs exactly the same to review as a finished one.
  • Resolve every comment before you re-request review. Re-requesting with threads still open means paying twice for the same conversation.
  • 🔁 Do not use CI review as an inner loop for a local agent. The reviewer is not a step-by-step debugger — do the unfolding locally and arrive with the answer, not the search.
  • 🙋 If something looks off, ask a human. One question to a maintainer is cheaper and faster than three rounds of agent re-review chasing a misread.

Reviews are not free. A draft costs nothing to review; a Ready PR is a promise that it is worth reviewing.

  • Prefer to skip automated review entirely? Add the skip-claude-review label.

@github-actions

Copy link
Copy Markdown
Contributor

🤖 Claude review started at commit 68219e9ad0eb371a51ebad2538cf89bea5194d05.

New commits are not auto-reviewed. Add the claude-review label to request a re-review — the label is consumed when the review starts, so just add it again next time.

@github-actions

Copy link
Copy Markdown
Contributor

Skills: none dispatched — theme/ (docs-site theme templates) has no dedicated surface skill; applied generic review plus the backward-compat / user-visible-behavior topic lens.

No dedicated surface skill covers theme/ (docs-site theme) — generic review plus topic skills only.

Scope: single Jinja2 template theme/sitemap.xml, a docs-site/SEO artifact — not part of a versioned subsystem, so no inference_models/Execution Engine changelog entry is required.

Traced the fix: guarding the loop on url|trim('/') != config.site_url|trim('/') correctly deduplicates the homepage where the old page.is_homepage guard silently failed (that field is undefined under zensical). Under zensical, page.canonical_url/page.abs_url resolve to falsy Undefined and are skipped by if url and ... — no crash, no spurious rows; under MkDocs they resolve normally, so the template now works on both engines. Dropping |e relies on the build engine autoescape (evidenced by the original &#x2f; double-escaping) and the emitted URLs contain no XML-special characters. No merge blockers.

Reviewed at HEAD: 68219e9

@github-actions

Copy link
Copy Markdown
Contributor

😎 PR passes the vibe-check and trust-me-bro verification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant