From 750d789fb5d6ad40eef773e6d9c9ac3ed69b1ae9 Mon Sep 17 00:00:00 2001 From: 0xkkonrad Date: Wed, 26 Aug 2026 17:36:47 +0000 Subject: [PATCH] hotfix(seo): crawl-allow /invite?invited_by= like /invite?code= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit peanut-ui emits /invite?invited_by= once #2828 lands (?code= stays a read alias). GOOGLE_DEINDEX_CRAWL_ALLOW_PATHS only listed the ?code= variant, so the new shape would be Disallowed in robots.txt and Google could never observe its X-Robots-Tag noindex — the exact URL-only indexing problem this exception exists for. Policy lives on main only, so this ships as a hotfix. --- src/constants/__tests__/seo-route-policy.test.ts | 16 ++++++++++------ src/constants/seo-route-policy.js | 4 +++- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/constants/__tests__/seo-route-policy.test.ts b/src/constants/__tests__/seo-route-policy.test.ts index 034e12ce63..4a314ee6ff 100644 --- a/src/constants/__tests__/seo-route-policy.test.ts +++ b/src/constants/__tests__/seo-route-policy.test.ts @@ -74,12 +74,15 @@ describe('SEO route policy', () => { expect(receivesNoindexHeader(route)).toBe(false) }) - it.each(['/home', '/home/activity', '/invite?code=abc&lid=campaign', '/api/og?type=send&username=alice&amount=10'])( - 'renders a noindex header for %s through Next route matching', - async (route) => { - await expect(renderedRobotsHeader(route)).resolves.toBe('noindex, nofollow') - } - ) + it.each([ + '/home', + '/home/activity', + '/invite?code=abc&lid=campaign', + '/invite?invited_by=abc', + '/api/og?type=send&username=alice&amount=10', + ])('renders a noindex header for %s through Next route matching', async (route) => { + await expect(renderedRobotsHeader(route)).resolves.toBe('noindex, nofollow') + }) it.each(['/lp', '/api/og/marketing?title=Peanut', '/m/stain', '/en/pay-with/pix'])( 'does not render a noindex header for %s through Next route matching', @@ -107,6 +110,7 @@ describe('SEO route policy', () => { '/setup$', '/invite$', '/invite?code=', + '/invite?invited_by=', ]) }) }) diff --git a/src/constants/seo-route-policy.js b/src/constants/seo-route-policy.js index ad72ca4da8..63565c3f72 100644 --- a/src/constants/seo-route-policy.js +++ b/src/constants/seo-route-policy.js @@ -77,7 +77,8 @@ const ROBOTS_DISALLOWED_PATHS = Object.freeze([ '/withdraw', ]) -// GSC shows these exact shells (or their invite query variants) in Google's +// GSC shows these exact shells (or their invite query variants — ?invited_by= +// is what peanut-ui emits since ui#2828, ?code= the legacy alias) in Google's // index. They need a narrow crawl exception so search engines can observe and // refresh the X-Robots-Tag. Descendant transaction/profile URLs remain // blocked. Keep the exceptions while these routes exist; only remove one once @@ -89,6 +90,7 @@ const GOOGLE_DEINDEX_CRAWL_ALLOW_PATHS = Object.freeze([ '/setup$', '/invite$', '/invite?code=', + '/invite?invited_by=', ]) const NOINDEX_HEADER = Object.freeze({ key: 'X-Robots-Tag', value: 'noindex, nofollow' })