From 11c01b80d5fb2e42f769a6b306f61116d7dba158 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 4 Jul 2026 14:10:20 +0000 Subject: [PATCH 1/2] docs(hutch): record homepage A/B noindex + canonical=/ as intentional defence-in-depth The server-side isbot gate already keeps crawlers on the control `/` and off the A/B arms, so the arms' `noindex` paired with `canonical=/` reads as redundant. Note that the redundancy is deliberate belt-and-suspenders so a future reader does not strip one half. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01Sfj512E2zhVqMoHpwTewdg --- projects/hutch/src/runtime/web/pages/home/home.component.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/hutch/src/runtime/web/pages/home/home.component.ts b/projects/hutch/src/runtime/web/pages/home/home.component.ts index 994afee70..fe9447666 100644 --- a/projects/hutch/src/runtime/web/pages/home/home.component.ts +++ b/projects/hutch/src/runtime/web/pages/home/home.component.ts @@ -75,6 +75,7 @@ export function HomePage(params: HomePageParams): PageBody { ogType: "website", // The A/B arms are noindex so only the canonical `/` competes for SEO; // the canonical above stays on `/` for all three renders. + // Defence-in-depth: the isbot gate already keeps crawlers off the arms, so pairing noindex with canonical=`/` here is deliberately redundant — don't remove either half. robots: variant ? "noindex, follow" : "index, follow", ogImage: `${staticBaseUrl}/og-image-1200x630.png`, ogImageType: "image/png", From a8399344d2305ae2e2a1ff4f7d63e0ee8b4b5c5e Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Sun, 5 Jul 2026 07:21:28 +0000 Subject: [PATCH 2/2] docs(hutch): clarify homepage A/B noindex complements the isbot gate, not redundant The prior comment called the arm noindex + canonical=/ pairing "deliberately redundant" with the server-side isbot gate. They cover different paths: the isbot gate only keeps crawlers off the arms reached via the client redirect from `/`, while a direct hit to a `/landing-*` URL is not bot-gated and not disallowed in robots.txt, so there the arm noindex is the sole guard. Call them complementary so a future reader does not drop the noindex assuming the isbot gate already covers it. Co-authored-by: Fayner Brack Co-Authored-By: Claude Opus 4.8 (1M context) --- .../hutch/src/runtime/web/pages/home/home.component.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/projects/hutch/src/runtime/web/pages/home/home.component.ts b/projects/hutch/src/runtime/web/pages/home/home.component.ts index fe9447666..e2f5a05da 100644 --- a/projects/hutch/src/runtime/web/pages/home/home.component.ts +++ b/projects/hutch/src/runtime/web/pages/home/home.component.ts @@ -73,9 +73,11 @@ export function HomePage(params: HomePageParams): PageBody { "The read-it-later app and online reader for distraction-free reading — save any article or web page in one click and read it later in a clean reader view. A privacy-first Pocket alternative with real Tesseract OCR for scanned PDFs (no LLM hallucination). Read the Web, not the Slop.", canonicalUrl: "https://readplace.com", ogType: "website", - // The A/B arms are noindex so only the canonical `/` competes for SEO; - // the canonical above stays on `/` for all three renders. - // Defence-in-depth: the isbot gate already keeps crawlers off the arms, so pairing noindex with canonical=`/` here is deliberately redundant — don't remove either half. + // The A/B arms render `noindex` with canonical=`/`, so only the canonical `/` competes for + // SEO across all three renders. This is defence-in-depth, not redundancy: the isbot gate on + // `/` only keeps crawlers off the arms they'd reach via the client redirect. A direct hit to + // a `/landing-*` URL is not bot-gated and not disallowed in robots.txt, so on that path the + // arm's own noindex + canonical=`/` are the only guard. Don't remove either half. robots: variant ? "noindex, follow" : "index, follow", ogImage: `${staticBaseUrl}/og-image-1200x630.png`, ogImageType: "image/png",