fix(seo): unblock /products/us/<slug> detail pages (BUY-63952 P0) - #241
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
"## 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.tshard-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 viaresolveUSProductRouteand rendersUSProductDetail+fetchUSProductSSR(live price comparison), falling back tonotFound()(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 inaccurate —SearchResultsClient.tsxlinks directly to affiliate/merchant URLs. The real exposure is (a) Google-indexed legacy URLs and (b) internal links fromUSProductDetail(related products) andProductCard(share actions).\n\n## Fix\n\nStop 410'ing US single-segment slugs; let the page render. This mirrors the existing/aboutdecision (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 cleanmain, unchanged).src/middleware.tsclean.\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 fullnext devmiddleware in this sandbox (EvalError: Code generation from strings disallowed— edge-runtimeevalblocked 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"