The bookmakerOddsComparison widget renders a per-event 1x2 odds-comparison table across multiple bookmaker brands, served from the per-event snapshot pre-aggregated by the odds-pipeline-worker. Each row is a clickable affiliate link (/go/<cloakedLink>) wrapping logo + brand name + the 1 / X / 2 price cells.
Key features:
configid (recommended), or pass the config inline as a configuration JSON. configid takes precedence — see below.team / league doc is linked to its odds entity; otherwise the canonical name shows and no logo is used.eventsubtitle / competitionsubtitle attributes, surfaced as meta.eventSubtitle / meta.competitionSubtitle.<a> to the brand’s cloaked tracking link. Optional widget-level CTA button via ctakey / ctatext.tlTarget): switch between the default Vulcan cloaked links and the RBO legacy-id links without changing anything else.market): 1x2 (1 / X / 2 columns) or a tournament outright (one column per outcome – e.g. World Cup Winner) set via the market field in the config. See the Outright section at the bottom of this page.Whichever config approach you use, the display / behaviour attributes — CTA (ctakey / ctatext), ctacolors / ctahovercolors, tlTarget, rel, target, anchorid, eventsubtitle, competitionsubtitle, country, language — always live as top-level attributes on the tag, never inside the configuration JSON. (rel and target control the affiliate anchors. rel accepts only nofollow or follow — any other value, or omitted, becomes nofollow. target accepts a standard anchor target such as _blank or _self — any other value, or omitted, becomes _blank.)
configid vs configurationThere are two ways to give the widget its event + brands, and configid takes precedence over configuration — if both are present, configid wins and configuration is ignored:
| Approach | Where the config lives | Use when |
|---|---|---|
configid (recommended) |
A Sanity Bookmaker Odds config document, referenced by its slug. internalEventId, market, brands, title, subtitle are loaded from Sanity at render time. |
Editorial-managed placements — editors curate the event + brands in Sanity; the page only carries the slug. |
configuration (inline / legacy) |
A JSON object on the tag: internalEventId, market, brands, and optional title / subtitle. |
Ad-hoc / hard-coded placements, or where no Sanity config document exists. |
⚠️ Precedence, and no silent fallback. When
configidis present the widget resolves it from Sanity and does not fall back toconfiguration. Aconfigidthat doesn’t resolve renders a clear error (so a wrong slug is obvious) rather than quietly using an inline config. Use one approach per widget.
Localized names + logos are automatic — no attribute needed. When the event’s teams / competition are linked to their odds entity in Sanity (with translations / images), names render localized for the
language/countrylocale and logos become available to the layout; otherwise the widget falls back to the canonical name with no logo.
configid (recommended)The recommended setup, shown first: the event + brands + title / subtitle live in the referenced Sanity Bookmaker Odds document; the tag carries the configid slug plus every top-level display attribute. This is a live widget (the referenced config exists in this environment).
configurationThe same widget with the inline configuration JSON instead of a configid, so every config field is visible on the tag. If both configid and configuration are present, configid wins and this JSON is ignored.
tlTarget + per-brand legacyId)The tlTarget top-level attribute controls how every affiliate link in the widget (brand logo, each odds cell, and the BET NOW button) is built:
tlTarget |
Link form | Notes |
|---|---|---|
vulcan (default) |
/go/<cloakedLink>?country=…&language=…&wid=… |
Standard Vulcan cloaked-link strategy. Used when tlTarget is omitted. |
rbo |
/go/<legacyId>.html |
RBO legacy strategy. Uses each brand’s legacyId; no query params are appended. |
RBO, Rbo, rbo all work) and any unrecognized value falls back to vulcan.rbo, each brand’s legacyId is read from the brands[] entry in the configuration JSON (it falls back to the brand’s Sanity reference legacyId when omitted). If no legacyId can be resolved for a brand, that link safely falls back to the Vulcan form.legacyId is ignored when tlTarget is vulcan, so it is harmless to always include it.tlTarget="rbo")Set tlTarget="rbo" and provide a legacyId for each brand. Every affiliate link in the widget (brand logo, odds cells, and the BET NOW button) is then built as /go/<legacyId>.html instead of the Vulcan /go/<cloakedLink> form.
market: "outright")The same bookmakerOddsComparison widget renders a tournament outright (e.g. World Cup Winner) when market is set to "outright" in the configuration JSON. Instead of fixed 1 / X / 2 columns, each brand row shows that bookmaker’s price for every outcome (one cell per selection – the competing teams or nations), served from the outright snapshot pre-aggregated by the odds-pipeline-worker.
Everything else is identical to the 1x2 market: brands, title / subtitle, ctakey / ctatext, tlTarget, and per-brand legacyId all behave exactly the same. Only two fields differ from the examples above – market is "outright" and internalEventId points at an outright event.
Note: Delasport does not offer outright markets, so these examples use Altenar- and Bahigo-backed brands. A configured brand with no outright price for the event is simply hidden, the same inactive-row behaviour as the 1x2 market.
tlTarget="rbo")Set tlTarget="rbo" and provide a legacyId for each brand. Every affiliate link in the outright table – the brand-logo column headers, every odds cell, and the footer BET NOW buttons – is then built as /go/<legacyId>.html instead of the Vulcan /go/<cloakedLink> form.