Presets
Presets are JSON files that capture all theme and layout settings for the widget. Partners design presets in the playground and deploy them for production use.
How Preset Loading Works
In production, the widget loads your theme from a remote URL at startup. The Betflow team configures the preset hosting for your deployment.
Loading Priority
The widget resolves its theme in this order:
?preset=query param (highest priority) — when present in the iframe URL, the widget fetches the corresponding preset JSON file. This lets you control the theme per embed.- Default preset (fallback) — if no
?preset=param is provided, the widget loads a default preset configured for your deployment. - Built-in defaults — if no preset is configured, the widget renders with built-in default colors.
Production Deployment
Step 1: Design in the Playground
Use the playground to design your theme and download the preset JSON file.
Step 2: Host the Preset File
Upload the JSON file to a publicly accessible URL. Options:
| Option | Pros | Cons |
|---|---|---|
| Your own servers | Full control, update anytime | You manage hosting |
| Betflow-managed hosting | Fast, reliable, managed by us | Changes require a request to the Betflow team |
Step 3: Configure Your Deployment
The Betflow team handles environment configuration for your widget deployment. Once your preset files are hosted, provide the URLs to the Betflow team and they will configure the widget to load them.
Step 4: Embed with Preset
<iframe
src="https://widget.example.com/?preset=brand_dark_v2"
width="100%"
height="480"
frameborder="0"
style="border: none;"
></iframe>
The widget fetches the corresponding preset file based on the ?preset= value. For example, ?preset=brand_dark_v2 loads brand_dark_v2.json from your configured preset hosting location.
Multiple Presets
A single production instance can serve different themes by changing the ?preset= query param:
<!-- Dark theme -->
<iframe src="https://widget.example.com/?preset=brand_dark_v2" ...></iframe>
<!-- Light theme -->
<iframe src="https://widget.example.com/?preset=brand_light_v1" ...></iframe>
<!-- Sport-specific -->
<iframe src="https://widget.example.com/?preset=nba_special" ...></iframe>
Preset JSON Structure
The downloaded .json file contains all theme and configuration settings. All fields are optional — only provided values override defaults.
{
"funFlowDark": { "flow_background_hex_1": "062b53", "..." : "..." },
"funFlowLight": {},
"factFlowDark": {},
"factFlowLight": {},
"plainFlowDark": {},
"plainFlowLight": {},
"syncMap": {},
"colorMode": "dark",
"layoutMode": "carousel",
"factFlowDisplayType": "base",
"carouselFlowAR": 0.9,
"carouselParlayAR": 0.9,
"carouselGapPct": 3.33,
"feedFlowAR": 0.9,
"feedParlayAR": 0.9,
"feedGapPct": 3.33,
"carouselBorderThicknessPct": 0.625,
"feedBorderThicknessPct": 0.625,
"oddsType": "american | decimal | fractional | probability",
"currency": "USD",
"betslipMode": "static",
"betslipBetWord": "Bet",
"betslipWinWord": "Win",
"betslipAmount": 10,
"showParlaySubtitle": true,
"showFilters": true,
"showPagination": true,
"allowOverrideIframeFilters": true,
"containerBgHex": "FFFFFF",
"containerBgOpacity": 2,
"containerBorderHex": "FFFFFF",
"containerBorderOpacity": 8,
"pageBgHex": "0a0a1a"
}
Top-Level Settings
| Field | Type | Default | Description |
|---|---|---|---|
colorMode | string | "dark" | "dark" or "light" |
layoutMode | string | "carousel" | "carousel" or "feed" |
factFlowDisplayType | string | "base" | "base", "expanded", or "multi" |
oddsType | string | "american" | "american", "decimal", "fractional", or "probability" |
currency | string | "USD" | Currency code (USD, EUR, GBP, etc.) |
Sizing
| Field | Type | Default | Description |
|---|---|---|---|
carouselFlowAR | number | 0.9 | Aspect ratio for carousel flow cards |
carouselParlayAR | number | 0.9 | Aspect ratio for carousel parlay cards |
carouselGapPct | number | 3.33 | Gap between carousel cards (%) |
feedFlowAR | number | 0.9 | Aspect ratio for feed flow cards |
feedParlayAR | number | 0.9 | Aspect ratio for feed parlay cards |
feedGapPct | number | 3.33 | Gap between feed cards (%) |
carouselBorderThicknessPct | number | 0.625 | Card border thickness in carousel (%) |
feedBorderThicknessPct | number | 0.625 | Card border thickness in feed (%) |
Betslip
| Field | Type | Default | Description |
|---|---|---|---|
betslipMode | string | "static" | "static" (fixed) or "payout" (adjustable) |
betslipBetWord | string | "Bet" | Label for the bet button |
betslipWinWord | string | "Win" | Label for the win display |
betslipAmount | number | 10 | Default wager amount |
Feature Toggles
| Field | Type | Default | Description |
|---|---|---|---|
showParlaySubtitle | boolean | true | Show parlay subtitle text |
showFilters | boolean | true | Show filter chips above the feed |
showPagination | boolean | true | Show pagination dots (carousel) |
allowOverrideIframeFilters | boolean | true | Allow users to change iframe-set filters |
Container & Page
| Field | Type | Default | Description |
|---|---|---|---|
pageBgHex | string | "0a0a1a" | Page background color (hex without #) |
containerBgHex | string | "FFFFFF" | Container background color |
containerBgOpacity | number | 2 | Container background opacity (0–100) |
containerBorderHex | string | "FFFFFF" | Container border color |
containerBorderOpacity | number | 8 | Container border opacity (0–100) |
Per-Flow Color Themes
The six flow theme objects (funFlowDark, funFlowLight, factFlowDark, factFlowLight, plainFlowDark, plainFlowLight) share the same structure. Key color fields:
| Field | Description |
|---|---|
flow_background_hex_1 | Card background color |
subject_name_hex | Subject/player name color |
matchup_info_hex | Matchup info text color |
narrative_hex | Narrative text color |
bet_name_hex | Bet name text color |
tagline_hex | Tagline text color |
odds_value_hex | Odds display color |
expand_close_hex | Expand/close button color |
subject_photo_outline_hex | Player photo border color |
bet_placement_button_hex_1 | CTA button gradient start |
bet_placement_button_hex_2 | CTA button gradient end |
bet_placement_cta_text_hex | CTA button text color |
emoji_outline_hex | Emoji container outline (Fun Flow) |
emoji_background_hex | Emoji container background (Fun Flow) |
emoji_glow_hex | Emoji glow effect (Fun Flow) |
count_down_clock_hex | Countdown timer color |
flow_border_hex_1 | Card border color |
flow_border_radius_pct | Card border radius (%) |
custom_brand_font | Font family name |
flow_button_radius_pct | Button border radius (%) |
graph_bar_red_hex | Red bar color (Fact Flow) |
graph_bar_green_hex | Green bar color (Fact Flow) |
graph_bar_neutral_hex | Neutral bar color (Fact Flow) |
graph_trend_line_hex | Trend line color (Fact Flow) |
parlay_header_bg_hex_1 | Parlay header gradient start |
parlay_header_bg_hex_2 | Parlay header gradient end |
Each color field has a corresponding _opacity field (0–100). For example, flow_background_hex_1_opacity: 100.
The syncMap object controls which color fields are synced across flow types when the sync feature is used in the playground.
Troubleshooting
Preset Not Loading
- Check that the
?preset=value matches the filename without.json - Ensure the JSON file is publicly accessible (try opening the URL in a browser)
- Check the browser console / network tab for fetch errors
- Confirm the JSON is valid
- Contact the Betflow team to verify your preset hosting is correctly configured
Colors Not Applying
- Hex values must not include
#— useFFFFFF, not#FFFFFF - Opacity values must be between 0 and 100
- Verify you customized the correct flow type tab (Fun/Fact/Plain) and color mode (dark/light)
Widget Shows Defaults
- The
?preset=query parameter is missing from the iframesrc - The preset hosting may not be configured yet — contact the Betflow team
- The preset file returns a non-200 response (404, CORS error, etc.)
Next Steps
- Playground — design and export your theme
- Iframe Parameters — combine presets with filters and entity scoping