Skip to Content
iFrameFrontend IntegrationIntegration ModuleOverview

Integration Module

integration.js is a small module you copy into your own project. It wraps the raw postMessage protocol in a pub-sub API, creates the iframe element with the right attributes, and handles route syncing for you.

This is the supported way to integrate the iFrame. The module is where the postMessage protocol is dealt with, so the rest of this section documents behaviour in terms of its API rather than raw messages. The protocol itself is documented in All Events, for when you need to know exactly what goes over the wire.

Getting the file

Copy the full source into your project — for example as services/integration.js — then import it as integration.

The examples throughout these docs use services/integration and path_to/integration interchangeably; both just mean “wherever you put the file”.

Because you own the copy, you also own keeping it current. Check the Source page when upgrading, and diff it against your copy.

Setting it up

Configure with init(), then create the iframe with mount(). init() returns the module, so calls can be chained.

Both calls in context, in a full integration with subscriptions and teardown, are in Getting Started. Their signatures follow.

init(options)

Sets the module’s configuration. Call it before mount().

OptionTypeRequiredDescription
languagesstring[]+Supported language codes. Used to find and strip the language segment in URLs
prefixstring-URL prefix for the sportsbook section on your site. Default 'sports'
blacklistedRoutesstring[]-Exact route paths to exclude from navigation syncing. See the note below
isNavigationCaptureDisabledboolean-Set true to stop the module from touching your URL. Default false

mount(id, inputUrl, onLoadCallback, attributes)

Creates the iframe, appends it to the container you name, and sends the initial iframe-navigation message.

ParameterTypeRequiredDescription
idstring+ID of the DOM element the iframe is appended to
inputUrlstring+The iframe URL
onLoadCallbackFunction-Assigned to the iframe’s onload. Runs once the iframe’s content and all dependent resources — images, CSS, scripts — have loaded
attributesObject-Extra attributes merged onto the iframe element, overriding the defaults

By default the iframe is created with id="betbook", class="betbook", name="target", frameBorder="0", and the allow list that video streaming needs. Anything you pass in attributes replaces the matching default rather than extending it, so passing your own allow drops the permissions the iFrame depends on. See Embedding the iFrame.

mount() returns the iframe element, or null if the same URL is already mounted — it de-duplicates repeat calls.

on(event, callback)

Subscribes to a message from the iframe. Returns { off } — call off() to unsubscribe.

Example of .on() method usage:
import integration from "path_to/integration"; const on = integration.on; const unsubscriptions = []; unsubscriptions.push( on("login.click", () => { // handles login-related logic whenever the event is emitted }), ); unsubscriptions.push( on("user.balance", () => { // triggers a UI or data refresh each time the user's balance updates }), );

Storing the return values makes cleanup a one-liner:

Example
// Remove all event listeners unsubscriptions.forEach((sub) => sub.off());

The callback receives the whole message object, and the payload is not nested the same way for every event. See Message envelope.

emit(data, type)

Sends a message to the iframe, wrapped as { type, value: data }.

Example of .emit() method usage:
import integration from "path_to/integration"; integration.emit({ mode: "dark" }, "theme-mode-change"); integration.emit({}, "get-user-balance");

Omitting type sends the message with the module’s default type, iframe, where each key acts as its own command — see The iframe command envelope.

helpers

Shorthands for the most common messages. Each one is equivalent to the emit() call it wraps, so mixing helpers and raw emit() is fine.

HelperEquivalent toNotes
logout()emit({ logout: true })See Session & Auth
toggleThemeMode(mode?)emit({ mode }, 'theme-mode-change')Without an argument, flips between light and dark. Also stores the choice and sets data-theme on document.body
getCurrentThemeMode()—Reads prefers-color-scheme from Local Storage. Returns null when nothing is stored
updateCurrency(currency)emit({ currency }, 'currency-update')See Balance & Currency
emitThemeName(name)emit({ name }, 'theme-mode-change')Sends a named theme rather than a light/dark mode

What it handles for you

Once init() and mount() have run, the module already does the following — there is nothing to implement on your side for any of it:

  • Route capture — subscribes to navigation and calls history.replaceState(), applying your prefix and skipping blacklisted routes. Turn it off with isNavigationCaptureDisabled: true.
  • Initial navigation — sends iframe-navigation with the current path during mount().
  • client-url — sends your page’s href in response to sdkInit, which video streaming and share links depend on. Add basePath here for custom share-link paths.
  • Theme persistence — applies the stored mode on init, falling back to the iframe’s defaultThemeMode, then to dark.

Customising it

The file is yours, so anything can be changed — but the parts differ a lot in how safe they are to touch.

Change these

WhatWhy
The postMessage target originPublished as '*', which lets any page receive these messages. Replace it with your iFrame’s origin. The source carries a @todo for exactly this
THEME_MODE.DEFAULTThe mode applied when nothing is stored and the iframe sends no defaultThemeMode. Default 'dark'
The blacklistedRoutes fallbackSee the note under init()

Leave these alone

Changing them breaks the protocol rather than customising it:

  • messagePubSub and the window message listener — the dispatch layer every subscription depends on.
  • The navigation subscriber’s guard conditions — the checks for '/', the current language segment and previousPath are what stop the module from rewriting your URL on the iframe’s own initial load.
  • The jwt deletion in the query handling — it keeps the token out of the URL the module writes into your address bar.
  • setData / getData / store — internal state used by mount().