Skip to content

feat(seo): add a temporary sitemap of retired URLs - #325

Merged
harlan-zw merged 7 commits into
mainfrom
feat/seo-retired-sitemap
Sep 30, 2026
Merged

harlan-zw merged 7 commits into
mainfrom
feat/seo-retired-sitemap

Conversation

@harlan-zw

@harlan-zw harlan-zw commented Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator

❓ Type of change

  • 👌 Enhancement

📚 Description

Stacked on #317 (fix/soft-404-missing-skills). The base is that branch, not main. It is independent of #322 and merges in any order.

Experiment E from the death-zone plan, temporary, remove on 2026-11-11. Google still holds about 52k old URLs as "Crawled, currently not indexed", and it crawls about 29 HTML pages a day. A separate retired sitemap lists URLs that now answer 301, 404 or 410, each with one stable lastmod (2026-09-30, the experiment start). The aim is a faster recrawl, so Google drops them sooner. Mueller has hinted this works; treat it as practitioner advice, not documented policy. Scale rule: "Crawled, currently not indexed" falls by 10k in four weeks.

I did not submit it to Search Console. sitemap_index.xml lists it, so submit the index only if you want it read.

Where the URLs come from (9,647 after de-duplication, checked against production on 2026-09-30):

Source URLs Status now
Search Console pages with impressions, 6 months (all 8,808 fetched; homepage and /skills answer 200 and are left out) 8,806 all 301 (8,461 legacy /skills/*, 345 /orgs/*)
Skills with source_resolved = 0, read from D1 on each request 798 410 through the gone middleware
Deleted collections, read from D1 on each request 24 12 answer 301, 12 answer 404
Tag pages that redirect to a category (MARKETING_REDIRECTS) 19 301

The 8,806 are a dated snapshot in data/retired-urls.json. The other three sources come from the same tables the middleware and redirects use, so they follow the site as it changes. I probed all 817 of those against production; each answered 301 or 410. scripts/check-retired-sitemap.ts re-probes the served sitemap. It exits non-zero if the sitemap fails to load, is empty, or any URL answers something other than 301, 404 or 410. Run it after deploy.

Not covered: /guides/* and /people/* (410) and the retired category redirects in routeRules. None of them appear in Search Console pages, and no table lists them.

After 2026-11-11 the handler returns an empty list without running its D1 queries. Removal steps are in the header of layers/registry/server/utils/retired-sitemap.ts.

The lastmod stays fixed on purpose. Google ignores a lastmod that changes on every regeneration. This PR holds only the retired sitemap work; marketing and docs edits are gone.

🤖 AI disclosure: Harlan Agent Kit modified this description. My AI open-source policy.

Any made-up /gh/<owner>/<repo>/<skill> URL answered 200 with a thin
page and a canonical to the homepage. Google filed 2,621 of them as
soft 404s, and the open URL space wastes a small crawl budget. A missing
Skill now answers 404 with noindex and no canonical. A page with no Skill
never canonicalises to the homepage.
Experiment E, remove 2026-11-11. Google still holds about 52k old URLs.
Listing the ones that now answer 301, 404 or 410 with a fresh lastmod
should get them recrawled and dropped sooner. Not submitted.
@harlan-github-agent harlan-github-agent Bot added harlan-agent-running An Agent holds a Task on this issue or pull request right now. harlan-agent-review-required Pull request triage requires an adversarial Review for this head commit. labels Sep 30, 2026
@harlan-github-agent

harlan-github-agent Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

🤖 MERGED

Harlan Agent Kit posted this automated review. It is not Harlan's personal review or approval. AI open source policy. Last updated: 2026-09-30 10:01 UTC.

GitHub merged this pull request.

  • Logged (20/100): Retired entries can go stale between builds, briefly marking a live 200 page as retired in the served sitemap. View code

8fda238b-8322-4350-8ca8-b9cf2466713d

@harlan-github-agent harlan-github-agent Bot added harlan-agent-ready The automated Review passed every gate on this head commit. and removed harlan-agent-running An Agent holds a Task on this issue or pull request right now. harlan-agent-review-required Pull request triage requires an adversarial Review for this head commit. labels Sep 30, 2026
Content edits belonged to other work. The checker now fails on an empty or unloadable sitemap. lastmod is fixed because Google ignores one that changes on every run. After the removal date the handler skips D1.
`nuxi preview --port 5678` starts wrangler on 8787 for the Cloudflare
preset, so Playwright timed out waiting for 5678. The Worker also read
an empty D1 under .output, so every Skill API call failed with 500 and
a missing Skill page rendered its error state with status 200.

The script now applies local migrations and runs wrangler dev against
the same local D1 that `pnpm dev` uses. A fresh checkout gets a
migrated, empty D1.
The page sets no canonical for a missing Skill, but nuxt-seo-utils
adds a self canonical to every page that is not a Nuxt error. That is
harmless on a 404. The spec now fails only when a canonical names
another URL, which is the homepage bug the PR fixes.
A transient API error rendered a real Skill page as 200 noindex, which could drop it from Google. The failed state now answers 503 with Retry-After and emits no robots directive, so Google retries.
@harlan-github-agent harlan-github-agent Bot added the harlan-agent-running An Agent holds a Task on this issue or pull request right now. label Sep 30, 2026
@harlan-github-agent harlan-github-agent Bot removed harlan-agent-ready The automated Review passed every gate on this head commit. harlan-agent-running An Agent holds a Task on this issue or pull request right now. labels Sep 30, 2026
@harlan-github-agent harlan-github-agent Bot added the harlan-agent-ready The automated Review passed every gate on this head commit. label Sep 30, 2026
@harlan-zw
harlan-zw changed the base branch from fix/soft-404-missing-skills to main September 30, 2026 09:11
@harlan-zw
harlan-zw merged commit 2d134da into main Sep 30, 2026
6 checks passed
@harlan-github-agent harlan-github-agent Bot removed the harlan-agent-ready The automated Review passed every gate on this head commit. label Sep 30, 2026
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