SEO remediation (Ahrefs 2026-07-30): site-wide Open Graph + ranking recovery - #226
Merged
Conversation
From the 2026-07-30 Ahrefs crawl. Clears both Errors and ~578 Warnings. - og:type + og:site_name in headTags. Docusaurus emits og:title/description/ image/url/locale but neither of these, so all 573 indexable pages failed Open Graph validation. Verified: 1019 built pages now carry both (the 245 without are client-redirect stubs, which correctly have no OG block). - Sitemap listed /crypto-reward-tax-calculator/ with a trailing slash. That path is a separate Next.js app whose normalization 308s to the unslashed form, so we were publishing a redirect in our own sitemap. - Two http:// internal links -> https: the v1 link on Pump-Fun-API (which alone tripped 4 separate reports) and both support.bitquery.io links on how-to-filter-anomaly-prices. - alt text on 4 images, written from the actual screenshots. - Polymarket generated-index retitled. This index, not its child page, is what ranks (position 2 for "polymarket api", 863 organic). Google was discarding "Polymarket Implementation Guide" and substituting the child page's title, so lead with the head term. Description was 95 chars. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…lize Pumpfun
Phase 2 of the 2026-07-30 Ahrefs remediation. Covers the 9 pages that lost
rankings. All 9 verified technically clean first (200, self-canonical, no
noindex), so these are content and internal-linking problems, not indexation.
Every documented query was run against the live API before being written.
matic-dextrades (1267 -> 1892 words)
- Added the archive/history section the page already promised: the callout
routed readers here for data older than the Trading window "with
dataset: combined or archive", but `dataset` appeared nowhere else in the
file. Verified dataset: archive returns 2025-01-01 trades.
- Added OHLC via Trading.Tokens (Interval.Time.Duration).
- Replaced both example tokens. AVAX (~$10k/30d) and IXT (~$427/30d, ~$0.19
per trade) were effectively dead; now WPOL/USDC and WETH.
- Replaced hardcoded 2024-11-13 / 2024-11-10 variables with since_relative.
Copy-pasting the old top-gainers query requested a ~20-month window.
- Documented the MATIC->POL rebrand (wrapped native now reports WPOL, Tether
as USDT0) and to filter by contract, not symbol.
- Documented Fungible: true, without which Polymarket ERC-1155 outcome tokens
dominate any Polygon volume ranking with empty symbols.
usdt-trc20-api (650 -> 1689 words, 0 -> 2 inlinks)
- Retitled from "Tron Usdt Trc20 API"; H1 now matches the title.
- Replaced the top-100-holders query: it fails server-side
("upstream: tron: backend ... context deadline exceeded") after 3 min, under
a heading claiming to answer the most-asked USDT question on Tron. Now uses
Balances per-address, plus Holders with an amount floor for a whale list.
Both verified. Balances is preferred over BalanceUpdates throughout.
- Documented UpdateCount as a wallet classifier: 1.2M updates in ~10 days
(exchange hot wallet) vs 5 updates on a wallet holding 87.5M USDT (cold).
- Added whale transfers, top receivers, and a single-request cross-chain
comparison across Tron/Ethereum/BSC/Polygon.
- Kept cross-chain depth on stablecoin-APIs/usdt-api rather than duplicating
it here; added reciprocal links.
Pumpfun cluster
- Assigned keyword ownership per page. Pump-Fun-API had no keywords at all
while the hub claimed "Best PumpFun API", and pump-fun-to-pump-swap -- the
page hoarding four terms it should not own -- was the only page in the
cluster that ranked. All five descriptions were near-duplicates; now
distinct. Added a "which page do I need" router to the hub.
- Trading API callout kept at the top on all pages, reframed as a positive
router instead of reading as "do not use this page".
solana_dexscreener
- Fixed unparseable JSON in the pair-stats variables ('""So111...' and an
unterminated "pair_address key). Copy-paste failed outright.
- Replaced 2024-08-15 / 2024-11-06 dates with since_relative/after_relative.
- Replaced three dead example mints (BILLY 12 trades/30d, AUTISM 9, Pnut 1)
with the WSOL/USDC Orca Whirlpool, and documented why: memecoin pools decay
within hours (one candidate went 34,325 trades/2h to 28 trades/1h while
being tested), and aggregators like Jupiter expose no MarketAddress.
erc20-token-transfer-api: de-templated description, added keywords.
No action, with reasons:
- BSC/four-meme-api: no payload problem. It ships 42 KB gzipped; the 728 KB
figure was uncompressed DOM, and peers are larger (solana-dextrades 892 KB).
- BSC/pancake-swap-api: already has 6 in-repo inlinks, not 3.
- start/errors: no commercial intent.
Not documented: Holders aggregate stats (sum/median/gini/nakamoto) returned
total: 0 and median: 0 on a token whose top holder has 18M. Needs API-team
confirmation before use.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ueries
Deprecated-cube cleanup, driven by live schema introspection rather than
find-and-replace. The schema's own deprecationReason strings are the source
of truth here.
State verified against the live API on 2026-07-30:
- EVM.TokenHolders -> BROKEN. Fails on realtime ("no table can query
TokenHolder ... consider use archive dataset") and on archive ("Database eth
does not exist"). Every documented query using it was dead.
- EVM.BalanceUpdates -> deprecated but STILL EXECUTES (returned data stamped
2026-07-30T11:38:59Z).
- Tron.BalanceUpdates -> deprecated but STILL EXECUTES.
- Solana.BalanceUpdates / InstructionBalanceUpdates -> NOT deprecated. Solana
has no Balances cube, so these are the current APIs there and must stay.
New: docs/cubes/balances-cube.md
Eight pages already tell users to use EVM.Balances, but no cube reference
documented it. Adds Balances (per-address current state) vs Holders (a token's
holders, dated snapshot), field lists, dataset guidance, a BalanceUpdates
migration mapping, and two verified gotchas:
- Balances has no amount filter (where accepts Balance.Address only), so
ranking by balance size requires Holders.
- Unbounded top-N over a very large token times out server-side. Ethereum USDT
times out even with a 50,000,000 floor; Tron USDT behaves the same.
Migrated 16 TokenHolders sites to Holders across 7 files: rwa-api, pepe-api,
token-holder-api, optimizing-graphql-queries, metrics/uniq,
stablecoin-payments-api, tokenholder-heatmap (inside an escaped-JSON payload).
The argument shape changes, not just the name: `tokenSmartContract: X` becomes
`where: { Currency: { SmartContract: { is: X } } }`. Verified by extracting a
migrated block verbatim from metrics/uniq.md and running it: 1,378,728 exact
holders returned.
balance-updates-cube.md had no deprecation notice at all despite documenting a
cube deprecated on EVM and Tron. Added one that also states why the page is
still the right reference: Solana, and change attribution -- Balances gives the
resulting amount but only BalanceUpdates exposes Type (transfer / fee /
block_reward) per change.
Corrected stale prose on token-holder-api.mdx that offered the "legacy
TokenHolders cube" as a working option for distribution metrics.
Not migrated, deliberately:
- NFT ownership queries (nft-ownership-api, nft-api, nft-collection-api,
nft-scanner, cross-chain, nft-creator). Balances CANNOT express per-token-ID
ownership: its filter accepts Address only, there is no Id field, and NFT
collections return Amount: "0" aggregate rows. These need BalanceUpdates
(which exposes BalanceUpdate.Id) or Transfers.
- graphql-reference/objects/evm.mdx: auto-generated schema reference.
- Solana pages: current API.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
buddies2705
added a commit
that referenced
this pull request
Jul 30, 2026
…it-fixes SEO Phase 3/4 + fix broken Holders queries shipped in #226
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.
Remediation of the 2026-07-30 Ahrefs Site Audit of
docs.bitquery.io.Two phases in one branch — reviewable as two independent commits:
4985eac4e1039686Correcting the export's headline numbers first
The CSVs are UTF-16/TSV with newlines inside multi-value cells, so
wc -loverstates record counts ~9×. "5,157 Open Graph issues" is 573; "3,604 IndexNow" is 572. Real totals collapse to three root causes, only one of which is in this repo.Phase 1 — config + mechanical
og:type+og:site_nameinheadTags. Docusaurus emitsog:title/description/image/url/localeand neither of these, so all 573 indexable pages failed Open Graph validation. One config change. Verified: 1019 built pages carry both; the 245 without are client-redirect stubs, which correctly have no OG block.createSitemapItemshardcoded/crypto-reward-tax-calculator/with a trailing slash; that path is a separate Next.js app whose normalization 308s to the unslashed form.http://internal links →https. The v1 link onPump-Fun-APIalone tripped 4 separate reports. Bothsupport.bitquery.iolinks onhow-to-filter-anomaly-prices(two occurrences, not one).generated-indexretitled. This index — not its child page — is what ranks (position 2 forpolymarket api, 863 organic). Google was discarding "Polymarket Implementation Guide" and substituting the child page's title verbatim. Description was 95 chars.Phase 2 — ranking recovery
All 9 pages verified technically clean first (200, self-canonical, no
noindex), so these are content and internal-linking problems, not indexation. Every documented query was run against the live API before being written.Defects found by reading the pages, absent from the Ahrefs export
solana_dexscreenershipped unparseable JSON —""So111…(doubled quote) and an unterminated"pair_addresskey. Copy-paste failed outright.matic-dextradespromised what it never delivered — the callout routed readers there for history "withdataset: combinedorarchive" whiledatasetappeared nowhere else in the file.upstream: tron: backend … context deadline exceededafter 3 minutes, under a heading claiming to answer the most-asked USDT question on Tron.$10k/30d), IXT ($427/30d), BILLY (12 trades/30d), AUTISM (9), Pnut (1).2024-08-15,2024-11-06,2024-11-13) — copy-pasting requested a ~20-month window. Nowsince_relative.Pump-Fun-APIhad nokeywordsat all while the hub claimed "Best PumpFun API", andpump-fun-to-pump-swap, the page hoarding four terms it shouldn't own, was the only page in the cluster that ranked.Two items where my own analysis was wrong
four-meme-apihas no payload problem. It ships 42 KB gzipped; the 728 KB I flagged was uncompressed DOM, and peers are larger (solana-dextrades892 KB). Ahrefs' "Size (bytes) 42372" was already the compressed figure.pancake-swap-apiinlinks were understated — 6 in-repo references, not 3. No action taken rather than adding decorative links.Also documented
WPOL, Tether asUSDT0— filter by contract, not symbol.Fungible: trueon Polygon rankings, or Polymarket ERC-1155 outcome tokens dominate with empty symbols.UpdateCountas a wallet classifier: 1.2M updates in ~10 days (exchange hot wallet) vs 5 on a wallet holding 87.5M USDT (cold storage).MarketAddress.Balancespreferred overBalanceUpdatesthroughout.Verification
yarn buildpasses; build output confirmed to reflect the changes (not a cache hit)scripts/check-links.mjs: no link errors (532 pages, 1294 routes, strict)/docslinks in changed files resolveDeliberately not in this PR
/v1/**page emitscanonical → /v1/, plus one shared 108-char title and one shared description across all 409, and double-fired GA4. Separate deployment — needs a handoff to that repo. Ourrobots.txtshould not declare/v1/sitemap.xmluntil that canonical is fixed.crypto-reward-tax-calculator— no OG, no X card, zero outlinks. Separate Next.js app.twitter:site— omitted rather than guess a live social handle.Open items
Holdersaggregate stats (sum/median/gini/nakamoto) returnedtotal: 0andmedian: 0on a token whose top holder has 18M. Left out of the docs; worth an API-team look.BalanceUpdatesstill appears in ~70 docs files.🤖 Generated with Claude Code