Embed Widgets
Embed interactive roulette widgets on any website with a single iframe tag.
Choose between the full Roulette Widget (wheel + board + stats) or the compact Board Widget (board only). Both share the same URL parameter API.
/embed/roulette: full widget with spinning wheel, stats panel, chip selector, and play or simulate modes.
/embed/board: compact board-only view. Same widget with wheel, chips, stats, and settings disabled by default. Add enableSimulation for click-to-simulate.
Quick Start
Roulette Widget
Full roulette experience with wheel, stats, and interactive play:
<iframe
src="https://spinstrategy.app/embed/roulette?bets=RED-5,17-1"
style="border:none;width:100%;height:700px"
></iframe>
Board Widget
Compact board-only view (no wheel, no chips, no stats):
<iframe
src="https://spinstrategy.app/embed/board?bets=RED-5,17-1"
style="border:none;width:100%;height:600px"
></iframe>
Query Parameters
Both widgets accept the same parameters. The board widget turns some flags on by default.
| Parameter | Type | Roulette default | Board default | Description |
|---|---|---|---|---|
bets | string | (none) | (none) | Comma-separated bet tokens (see format below) |
enableSimulation | flag | off | off | Click-to-simulate mode |
theme | string | dark | dark | dark or light |
disableWheel | flag | off | on | Hide the wheel. Stats stay unless disableStats. Also forces instant spins and the stacked layout |
disableHistory | flag | off | off (on without enableSimulation) | Hide the history bar |
disableOutcomeBoard | flag | off | off (on without enableSimulation) | Hide the outcome heatmap above the board |
disableStats | flag | off | on | Hide the stats panel |
disableChips | flag | off | on | Hide the chip selector |
disableSettings | flag | off | on | Hide the settings gear |
sound | flag | off | off | Play sound effects. Off everywhere by default so an embed never plays audio unprompted |
Flags are presence-based: ?enableSimulation&disableWheel turns both on. Any value, including =false, still turns the flag on, so the board widget's defaults cannot be turned back off from the URL. Repeated parameters (?bets=A&bets=B) are dropped; put all bets in one bets value.
disableStats and disableOutcomeBoard also lock their checkboxes in the settings dialog. sound stays user-toggleable. There is no wheel parameter; the wheel picker in the settings dialog (European, American, French) clears any URL bets when changed.
Bet Token Format
Each bet is a token in SELECTION-BETSIZE format, separated by commas. The bet size is in dollars ($0.01 to $10,000). Tokens are uppercase only; red-5 is dropped. Tokens that fail to parse are dropped silently; tokens that parse but point outside the board (DOZEN4, STREET13, CORNER1) are kept as bets that can never win.
Straight Bets
Use the pocket number directly. STRAIGHT17-1 is not accepted, and there is no way to bet 00 from the URL.
| Token | Meaning |
|---|---|
17-1 | Straight on 17, $1 |
0-2 | Straight on 0, $2 |
Named Bets
| Token | Meaning |
|---|---|
RED-5 | Red, $5 |
BLACK-5 | Black, $5 |
EVEN-2 | Even, $2 |
ODD-2 | Odd, $2 |
LOW-3 | Low (1-18), $3 |
HIGH-3 | High (19-36), $3 |
CORNER8-3 | Corner whose top-left number is 8, $3 |
SPLIT_LEFT5-2 | Split between 5 and the number to its left, $2 |
SPLIT_TOP5-2 | Split between 5 and the number above it, $2 |
CORNER, SPLIT_LEFT, and SPLIT_TOP need a selection number. Without one the selection defaults to 0, which is not a valid corner or split, so the bet is accepted but never wins.
Grouped Bets (1-Based Index)
DOZEN, COLUMN, STREET, and DOUBLE_STREET take a 1-based index, not a number on the board:
| Token | Meaning |
|---|---|
DOZEN1-10 | 1st dozen (1-12), $10 |
DOZEN2-10 | 2nd dozen (13-24), $10 |
DOZEN3-10 | 3rd dozen (25-36), $10 |
COLUMN1-5 | 1st column, $5 |
STREET7-1 | 7th street (19-21), $1 |
DOUBLE_STREET3-1 | 3rd double street (7-12), $1 |
All Supported Bet Types
RED, BLACK, EVEN, ODD, LOW, HIGH, DOZEN, COLUMN, STREET, DOUBLE_STREET, CORNER, SPLIT_LEFT, SPLIT_TOP
Play Mode and Simulation Mode
Without enableSimulation the widget is in play mode: visitors place chips by clicking, and the wheel spins. URL bets are placed for the first spin only and cleared afterwards unless the visitor turns on Keep Bets; Repeat puts them back. Clicking a number on the outcome heatmap spins to that number. The board widget without enableSimulation is still play mode, but with no wheel and no outcome board there is nothing that spins; it only shows the chips.
With enableSimulation the widget is in simulation mode: clicking any number on the board or the outcome heatmap simulates that pocket hitting. Bets are frozen to the URL bets (board clicks do not place chips and the chip selector is hidden). The widget tracks W/L stats, balance, and round history with branching: go back to a past round and click to start an alternate timeline.
<iframe
src="https://spinstrategy.app/embed/roulette?bets=RED-5,17-1&enableSimulation"
style="border:none;width:100%;height:700px"
></iframe>
postMessage API
The widget sends messages to its parent frame via window.postMessage. It does not listen for messages from the parent. Listen on the parent window to react to resize and round events.
Resize Event
Emitted when the widget's document size changes. The reported height is the document body, which never shrinks below the iframe's own height, so it is useful for growing the iframe but not for shrinking it. Below 540px the widget scales down visually but reports its unscaled height.
{
type: "spinstrategy:resize",
payload: { width: number, height: number }
}Round Result Event
Emitted after a finalized spin or simulation click whenever the round history grows. After branching from a past round in simulation mode, the new timeline is shorter than the old one, so no events are emitted until it outgrows the previous length.
{
type: "spinstrategy:roundResult",
payload: {
pocket: number, // 0-36, or 37 for 00 on an American wheel
won: boolean, // true when the net result is positive (a mixed round that lost money is false)
net: number, // net result in dollars (can be negative)
totalRounds: number // rounds in the current timeline
}
}Listener Example
window.addEventListener("message", (event) => {
if (event.data?.type === "spinstrategy:roundResult") {
const { pocket, won, net, totalRounds } = event.data.payload;
console.log(`Round ${totalRounds}: pocket ${pocket}, ${won ? "WIN" : "LOSS"}, net $${net}`);
}
if (event.data?.type === "spinstrategy:resize") {
const iframe = document.getElementById("my-roulette");
if (iframe) iframe.style.height = event.data.payload.height + "px";
}
});event.origin === "https://spinstrategy.app" before trusting message payloads.Responsive Behavior
The roulette widget switches between horizontal (board + wheel side-by-side) and stacked layout based on the container width. Above 860px, the wheel panel sits beside the board. Below 860px, it stacks. Below 540px, the content scales proportionally to fit.
Use height:700px for the roulette widget and height:600px for the board widget. With simulation enabled the history bar adds height; consider 700px for the board too.
Examples
Shared Strategy Embed
Embed a shared strategy's board with full progression-aware simulation. The widget loads the strategy's bets, progression, triggers, and wheel automatically; no bet tokens needed.
<iframe
src="https://spinstrategy.app/embed/board/s/YOUR_SHARE_TOKEN"
style="border:none;width:100%;height:800px"
></iframe>
The token comes from the strategy sharing feature: a shared strategy lives at /s/abc123, so abc123 is the token. Session share links (/ss/…) cannot be embedded.
Shared Strategy Parameters
These take explicit values, unlike the flags above:
| Parameter | Default | Description |
|---|---|---|
enableSimulation | on | enableSimulation=false hides the board and shows a hint instead |
hideStats | off | hideStats=true hides the stats panel (compact mode with a reset button) |
theme | dark | dark or light |
Unlike the generic board embed with flat bets, the shared strategy embed runs the full game engine: bets step with the progression, step-gated bets appear at their step, and the strategy's triggers fire. The shared embed does not emit the resize or roundResult messages.