Roulette Widget
Embed a full roulette widget with spinning wheel, stats panel, chip selector, and animated gameplay.
Supports play mode (interactive spins) and simulation mode (click-to-simulate). Sends round results to the parent page via postMessage.
The Roulette Widget and the Board Widget are the same component. The board is the roulette widget with the wheel, chips, stats, and settings disabled by default, and with history and outcome board hidden unless simulation is on. All URL parameters work on both, but the board's defaults cannot be turned back off from the URL.
Quick Start
Copy this snippet into your HTML:
<iframe
src="https://spinstrategy.app/embed/roulette"
style="border:none;width:100%;height:700px"
></iframe>
Query Parameters
All parameters from the main embed docs apply. Summary:
| Parameter | Default | Description |
|---|---|---|
bets | (none) | Comma-separated bet tokens (format reference) |
enableSimulation | off | Click-to-simulate instead of interactive play |
theme | dark | dark or light |
disableWheel | off | Hide the spinning wheel (stats stay unless disableStats) |
disableHistory | off | Hide the round history bar |
disableOutcomeBoard | off | Hide the outcome heatmap |
disableStats | off | Hide the stats panel |
disableChips | off | Hide the chip selector |
disableSettings | off | Hide the settings gear |
sound | off | Enable sound effects (chip place, spin); muted by default |
disableStats and disableOutcomeBoard lock their checkboxes in the settings dialog. sound stays toggleable by the visitor. The other flags have no dialog control at all.
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 widget adapts to its container width. Above 860px, the wheel panel sits beside the board. Below 860px, it stacks vertically. Below 540px, the content scales proportionally to fit.