Skip to main content

Esports Odds API — SEO Campaign Design

Date: 2026-06-11 Status: Approved (design), in implementation Author: Markus + Claude

Goal

Rank page 1 of Google for the esports-odds keyword cluster, capitalising on the 2026-06-10 platform upgrade that took esports coverage from ~70 to 550+ upcoming matches across 15 titles, added ~1s live scores, and added live scores/status over WebSocket. We currently have zero dedicated esports pages despite esports now being our strongest coverage — this is the gap.

Keyword strategy (pillar + cluster)

Bare “esports api” is contested and intent-mismatched — the incumbents (PandaScore, Abios/Sportradar, GRID) sell match/stats data, not odds. We target the intent-matched cluster instead, where competition is weak and our product fits:
PagePrimary KWSecondary KWs
/esports-odds-api (pillar)esports odds apiesports api, esports betting api, live esports odds api, esports data api
/esports/[game] (×15){game} odds api{game} betting odds api, {game} betting data

Architecture

Three page types, all reusing existing patterns — no new CMS, MDX, or redesign.

1. Pillar page — src/app/esports-odds-api/page.tsx (+ layout.tsx)

Modeled on the existing /sports-betting-api landing page (client component + layout.tsx for metadata). Richest page; main rank target for “esports odds api”. Sections: hero (550+ matches / 15 titles / ~1s scores / WebSocket), differentiators (8x coverage jump, second-level live scores, WS scores+status — moats the stats-data incumbents lack), 15-title grid linking to per-title pages, markets & live data (incl. new period keys ft/ot/ap), code example, use cases, FAQ. JSON-LD: SoftwareApplication + FAQPage + BreadcrumbSchema.

2. Programmatic per-title pages — src/app/esports/[game]/page.tsx

Mirrors the /sports/[sport] template exactly (generateStaticParams, generateMetadata, JSON-LD). Driven by a new src/utils/esportsData.ts with an EsportsTitle interface (same shape as SportData plus pandascoreSlug). 15 titles, SEO URL slug ≠ PandaScore slug:
TitleurlSlugpandascoreSlugTop leagues
Counter-Strike (CS2)cs2cs-goBLAST, ESL Pro League, IEM
Dota 2dota-2dota-2The International, Majors, PGL
League of Legendsleague-of-legendsleague-of-legendsLCK, LPL, LCS
ValorantvalorantvalorantVCT
Rainbow Six Siegerainbow-sixr6-siegeSix Invitational, Pro League
StarCraft 2starcraft-2starcraft-2GSL, DH Masters
Rocket Leaguerocket-leaguerlRLCS
LoL Wild Riftwild-riftlol-wild-riftWild Rift League
Mobile Legendsmobile-legendsmlbbM-World Championship, MPL
King of Gloryking-of-glorykogKing Pro League
EA Sports FCea-sports-fcfifaFIFAe World Cup
PUBGpubgpubgPGS, Global Invitational
OverwatchoverwatchowOWL, World Cup
StarCraft: Brood Warstarcraft-brood-warstarcraft-brood-warASL
Call of Dutycall-of-dutycod-mwCDL, Challengers
(Title + league list verified against the live PandaScore /videogames endpoint on 2026-06-10.)

3. Blog cluster — 4 Sanity posts

Informational long-tail, each linking up to the pillar:
  1. How to Build an Esports Betting App with a Real-Time Odds API
  2. The 15 Biggest Esports for Betting in 2026 (with API coverage)
  3. Live Esports Scores & Status over WebSocket: a Developer Guide
  4. Esports Betting Markets Explained: Maps, Handicaps & Live Odds
Delivered as markdown drafts under docs/blog-drafts/ for manual Sanity import (blog content lives in Sanity CMS, not the repo).

Glue

  • next-sitemap.config.js: /esports-odds-api and /esports/* at priority 0.9 / daily.
  • Homepage footer (src/app/page.tsx) + BlogFooter.tsx: add Esports API link.
  • Pillar ↔ per-title cross-links; per-title pages link to the pillar and to each other.

Out of scope (YAGNI)

No new CMS, no MDX migration, no redesign, no /v3/ API changes (so the CLAUDE.md endpoint-doc workflow does not apply). Remaining-4-titles extension and live event-count wiring deferred.

Success criteria

  • All 16 pages build via next build and render with valid metadata + JSON-LD.
  • Pages appear in sitemap.xml at priority 0.9.
  • Internal links resolve (pillar ↔ titles ↔ homepage/footer).