Skip to content

[DOCS] Keep archived doc versions out of search results - #3125

Merged
jiayuasu merged 2 commits into
apache:masterfrom
jiayuasu:docs/noindex-archived-versions
Jul 19, 2026
Merged

[DOCS] Keep archived doc versions out of search results#3125
jiayuasu merged 2 commits into
apache:masterfrom
jiayuasu:docs/noindex-archived-versions

Conversation

@jiayuasu

Copy link
Copy Markdown
Member

Did you read the Contributor Guide?

Is this PR related to a ticket?

  • No:
    • this is a documentation update. The PR name follows the format [DOCS] my subject

What changes were proposed in this PR?

Old, versioned documentation is being indexed by search engines and ranking above the current docs. For example, searching "sedona apache discord" returns the outdated 1.4.1 Discord invite page as the top result.

Root cause, verified on the live site:

Check Result
https://sedona.apache.org/1.4.1/community/discord-invite-form.html HTTP 200 — live & crawlable
Its rel=canonicalhttps://sedona.apache.org/latest/community/discord-invite-form/ HTTP 404 — removed from current docs
robots meta tag on the page none

mike already sets canonical_version: latest, so archived pages carry a canonical to their /latest/ equivalent — but when that equivalent has been removed, the canonical points at a 404 and search engines ignore it and index the stale archived page.

The intuitive fix — a robots.txt Disallow for the archived paths — does not work here: a disallowed page can no longer be crawled, so search engines never observe a removal signal and may keep the stale URL in the index (Google explicitly advises against robots.txt for removal, and Bing similarly needs the page crawlable to see a noindex). The reliable signal on static hosting (no control over response headers / redirects / 410s) is a crawlable <meta name="robots" content="noindex">.

This PR adds tools/noindex_archived_docs.py and a post-deploy step in docs.yml that:

  • Adds <meta name="robots" content="noindex, follow"> to every page of the archived versions and the development snapshot on the published website branch, leaving them crawlable so search engines can drop them.
  • Skips the current stable version. latest is a symlink to that version's directory, so tagging it would de-index the live docs; its duplicate versioned URL (e.g. /1.9.0/) is already consolidated onto /latest/ by the existing canonical tag.
  • Handles raw HTML fragments with no <head> (the Discord invite pages in 1.4.1/1.5.0 — exactly the reported case) by prepending the tag, which the HTML parser hoists into the head.
  • Writes a sitemap-only robots.txt (advertises /latest/sitemap.xml, blocks nothing) so the noindex stays crawlable.
  • Is idempotent: pages that already carry a robots meta tag are untouched. It backfills existing archived versions on the next deploy and tags each version automatically as a new release supersedes it — no per-release maintenance.

Supersedes #3123 (the earlier robots.txt-only approach, which had this exact removal limitation).

How was this patch tested?

  • Ran the script against a current snapshot of the website branch: 19,671 archived pages tagged across all numbered versions + latest-snapshot; the current stable 1.9.0 (and the latest symlink) left untouched; 0 archived HTML pages left without a robots meta, including both headless Discord fragment pages.
  • Verified idempotency (a second run tags 0 pages) and unit-level behavior in sandboxes (current skipped, archived + headless tagged, non-HTML ignored).
  • tools/noindex_archived_docs.py passes black, pyupgrade, and the license-header hook; docs.yml passes actionlint and yamllint (pre-commit).

Did this PR include necessary documentation updates?

  • No, this PR does not affect any public API so no need to change the documentation.

Old, versioned documentation was being indexed by search engines and
ranking above the current docs. For example, the 1.4.1 Discord invite
page ranked as the top result for "sedona apache discord"; it was removed
from current docs, so its rel=canonical points to a /latest/ URL that now
404s and search engines ignore the canonical and index the stale page.

robots.txt Disallow does not fix this: a disallowed page can no longer be
crawled, so search engines never observe a removal signal and may keep the
stale URL indexed. Instead, tag every page of the archived versions and the
development snapshot with a crawlable <meta name="robots" content="noindex">
so they can be crawled and dropped, while /latest/ stays indexable.

Archived versions are frozen once released and never rebuilt, so the tag is
applied by a post-deploy step (tools/noindex_archived_docs.py) that runs over
the published website branch. It is idempotent and skips the current stable
version, which latest symlinks to. The step backfills existing versions on
the next deploy and tags each version as it is superseded by a new release.
- Only skip a page when its robots meta already contains noindex. If it
  carries other directives (e.g. "index, follow" or "noarchive"), merge
  noindex in and drop a conflicting "index" instead of leaving the page
  indexable.
- Fail (exit non-zero) when "latest" is missing, is not a symlink, or
  points to a non-existent directory, instead of tagging every version
  including the current stable one.
@jiayuasu
jiayuasu merged commit 121a319 into apache:master Jul 19, 2026
12 checks passed
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