> For the complete documentation index, see [llms.txt](https://docs.sportradar.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sportradar.com/nextgen-igaming/ignite/recommended-betslips-integration-guide.md).

# Recommended Betslips Integration Guide

Introduction

The **Recommended Betslips** is a standalone micro-frontend Web Component that displays personalized recommended betting slips to users. It’s designed to be lightweight, self-contained, and easy to integrate into any section of your application, complementing your betting interface or appearing alongside other content.

This guide contains all information necessary to integrate, configure, and customize the Recommended Betslips for your specific use case.

### About Micro-Frontends&#xD;

Micro-frontends are independent, self-contained frontend applications that can be deployed separately and composed together in a larger application. They enable teams to develop, test, and deploy frontend features independently while maintaining a cohesive user experience.

The Sportsbook is built as a Web Component, a standard browser API that allows you to:

* Define custom HTML elements with encapsulated functionality
* Use the component in any JavaScript framework, vanilla HTML or even in native applications via WebViews
* Deploy and update the component independently
* Maintain clear boundaries between the component and host application

About the Tooling

All **NSoft Sportsbook** micro-frontends share a consistent architecture and deployment model.

### Distribution Model&#xD;

* **CDN-only**: Components are distributed exclusively via CDN to ensure users always receive the latest stable version without managing local builds
* **ES Module**: Distributed as ES modules (type="module"), compatible with all modern browsers and modern build systems
* **Environment-specific**: Separate builds are published for staging and production environments
* **Dependency-free**: Each component is self-contained with all dependencies bundled. Tree-shakeable and optimized for minimal payload size, with no external npm dependencies required.

### Technology Stack&#xD;

* **TypeScript**: Full type safety for better development experience
* **Web Components API**: Standard browser APIs for custom elements

### Component Registration Pattern&#xD;

All **NSoft Sportsbook** micro-frontend components follow a consistent registration pattern:

```javascript
import { registerComponentName } from 'https://staging.nsftx-sports-web.nsoft.app/nsftx-sports-web.js'

registerComponentName({
  // Configuration options (component-specific)
})
```

Each component exports a registration function that:

* Validates the provided configuration using Zod schemas
* Defines the custom element in the browser’s element registry
* Sets up internal state management and routing (if applicable)

## Installation

The Recommended Betslips Widget is distributed exclusively via CDN as an ES module. This ensures you always receive the latest stable version without managing local builds.

### CDN URLs&#xD;

<table><thead><tr><th width="152">Environment</th><th>Primary CDN</th><th>Secondary CDN (Fallback)</th></tr></thead><tbody><tr><td>Production</td><td><a href="https://nsftx-sports-web.nsoft.app/nsftx-sports-web.js"><code>https://nsftx-sports-web.nsoft.app/nsftx-sports-web.js</code></a></td><td><a href="https://nsftx-sports-web.7platform.net/nsftx-sports-web.js"><code>https://nsftx-sports-web.7platform.net/nsftx-sports-web.js</code></a></td></tr><tr><td>Staging</td><td><a href="https://staging.nsftx-sports-web.nsoft.app/nsftx-sports-web.js"><code>https://staging.nsftx-sports-web.nsoft.app/nsftx-sports-web.js</code></a></td><td><a href="https://staging.nsftx-sports-web.7platform.net/nsftx-sports-web.js"><code>https://staging.nsftx-sports-web.7platform.net/nsftx-sports-web.js</code></a></td></tr></tbody></table>

{% hint style="info" %}
We recommend implementing a fallback mechanism that attempts to load from the primary CDN first, then falls back to the secondary CDN if the primary is unavailable.
{% endhint %}

## Registration

To register the Recommended Betslips Widget, import the registration function and call it with your configuration:

```javascript
const PRIMARY_CDN = 'https://nsftx-sports-web.nsoft.app/nsftx-sports-web.js'
const SECONDARY_CDN = 'https://nsftx-sports-web.7platform.net/nsftx-sports-web.js'

let registerRecommendedBetslipsWidget

try {
  ;({ registerRecommendedBetslipsWidget } = await import(PRIMARY_CDN))
} catch (error) {
  console.warn('Primary CDN failed, attempting secondary CDN...', error)
  try {
    ;({ registerRecommendedBetslipsWidget } = await import(SECONDARY_CDN))
  } catch (error) {
    console.error('Both CDNs failed to load', error)
    throw error
  }
}

registerRecommendedBetslipsWidget()
```

Then add the component to your HTML:

```html
<aside>
  <recommended-betslips />
</aside>
```

{% hint style="info" %}
The default tag name is `recommended-betslips`. You can customize this during registration.
{% endhint %}

Configuration Options

### Custom Tag Name&#xD;

You can optionally provide a custom tag name if you need to distinguish between multiple instances or follow a specific naming convention:

```javascript
registerRecommendedBetslipsWidget({
  tag: 'custom-betslips-widget'
})
```

```html
<aside>
  <custom-betslips-widget />
</aside>
```

This is useful when:

* You have multiple widget instances with different purposes
* You need namespace separation
* You’re integrating with other components that might have naming conflicts

Events

The Recommended Betslips Widget emits events to communicate with its parent application through iGnite’s `sendDomEvent` mechanism. Your parent application can listen to these events using the `onDomEvent` handler.

### NSFTX\_RECOMMENDED\_BETSLIPS\_PREVIEW\_DIALOG\_OPENED&#xD;

Emitted when a user opens the preview dialog for a recommended betslip (desktop view).

**Payload**: No payload

**Example usage**:<br>

```javascript
onDomEvent: (event) => {
  if (event.type === 'NSFTX_RECOMMENDED_BETSLIPS_PREVIEW_DIALOG_OPENED') {
    console.log('Preview dialog opened');
  }
}
```

### NSFTX\_RECOMMENDED\_BETSLIPS\_PREVIEW\_DIALOG\_CLOSED <a href="#nsftx_recommended_betslips_preview_dialog_closed" id="nsftx_recommended_betslips_preview_dialog_closed"></a>

Emitted when a user closes the preview dialog for a recommended betslip (desktop view).

**Payload**: No payload

### NSFTX\_RECOMMENDED\_BETSLIPS\_DRAWER\_OPENED

Emitted when a user opens the drawer containing recommended betslips (mobile view).

**Payload**: No payload

### NSFTX\_RECOMMENDED\_BETSLIPS\_DRAWER\_CLOSED

Emitted when a user closes the drawer containing recommended betslips (mobile view).

**Payload**: No payload

### NSFTX\_RECOMMENDED\_BETSLIPS\_IN\_FULL\_VIEW\_ENABLED

Emitted when the widget enters full view mode on mobile, displaying all recommended betslips.

**Payload**: No payload

```javascript
{
  "type": "NSFTX_RECOMMENDED_BETSLIPS_IN_FULL_VIEW_ENABLED",
}
```

### NSFTX\_RECOMMENDED\_BETSLIPS\_ADD\_TO\_BETSLIP <a href="#nsftx_recommended_betslips_add_to_betslip" id="nsftx_recommended_betslips_add_to_betslip"></a>

Emitted when a user adds a recommended betslip to their active betslip.

**Payload**:

<table><thead><tr><th width="189">Field</th><th>Description</th></tr></thead><tbody><tr><td><code>action</code></td><td>Always set to <code>'add_to_betslip'</code></td></tr><tr><td><code>bet.betType</code></td><td>The type of bet (e.g., 'single', 'accumulator')</td></tr><tr><td><code>bet.selections</code></td><td>Array of bet selections, each containing:<br>- <code>marketId</code>: Market identifier<br>- <code>outcomeId</code>: Outcome identifier<br>- <code>outcomeOdds</code>: Odds for the outcome<br>- <code>banker</code>: Whether this is a banker selection (for trixie/yankee bets)<br>- <code>eventId</code>: Event identifier<br>- <code>eventMarketId</code>: Event market identifier<br>- <code>eventMarketOutcomeId</code>: Event market outcome identifier</td></tr></tbody></table>

```javascript
{
  "type": "NSFTX_RECOMMENDED_BETSLIPS_ADD_TO_BETSLIP",
  "payload": {
    "action": "add_to_betslip",
    "bet": {
      "betType": "single",
      "selections": [
        {
          "marketId": "12345",
          "outcomeId": "67890",
          "outcomeOdds": 1.85,
          "banker": false,
          "eventId": "event123",
          "eventMarketId": "market123",
          "eventMarketOutcomeId": "outcome123"
        }
      ]
    }
  }
}
```

### NSFTX\_RECOMMENDED\_BETSLIPS\_NAVIGATE\_TO\_EVENT

Emitted when a user clicks to navigate to a specific event from within the widget.

**Payload**:

<table><thead><tr><th width="113">Field</th><th>Description</th></tr></thead><tbody><tr><td><code>path</code></td><td>Navigation path to the event in format <code>/sports/e_{eventId}</code></td></tr></tbody></table>

```javascript
{
  "type": "NSFTX_RECOMMENDED_BETSLIPS_NAVIGATE_TO_EVENT",
  "payload": {
    "path": "/sports/e_12345"
  }
}
```

## Troubleshooting

### Styling Not Applied <a href="#styling_not_applied" id="styling_not_applied"></a>

**Problem**: CSS styles for the widget aren’t working.

**Solution**: The widget uses Shadow DOM encapsulation. Style the component container instead of elements inside:

```css
/* Correct - style the container */
aside recommended-betslips {
  display: block;
  margin: 20px 0;
}

/* Won't work - widget content is encapsulated */
recommended-betslips h2 {
  color: blue;
}
```

### CSS Variable Inheritance

Exposed CSS variables

The widget can inherit CSS variables from its integrator, allowing you to tailor certain styles by declaring CSS variables in your root element.

<table><thead><tr><th width="158">Variable</th><th width="106">CSS Property</th><th width="87">Default</th><th>Description</th></tr></thead><tbody><tr><td><code>--nsftx-recommended-betslips-preview-dialog-z-index</code></td><td>z-index</td><td>1</td><td>Defines the z-index value for the overlay of the recommended betslip’s preview dialog. This setting ensures that the overlay appears above other UI elements when the dialog is active, maintaining proper visual stacking and focus.</td></tr></tbody></table>

### **Usage example**

```css
:root {
  --nsftx-recommended-betslips-preview-dialog-z-index: 2;
}
```

This allows you to integrate the widget seamlessly into your application’s layout, ensuring dialogs appear at the correct stacking level relative to other elements.

### No Router Required

Unlike the Sportsbook component, this widget doesn’t require routing configuration. It works as-is with minimal setup.

### Additional Resources <a href="#additional_resources" id="additional_resources"></a>

* [Web Components - Using Custom Elements](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements) - MDN documentation on Web Components

### Integration Examples

You can find a GitHub project showcasing integration of the Recommended Betslips micro-frontend in multiple JavaScript frameworks (Vanilla JS, Vue, Next.js, Svelte) here:

* [NSoft Sportsbook Micro-Frontends Integration Examples](https://github.com/nsftx/nxg-sports-micro-frontends-example)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.sportradar.com/nextgen-igaming/ignite/recommended-betslips-integration-guide.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
