Markets widget is a front end visualization of a market list that is personalized and sorted in order of the most relevant markets. The widget sorts the markets based on their popularity and the punters betting history. It simplifies the process of finding the right betting opportunities from the myriad of possible choices and boosts betting volume for both upcoming and live events.
Recommendation types
Personalization requirement
To enable personalized recommendations (the recommended type), you must provide a unique user identifier. When no user ID is provided, the widget will fall back to popular recommendations.
Personalized AI-powered list of relevant markets tailored to individual punter preferences.
Full support for real-time in-play betting and upcoming pre-match event opportunities.
Advanced support for sophisticated layout configurations with more than three outcomes per market.
Adaptive layout that automatically recalibrates for flawless desktop and mobile experiences.
Interactive onItemClick callbacks for seamless bet slip and site-wide navigation handling.
Extensive customization and CSS styling options to perfectly match your platform's visual identity.
Integrate on landing, sport, or tournament pages to surface high-relevance markets across matches.
Embed directly on specific match pages to prioritize the most valuable markets for that event.
Ideal for high-traffic entry points where users need immediate access to popular betting options.
Dynamically adapts between multi-event summaries and deep-dive single event market focuses.
Access to the client API
Required endpoints: User IDs, Odds, Event info, Market and Outcome ID mapping (for custom layouts)
If IDs are not mapped, outcomes fall back to a single-column layout
Requires an adapter to be registered via SIR('registerAdapter', '{ADAPTER_NAME}'). See the adapter overview: https://apidocs.sportradar.online/resources/widgets/docs/adapter/Overview
widget-name: betRecommendation.markets
Environment Requirements
| Browser | Version | Mobile Support |
|---|---|---|
| Chrome | 60+ | ✅ Chrome Mobile 60+ |
| Firefox | 55+ | ✅ Firefox Mobile 55+ |
| Safari | 12+ | ✅ iOS Safari 12+ |
| Edge | 79+ | ✅ Edge Mobile 79+ |
| Internet Explorer | All versions | ❌ Not Supported |
Supported Sports
See the Markets widget demo. Illustrations of main recommendation types and display modes with relevant property values below.

Multiple recommended markets from one match with outcomes and odds.
| Property | Type | Default | Description |
|---|---|---|---|
user | string|number | 0 | User identifier for personalized market recommendations. |
count | number | 3 | Number of markets to return (1-100). |
eventId | string|number | undefined | Event identifier for single-event mode. |
enableCollapseExpand | boolean | false |
Extended Properties
| Property | Type | Default | Description |
|---|---|---|---|
filters | object | Required | Configuration object for recommendation type, sports, time, and leagues. See below for detailed structure. |
The filters object controls recommendation algorithm, time windows, sports, and leagues.
Filters Property Details
| Property | Type | Default | Description |
|---|---|---|---|
recommendationType |
Theming customization allows to tailor the appearance of Bet Recommendation widgets to meet specific needs and preferences. In the context of the Bet Recommendation widget, customization refers to the ability to modify the default styling of the widget by applying custom CSS properties to the various HTML elements that make up the widget.
Widget comes with pre-existing styling but can be customized by applying custom CSS properties to its different HTML elements. The widget's custom class selectors and supported CSS properties are listed below.
All custom classes must be nested within the .sr-bb.sr-br-markets selector class. This ensures that the custom styles only apply to that widget and not to other elements on the page.
| CSS class | Supported CSS properties |
|---|---|
srct-br-container | background-color, font-family, border-radius, border-style, border-width, border-color, padding |
srct-br-header | background-color, color, border-radius, font-style, border-style, border-width, border-color, padding |
srct-br-eventinfo__icon | color |
srct-br-scoreboard__teams | font-size, color |
srct-br-eventinfo | font-size, color |
srct-br-eventinfo__status | font-size, color |
Mandatory Configuration
The filters property is required for this widget to function correctly. It defines the recommendation logic and basic data constraints.

Demo: Open demo
The onItemClick callback is fired whenever the user interacts with the widget. The first argument is a target string that identifies the interaction type; the second argument is a data object containing contextual information.
target value | Trigger | Key data properties |
|---|---|---|
"externalOutcome" | User clicks a single outcome button | externalEvent, externalMarket, externalOutcome |
"externalOutcomes" | User clicks multiple outcomes at once (e.g. combo card) | Array of { externalEvent, externalMarket, externalOutcome } |
"externalEvent" | User clicks an event header/card | externalEvent |
"externalCompetition" | User clicks a competition/league name |
Note: Widgets support callbacks on outcome clicks — the onItemClick handler receives target === "outcome" and a data object containing externalEvent, externalMarket and externalOutcome. Use this for custom outcome callbacks (e.g., add-to-betslip, analytics, modals).
The widget also exposes onTrack for event tracking analytics. See the tracking guide for details.
To keep the widget's selected-outcome state in sync with your own bet slip (i.e. show outcomes as selected when they were added outside the widget), use registerOnBetSlipChange inside registerAdapter.
// 1. Track your bet slip state
let changeCallback;
let betSlipState = { betslip: [], combinedOddsValue: undefined };
// 2. Notify the widget whenever the bet slip changes
function onBetSlipChanged
An adapter is a software component developed by the Sportradar engineering team that bridges the Bet Recommendation widgets and your platform's API. It retrieves data from your API and feeds it to the widget, ensuring seamless communication between the two systems.
Before adapter development begins, confirm and align your API contract with the Sportradar engineering team. Integration requires two SIR calls:
| SIR method | Purpose |
|---|---|
SIR('registerAdapter', ...) | Configure the adapter that retrieves and displays data from your API. |
SIR('addWidget', ...) | Mount the widget on the page. |
(function
The following data types are provided by the adapter and are also available in the onItemClick callback payload.
Event
| Property | Type | Required | Description |
|---|---|---|---|
id | string | number | Yes | Sportradar event ID. |
externalId | string | number | — | Client-side event ID. |
date | string | Yes | Formatted date string displayed in the widget. |
The widget reacts to market and outcome status changes as follows:
| Condition | Markets widget behavior |
|---|---|
Market closed (market.status.isActive: false) | Market is not displayed. |
Single outcome closed (outcome.status.isActive: false) | That outcome's selection is disabled. |
| All outcomes closed | All outcome selections are disabled. |
enableCollapseExpand is enabled, the collapsed/expanded state is maintained during the user's session but resets on page reload.| Enables collapsible/expandable sections for markets and events. |
outcomeNamePosition | string | "start" | Outcome label position: "start", "end", "top", "bottom", or "outside". |
branding.sports.icons | object | undefined | Map of Sportradar sport IDs to custom icon image paths. Overrides default sport icons. Example: { 1: 'path/to/soccer.svg', 2: 'path/to/basketball.svg' }. |
onItemClick | function | undefined | Callback for outcome or event clicks. See onItemClick reference. |
silent | boolean | false | When true, suppresses widget error messages displayed to end users. Errors are still logged internally. |
object| Required |
| Recommendation algorithm configuration. |
Recommendation Type Algorithm Options:
| Property | Type | Default | Description |
|---|---|---|---|
available | string | "recommended" | Required. recommendation algorithm to use. Options:
|
| Property | Type | Default | Description |
|---|---|---|---|
sport | object | undefined | Sport filter configuration. |
sport.available | array<string|number> | [] | Array of Sportradar sport IDs to include in recommendations. See Sports Reference. |
time | object | undefined | Time filter configuration for event scheduling. |
time.range | number | 0 | Time offset in hours from current time (0-12). 0 shows immediate/current events only. |
time.available | string | undefined | Time status filter. Options: "live" (only live/in-play events) or undefined (all events). |
league | object | undefined | League/tournament filter configuration. |
league.available | array<string|number> | undefined | Array of Sportradar tournament/league IDs to include in recommendations. When provided, only events from specified leagues generate market recommendations. See Getting Identifiers. |
{
recommendationType: {
available: 'recommended' // Personalized AI recommendations
},
sport: {
available: [1, 2, 5] // Soccer, Basketball, Tennis
},
time: {
range: 3, // Next 3 hours
available: 'live' // Only live events
},
league: {
available: [
'sr:tournament:17', // Premier League
'sr:tournament:132' // NBA
]
}
}srct-br-eventinfo__time |
font-size, color |
srct-br-content | background-color, border-style, border-width, border-color, padding |
srct-br-market__name | font-size, color, background-color, border-radius, border-style, border-width, border-color, padding |
srct-br-outcomes | background-color, border-radius, border-style, border-width, border-color, padding |
srct-br-outcome | background-color, color, border-radius, border-style, border-width, border-color, padding |
srct-br-outcome__name | font-size, color |
srct-br-outcome__value | font-size, color |
Basic multi-event popular markets for anonymous users.
JavaScript
SIR("addWidget", "#markets-1", "betRecommendation.markets", {
count: 5,
filters: {
recommendationType: {
available: "popular",
},
},
});HTML (data attributes)
<div
class="sr-widget"
data-sr-widget="betRecommendation.markets"
data-count="5"
data-filters='{"recommendationType": {"available": "popular"}}'
></div>externalCompetition |
"goToBetSlip" | User clicks the "Go to Bet Slip" button (swipeBet only) | — |
"betSlipMode" | Bet slip mode changes between single and multi (swipeBet only) | value: "single" | "multi" |
SIR("addWidget", "#sr-widget", "betRecommendation.markets", {
onItemClick: function (target, data) {
if (target === "externalOutcome") {
// Add single outcome to bet slip
const { externalEvent, externalMarket, externalOutcome } = data;
betSlip.add({
eventId: externalEvent.id,
marketId: externalMarket.id,
outcomeId: externalOutcome.id,
});
} else if (target === "externalEvent") {
// Navigate to event/match detail page
window.location.href = `/matches/${data.externalEvent.id}`;
} else if (target === "externalCompetition") {
// Navigate to competition/league page
window.location.href = `/league/${data.externalCompetition.tournament.id}`;
}
},
filters: { recommendationType: { available: "popular" } },
});Until a custom adapter is developed, use the mockData adapter for local testing:
SIR("registerAdapter", "mockData", { onBetSlipChanged });sport.id | string | number | Yes | Sport ID. Use sportsMapping if not using Sportradar sport IDs. |
sport.name | string | Yes | Sport name. |
category.id | string | number | — | Category ID. |
category.name | string | Yes | Category name (e.g. "England"). |
tournament.id | string | number | — | Tournament/league ID. |
tournament.name | string | Yes | Tournament name. |
teams | Array<{id, name}> | Yes | Home and away competitors. |
isLive | boolean | Yes | Whether the event is currently live. |
liveCurrentTime | string | Yes | Live time display (e.g. "2nd set", "45'"). |
result1 / result2 / result3 | result | — | Score columns: { result: [homeScore, awayScore] }. |
Market
| Property | Type | Required | Description |
|---|---|---|---|
id | string | number | Yes | Market ID. |
name | string | — | Market name (e.g. "Match Winner"). |
status.isActive | boolean | — | When false, see Widget Behavior. |
Outcome
| Property | Type | Required | Description |
|---|---|---|---|
id | string | number | Yes | Outcome ID. |
name | string | Yes | Outcome name (e.g. "Home", "Draw"). |
odds | string | number | Yes | Odds value. Use a number type to enable odds-change indicators (up/down arrows). |
specifier.value | string | number | — | Additional specifier (e.g. handicap value "-2.50"). |
status.isActive | boolean | — | When false, see Widget Behavior. |
If your adapter only provides market-level closure data, only market-closure behavior applies. If it also provides outcome-level data, outcome-specific behavior is triggered as well.