From c4b6d118bb70cd63bd5e6b056a4a4bd024af8e36 Mon Sep 17 00:00:00 2001 From: Florent Tapponnier Date: Fri, 26 Jun 2026 17:32:53 +0200 Subject: [PATCH] fix(seo): filter unresolvable compare pairs out of search index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #749 stopped /compare from rendering pairs where either provider is unresolved (e.g. jupiter-vs-raydium), but the search index built in buildSearchIndex iterated COMPARE_PAIRS directly. Ahrefs crawls the embedded JSON and flagged /compare → /compare/jupiter-vs-raydium as a dead internal link. Same getProvider() probe as /compare/page.tsx, so the two surfaces stay in lockstep. --- src/lib/search/buildIndex.ts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/lib/search/buildIndex.ts b/src/lib/search/buildIndex.ts index fcd00793..fd5b03a3 100644 --- a/src/lib/search/buildIndex.ts +++ b/src/lib/search/buildIndex.ts @@ -17,7 +17,7 @@ import { loadAllAnswers } from "@/lib/answers"; import { CHAINS } from "@/lib/chains"; import { COMPARE_PAIRS } from "@/data/compare-pairs"; import { PROVIDER_REGISTRY } from "@/data/provider-registry"; -import { canonicalize } from "@/lib/providers"; +import { canonicalize, getProvider } from "@/lib/providers"; import type { SearchItem } from "@/lib/search/types"; /** @@ -221,7 +221,23 @@ export const buildSearchIndex = cache(async function buildSearchIndex(): Promise } // ── Compare pairs ─────────────────────────────────────────────── - for (const pair of COMPARE_PAIRS) { + // Mirror the filter applied by /compare/page.tsx: skip pairs where + // either side is unresolved (provider deregistered, never imported, + // or hex-blacklisted). Without this the search index keeps surfacing + // jupiter-vs-raydium et al even after the compare page itself stops + // rendering them, and Google / Ahrefs flag the embedded JSON as a + // dead internal link. + const resolvedPairs = await Promise.all( + COMPARE_PAIRS.map(async (pair) => { + const [a, b] = await Promise.all([ + getProvider(pair.providerA), + getProvider(pair.providerB), + ]); + return a && b ? pair : null; + }), + ); + for (const pair of resolvedPairs) { + if (!pair) continue; const a = providerNameFor(pair.providerA); const b = providerNameFor(pair.providerB); items.push({