Skip to content

fix(seo): unblock /products/us/<slug> detail pages (BUY-63952 P0) - #241

Merged
BuyWhere merged 1 commit into
mainfrom
fix/BUY-63952-us-product-detail-410
Jul 25, 2026
Merged

fix(seo): unblock /products/us/<slug> detail pages (BUY-63952 P0)#241
BuyWhere merged 1 commit into
mainfrom
fix/BUY-63952-us-product-detail-410

Conversation

@BuyWhere

Copy link
Copy Markdown
Owner

"## Problem (BUY-63952 P0)\n\nEvery US product detail URL at /products/us/<slug> returned HTTP 410 Gone (verified: https://buywhere.ai/products/us/asus-rog-zephyrus-g16 → 410, lenovo-legion-pro-5i → 410). This broke the search → product → buy funnel: inbound Google-indexed US product URLs and internal related-product links were all dead.\n\n## Root cause\n\nsrc/middleware.ts hard-410'd every single-segment /products/us/<slug> URL:\n\nts\n// Dead US product slug pages — same thin-content issue (BUY-40757)\nif (normalizedForDead.startsWith(\"/products/us/\")) {\n const afterUsPrefix = normalizedForDead.slice(\"/products/us/\".length);\n if (afterUsPrefix.split(\"/\").filter(Boolean).length <= 1) {\n return new NextResponse(null, { status: 410, ... });\n }\n}\n\n\nThis was an old SEO decision (BUY-40757) to de-index thin-content pages. But the single-segment route (src/app/products/us/[slug]/page.tsx) now SSR-renders real content — it resolves the product from the -<id> slug suffix via resolveUSProductRoute and renders USProductDetail + fetchUSProductSSR (live price comparison), falling back to notFound() (404) for genuinely unknown slugs. So the 410 was suppressing a functional page.\n\nNote: the QA report's claim that search-result cards link to /products/us/<slug> is inaccurateSearchResultsClient.tsx links directly to affiliate/merchant URLs. The real exposure is (a) Google-indexed legacy URLs and (b) internal links from USProductDetail (related products) and ProductCard (share actions).\n\n## Fix\n\nStop 410'ing US single-segment slugs; let the page render. This mirrors the existing /about decision (BUY-58440): let the page render real content + metadata so Google can index it, instead of suppressing with a 410.\n\n- SG single-segment slugs stay 410'd — their page is still client-only thin content (the original rationale still holds; out of scope here).\n- The 2-segment canonical /products/us/<merchant>/<id> is untouched and remains the sitemap canonical.\n\n## Verification\n\n- tsc --noEmit: 0 new errors (197 pre-existing on clean main, unchanged). src/middleware.ts clean.\n- Logic harness confirming before/after path-classification (all assertions PASS):\n | Path | before | after |\n |---|---|---|\n | /products/us/asus-rog-zephyrus-g16 | 410 | pass→page |\n | /products/us/asus-rog-zephyrus-g16/ (trailing slash) | 410 | pass→page |\n | /products/us/<name>-<id> (real id-suffix form) | 410 | pass→page |\n | /products/us/amazon/123 (2-seg canonical) | pass→page | pass→page (unchanged) |\n | /products/sg/some-dead-slug (SG) | 410 | 410 (unchanged) |\n- getUSProducts() degrades gracefully (returns [] on API failure → page returns 404, not 500), so no risk of trading a 410 for a 500.\n- Could not run the full next dev middleware in this sandbox (EvalError: Code generation from strings disallowed — edge-runtime eval blocked by the Paperclip sandbox, affects all routes including /). Logic-level verification above covers the change; post-merge prod curl will confirm the 410 is gone.\n\n## Post-merge check\n\nbash\ncurl -s -o /dev/null -w \"%{http_code}\\n\" https://buywhere.ai/products/us/asus-rog-zephyrus-g16\n# expect: NOT 410 (200 real content for known product, 404 for unknown)\n\n\n🤖 Generated with Claude Code\n"

The middleware hard-410'd every single-segment US product URL
(/products/us/<slug>) per the old BUY-40757 thin-content de-index, but
that page route now SSR-renders a real price-comparison page and falls
back to notFound() (404) for unknown slugs. The blanket 410 left every
inbound Google-indexed US product URL and every internal related-product
link dead, so all US product detail pages read as "410 Gone" and broke
the search → product → buy funnel (BUY-63952).

Stop 410'ing US single-segment slugs and let the page render, mirroring
the /about decision (BUY-58440). SG single-segment slugs stay 410'd
(their page is still client-only thin content) and the richer 2-segment
canonical (/products/us/<merchant>/<id>) is untouched and remains the
sitemap canonical.

Co-Authored-By: Claude <noreply@anthropic.com>
@BuyWhere
BuyWhere merged commit 0e8b579 into main Jul 25, 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