Betslip
A floating betslip overlay for building and submitting bets, controlled via the FuWidget.betslip API.
A floating betslip overlay that lets users build and submit a bet slip directly on your page. Unlike other widgets, the Betslip has no content ID — it works as a persistent element positioned anywhere on the screen. Selections are added and removed from your own code using the FuWidget.betslip API.
For the programmatic methods (setSelection,removeSelection,subscribe,getState), see API Reference → Betslip API.
<div
data-component="fu-widget"
data-content-type="betslip"
data-betslip-position="bottom-right"
data-betslip-currency="USD"
data-betslip-max-selections="10"
data-betslip-stake-presets="5,10,20,50"
data-betslip-operator-id="betano-bg"
data-betslip-affiliate-id="your-affiliate-id"
data-betslip-branding-logo-url="https://example.com/brand-logo.png"
></div>
Nodata-betslip-cta-url-templateis needed: the place-bet button uses the operator's own betslip deep link, which lands the user on a pre-filled slip at the bookmaker. Set the template only when the CTA must go somewhere else.
Configuration Attributes
| Attribute | Description | Options/Format | Default |
|---|---|---|---|
data-betslip-position | Where the betslip appears on the page | "bottom-right", "bottom-left", "top-right", "top-left", "side-right", "side-left" | Global config |
data-betslip-max-selections | Maximum number of selections the user can add | Positive integer | Global config |
data-betslip-stake-presets | Comma-separated quick-stake amounts | e.g. "5,10,20,50" | Global config |
data-betslip-odds-polling-interval | How often to refresh odds, in milliseconds | e.g. 5000 for every 5 seconds | Global config |
data-betslip-currency | Currency label shown for stake and potential winnings | Any string, e.g. "USD", "EUR", "GBP" | Global config |
data-betslip-cta-url-template | URL for the place-bet CTA button | URL string, use {selectionIds} as a placeholder for selection IDs | Global config |
data-betslip-branding-logo-url | Bookmaker or sponsor logo displayed in the widget | Valid image URL | Global config |
data-betslip-operator-id | Bookmaker to pin the betslip to (operator config id) | Operator config id, e.g. "betano-bg" (see below) | Global config |
data-betslip-affiliate-id | Affiliate id used to attribute CTA clicks to you | Any string, e.g. "your-affiliate-id" | Global config |
data-betslip-labels | JSON object to override any displayed text | BetslipLabels object (see below) | Global config |
No Content ID Required
The Betslip is the only widget type that does not require a content id. When using loadWidget(), simply omit the id field:
FuWidget.loadWidget({
apiKey: "your-api-key",
clientId: "your-client-id",
configId: "your-config-id",
contents: [
{
type: "betslip", // No id needed
container: "betslip-container",
},
],
configOverrides: {
betslip: {
position: "bottom-right",
currency: "EUR",
maxSelections: 8,
},
},
});<div id="betslip-container"></div>Global Configuration
Set defaults for all Betslip widgets in FuWidget.init():
FuWidget.init({
// ... other config
betslip: {
position: "bottom-right",
maxSelections: 10,
stakePresets: [5, 10, 20, 50],
oddsPollingInterval: 5000,
currency: "USD",
ctaUrlTemplate: "https://bookmaker.com/betslip?s={selectionIds}",
brandingLogoUrl: "https://example.com/brand-logo.png",
operatorId: "betano-bg",
affiliateId: "your-affiliate-id",
},
});Choosing a Bookmaker
The odds feed returns prices from every bookmaker configured for a match, and the betslip renders one bookmaker at a time. Without operatorId it uses whichever one the response happens to list first, which is not guaranteed to stay the same. Set data-betslip-operator-id (or betslip.operatorId) to pin the widget to one bookmaker:
<div data-component="fu-widget" data-content-type="betslip" data-betslip-operator-id="betano-bg"></div>Everything the betslip derives from the bookmaker follows: the odds themselves, the accent colour, the header and CTA logo, and the deep link to its betslip. Markets the chosen bookmaker does not price are dropped from the widget, and if it prices nothing at all, the panel stays hidden. The id is sent with the odds request, so the other bookmakers' prices are never downloaded.
Available operator ids:
betano-bg
efbet-bg
inbet-bg-online
inbet-bg-offline
betwild-bg
bet-bg
sesame-bg
winbet-bg
Operators are configured on the Fans United side, so this list can change — check with your account manager if the one you need is not listed.
Inside the Predictor or TopX widget you don't need to set it twice: the first operator of the widget's own data-predictor-odds-operators / data-top-x-odds-operators (or predictor.odds.operators / topX.odds.operators) also pins its built-in betslip, unless betslip.operatorId says otherwise. See Predictor → Odds.
The Place-Bet CTA and Affiliate Attribution
The CTA link resolves in three steps, first match wins:
ctaUrlTemplate, if you set one — your own destination.- The operator's betslip deep link from the odds response — this is the one that lands the user on a pre-filled betslip at the bookmaker, and it needs no configuration.
- The operator's homepage — a last resort that opens the bookmaker with an empty slip.
So in the normal case you configure nothing. Set ctaUrlTemplate only when the CTA has to go somewhere other than the bookmaker's betslip.
Operator links carry an affiliate placeholder that the API fills only when the request supplies one — otherwise the tag comes back empty. Set affiliateId so clicks through the CTA are attributed to you:
<div
data-component="fu-widget"
data-content-type="betslip"
data-betslip-operator-id="betano-bg"
data-betslip-affiliate-id="your-affiliate-id"
></div>Placeholders available in ctaUrlTemplate:
| Placeholder | Value |
|---|---|
{selectionIds} | Comma-separated selection IDs, URI-encoded as a whole |
{betslip_ids} | Operator selection IDs joined with the operator's own separator |
{stake} | Current stake input value |
{currentUrl} | window.location.href, URI-encoded |
{eventId} | eventId of the first selection |
{oddsDecimal} | Decimal odds of the first selection |
{market} | Market code of the first selection |
{outcome} | Outcome label of the first selection |
Managing Selections Programmatically
The betslip itself renders no UI until it has at least one selection. Add and remove selections using FuWidget.betslip:
// Add a selection (e.g. from a match odds click on your page)
FuWidget.betslip.setSelection("fb:m:328701:FT_1X2:1");
// Remove a specific selection
FuWidget.betslip.removeSelection("fb:m:328701:FT_1X2:1");Selection IDs follow the format {match_id}:{market}:{outcome}. The exact values depend on your data provider and the odds feed — refer to your odds provider documentation for the correct format.
Note:FuWidget.betslipis available after the widget bundle has loaded (i.e. insideonReadywhen using the loader, or after your<script>has executed). See API Reference → Betslip API.
Customising Labels
Use data-betslip-labels (or betslip.labels in global config) to override the text displayed inside the widget. All fields are optional — only provide the ones you want to change.
<div
data-component="fu-widget"
data-content-type="betslip"
data-betslip-labels='{"title":"My Betslip","placeBetLabel":"Place Bet","emptyTitle":"No selections yet","emptyDescription":"Add selections to get started"}'
></div>Available label fields (BetslipLabels):
| Field | Description |
|---|---|
title | Heading text of the betslip panel |
placeBetLabel | Label on the primary CTA button that submits the bet |
emptyTitle | Heading shown when the betslip has no selections |
emptyDescription | Body text shown when the betslip has no selections |
continueLabel | Label on the "Continue" / proceed button (e.g. after a review step) |
disclaimer | Legal / responsible gambling disclaimer text in the betslip footer |
combinedOddsLabel | Label preceding the calculated combined (accumulator) odds value |
stakeLabel | Label for the per-selection stake input field |
totalStakeLabel | Label for the total stake amount in the summary row |
potentialWinLabel | Label for the potential winnings amount in the summary row |
oddsUnavailableLabel | Text shown on a selection when odds cannot be fetched |
suspendedLabel | Text shown on a selection when it has been suspended by the bookmaker |
outcomeLabels | Nested BetslipOutcomeLabels object — overrides generated outcome display strings |
marketLabels | Map of market-key → display string for overriding market name labels |
Nested outcome labels (BetslipOutcomeLabels):
| Field | Description |
|---|---|
yes | Label for a boolean "Yes" outcome |
no | Label for a boolean "No" outcome |
draw | Label for a draw / tie outcome |
over | Label for an "Over" outcome in totals markets |
under | Label for an "Under" outcome in totals markets |
noGoal | Label for a "No Goal" outcome |
nobody | Label for a "Nobody" outcome (e.g. no goalscorer) |
or | Separator word used between alternative outcomes (e.g. "Team A or Team B") |
Features
- Floating overlay — positioned anywhere on the page, independent of page layout
- Live odds polling with configurable refresh interval
- Accumulator support with combined odds calculation
- Configurable stake presets for quick bet amounts
- Suspended and settled selection states
- Bookmaker pinning via
operatorId, with affiliate attribution viaaffiliateId - Branding / sponsor logo support
- Fully customisable labels
- Custom theming via
themeOptions
Implementation Tips
- Position near odds: Place the betslip widget close to where your odds are displayed so users don't have to scroll to see their selections.
- Use
loadWidget()with a container: For most pages, passing acontainerkeeps the betslip anchored to a predictable spot in the DOM. - Call
setSelectionafteronReady: Always wait for the widget bundle to finish loading before callingFuWidget.betslip.setSelection(). - Pair with Predictor: If you use the Predictor widget, enable its built-in betslip integration via
predictor.betslipinstead of running both widgets side-by-side.
Updated 4 days ago
