From 357d9e4c21386cdc6ec9fe95d035eea9c63973c8 Mon Sep 17 00:00:00 2001 From: Taras Mankovski Date: Mon, 28 Sep 2026 10:12:19 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Stop=20doubling=20the=20prefix?= =?UTF-8?q?=20on=20a=20proxied=20site's=20sitemap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Deploys have failed since effection started publishing under its real home. thefrontside/effection#1248 moved its production `--base` to `https://frontside.com/effection`, so every `` in the sitemap it serves now carries the mount point rather than a site-relative path. `parseSitemapUrls` added `/effection` to all of them regardless, asking staticalize for 519 urls under `/effection/effection` that are nowhere. The crawl reported 519 errors and exited non-zero, which is the whole deploy. A path already under the mount is left alone. One that is not still gets it, so Interactors and Graphgen — which advertise their own origin — are unchanged, and so is an Effection preview, whose base is its own alias url. Deciding on the path rather than the origin covers all three, and a sibling such as `/effectionx` is not mistaken for the mount. --- routes/proxy-route.ts | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/routes/proxy-route.ts b/routes/proxy-route.ts index 7132ac9f..60877694 100644 --- a/routes/proxy-route.ts +++ b/routes/proxy-route.ts @@ -199,11 +199,32 @@ function parseSitemapUrls( let path = options.root ? url.pathname.replace(`/${options.root}`, "/") : url.pathname; - let pathname = posixNormalize(`/${options.prefix}${path}`); - paths.push({ pathname }); + paths.push({ pathname: prefixed(path, options.prefix) }); } catch { // skip malformed URLs } } return paths; } + +/** + * Mount a path from a proxied site's sitemap under its prefix here. + * + * A site staticalized with `--base` naming the url it lives at *on this site* + * already carries the prefix in every `` — Effection publishes + * `https://frontside.com/effection/docs`, not `/docs`. Adding the prefix to + * that would ask for `/effection/effection/docs`, which is nowhere. + * + * A site that still advertises its own origin, as Interactors and Graphgen do, + * needs the prefix. So does an Effection preview, whose base is its own alias + * url. Deciding on the path rather than the origin covers all three. + */ +export function prefixed(path: string, prefix: string): string { + let mount = `/${prefix}`; + + if (path === mount || path.startsWith(`${mount}/`)) { + return posixNormalize(path); + } + + return posixNormalize(`${mount}${path}`); +}