The Button Widget provides a floating call-to-action button that opens the Virtual Stadium experience. It displays real-time user counts and can be configured in two visual variants to fit your integration needs.
Key Features:

Before integrating the Button Widget, ensure you have:
For complete setup instructions, see Getting Started.
See the Button Widget in action: Working Example
Add the Button Widget with minimal configuration. The widget will display the large variant by default with real-time user counts.
Basic Button Widget:
<script>
SIR('addWidget', '#button-container', 'button', {
channelId: 'your-channel-id',
apiKey: 'your-api-key',
onAction: function(value) {
if (value.type === 'OpenVirtualStadium') {
// load/open virtual stadium widget
}
}
});
</script>
<div id="button-container"></div>channelId string required
The unique identifier for the Virtual Stadium channel this button will open.
apiKey string required
Your Sportradar API key for read-only mode. Used to fetch channel statistics like user counts.
Required Configuration:
{
channelId: 'channel_123',
apiKey: 'your-api-key'
}buttonVariant 'large' | 'compact' optional
Controls the button's display size and content. Default: 'large'
'large' - Full button with icon, "Virtual Stadium" text, and user count'compact' - Icon-only button for space-constrained layoutsonAction function optional
Callback function invoked when the button is clicked. Receives an action object with type and data properties.
Action Type: 'OpenVirtualStadium'
Parameters:
value.type - Action type identifiervalue.data.source - Action source (e.g., 'OpenSolution')value.data.channelId - The channel ID being openedButton Variants:
// Large button (default)
{
channelId: 'channel_123',
apiKey: 'your-api-key',
buttonVariant: 'large',
onAction: function(value) {
if (value.type === 'OpenVirtualStadium') {
// load/open virtual stadium widget
}
}
}
// Compact button
{
channelId: 'channel_123',
apiKey: 'your-api-key',
buttonVariant: 'compact',
onAction: function(value) {
if (value.type === 'OpenVirtualStadium') {
// load/open virtual stadium widget
}
}
}The large variant displays the full button experience with:
Best for:
Large Button:
SIR('addWidget', '#button-large', 'button', {
channelId: 'channel_123',
apiKey: 'your-api-key',
buttonVariant: 'large',
onAction: function(value) {
if (value.type === 'OpenVirtualStadium') {
// load/open virtual stadium widget
}
});The compact variant displays only the Virtual Stadium icon, providing a minimal footprint.
Best for:
Compact Button:
SIR('addWidget', '#button-compact', 'button', {
channelId: 'channel_123',
apiKey: 'your-api-key',
buttonVariant: 'compact',
onAction: function(value) {
if (value.type === 'OpenVirtualStadium') {
// load/open virtual stadium widget
}
}
});Here's a complete example showing the Button Widget integrated with the Virtual Stadium widget. When users click the button, the Virtual Stadium experience opens.
Complete Integration:
<!DOCTYPE html>
<html>
<head>
<title>Virtual Stadium Button</title>
</head>
<body>
<!-- Widget Loader -->
<script>
(function (a, b, c, d, e, f, g, h, i) {
a[e] || ((i = a[e] = function(){(a[e].q = a[e].q || []).push(arguments)}),
(i.l = 1 * new Date()),(i.o = f),(g = b.createElement(c)),(h = b.getElementsByTagName(c)[0]),
(g.async = 1),(g.src = d),g.setAttribute("n", e),h.parentNode.insertBefore(g, h));
})(window, document, "script", "https://widgets.sir.sportradar.com/<clientId>/widgetloader", "SIR", {
language: "en",
});
// Add Button Widget
SIR('addWidget', '#vs-button', 'button', {
channelId: 'your-channel-id',
apiKey: 'your-api-key',
buttonVariant: 'large',
onAction: function(value) {
if (value.type === 'OpenVirtualStadium') {
// Remove button widget
SIR('removeWidget', '#vs-button');
// Add Virtual Stadium widget
SIR('addWidget', '#vs-container', 'virtualStadium', {
// ...
});
}
}
});
</script>
<!-- Button Container -->
<div id="vs-button"></div>
<!-- Virtual Stadium Container -->
<div id="vs-container"></div>
</body>
</html>Consider switching between button variants based on screen size for optimal user experience.
Recommended approach:
'large' variant'compact' variantYou can implement this using CSS media queries for positioning or by dynamically changing the widget configuration.
Responsive Button:
// Store widget configuration
const buttonConfig = {
channelId: 'your-channel-id',
apiKey: 'your-api-key',
buttonVariant: window.innerWidth < 768 ? 'compact' : 'large',
onAction: function(value) {
if (value.type === 'OpenVirtualStadium') {
// load/open virtual stadium widget
}
}
};
// Add widget with initial configuration
SIR('addWidget', '#vs-button', 'button', buttonConfig);
// Update on window resizewindow.addEventListener('resize', () => {
const isMobile = window.innerWidth < 768;
const newVariant = isMobile ? 'compact' : 'large';
// Only update if variant changed
if (buttonConfig.buttonVariant !== newVariant) {
buttonConfig.buttonVariant = newVariant;
// Update widget with complete configuration
SIR('updateWidget', '#vs-button', buttonConfig);
}
});Positioning - Place the button in a visible, accessible location (e.g., bottom-right corner as a floating button)
Variant Selection - Choose the variant that best fits your layout without overwhelming the page
Multiple Channels - If you have multiple channels, use separate buttons with different channelId values
Error Handling - Implement fallback behavior if the widget fails to load
Accessibility - Ensure the button is keyboard accessible and has appropriate ARIA labels
Best Practices Example:
// Good: Floating button placement
const buttonContainer = document.createElement('div');
buttonContainer.id = 'vs-button';
buttonContainer.style.cssText = `
position: fixed;
bottom: 20px;
right: 20px;
z-index: 1000;
`;
document.body.appendChild(buttonContainer);
SIR('addWidget', '#vs-button', 'button', {
channelId: 'your-channel-id',
apiKey: 'your-api-key',
buttonVariant: window.innerWidth < 768 ? 'compact' : 'large',
x onAction: function(value) {
if (value.type === 'OpenVirtualStadium') {
// load/open virtual stadium widget
}
}
});
// Good: Multiple channels
const channels = ['channel-1', 'channel-2'];
channels.forEach((channelId, index) => {
SIR('addWidget', `#button-${index}`, 'button', {
channelId,
apiKey: 'your-api-key',
onAction: function(value) {
if (value.type === 'OpenVirtualStadium') {
// load/open virtual stadium widget
}
}
});
});