Skip to content

Commit b4934a9

Browse files
lucasrodesclaude
andcommitted
🔨🤖 301 legacy /en/latest URLs to canonical paths
Existing inbound links from blog posts, Slack, bookmarks etc. point at the ReadTheDocs URL shape (/en/latest/...). Strip that segment in the umbrella router before subproject routing so links continue to resolve on docs-cf.owid.io and the eventual docs.owid.io cut-over. Examples: /projects/etl/en/latest/ → /projects/etl/ /projects/owid-grapher-py/en/latest/x → /projects/owid-grapher-py/x /en/latest/ → / Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 80372ce commit b4934a9

1 file changed

Lines changed: 10 additions & 0 deletions

File tree

‎_worker.js‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,20 @@ const SUBPROJECTS = {
1717
"/projects/owid-grapher-py/": "https://owid-grapher-py-docs.pages.dev",
1818
};
1919

20+
// Legacy ReadTheDocs URLs include an /en/latest segment (e.g.
21+
// /projects/etl/en/latest/, /en/latest/). 301 to the canonical form so
22+
// existing inbound links from blog posts / Slack / bookmarks keep working.
23+
const RTD_LEGACY = /\/en\/latest(\/|$)/;
24+
2025
export default {
2126
async fetch(request, env) {
2227
const url = new URL(request.url);
2328

29+
if (RTD_LEGACY.test(url.pathname)) {
30+
url.pathname = url.pathname.replace(RTD_LEGACY, "$1") || "/";
31+
return Response.redirect(url.toString(), 301);
32+
}
33+
2434
for (const [prefix, origin] of Object.entries(SUBPROJECTS)) {
2535
if (url.pathname.startsWith(prefix)) {
2636
const target = `${origin}${url.pathname}${url.search}`;

0 commit comments

Comments
 (0)