FrontEnd integration¶
General info¶
Sportsbook iFrame uses a token-based authentication protocol for authenticating users and securing interactions between the client's platform and GR8 Tech's services. This protocol generates encrypted security tokens that are used to verify the identity of users on the website.
The client's platform generates a unique encrypted authentication token using the token-based authentication protocol provided by GR8 Tech.
GR8 Tech provides clients with a brand with preconfigured features and color styles.
GR8 Tech also provides an iframe host that clients can use for the FE integration.
Clients can insert the GR8 Tech iFrame into their own platform using the following integration code.
Iframe integration¶
To embed an iframe, you need to import an integration file.
This module provides a configuration and messaging system designed to initialize and control navigation behavior.
The integration module contains the following methods for use:
Initializes the module's configuration.
Parameters:
| Param | Type | Required | Description |
|---|---|---|---|
| languages | string[] | + | Array of supported language codes |
| prefix | string | - | URL prefix. Default value 'sports' |
| blacklistedRoutes | string[] | - | Array of route patterns to exclude from processing |
| isNavigationCaptureDisabled | boolean | - | If true, disables internal navigation interception. Default value false |
Mounts the application.
Parameters:
| Param | Type | Required | Description |
|---|---|---|---|
| id | string | + | ID of the DOM element where the iframe will be appended |
| inputUrl | string | + | Iframe URL |
| onLoadCallback | Function | - | Callback function to pass into iframe |
onLoadCallback is assigned to the iframe’s onload attribute and runs when the iframe’s content has fully loaded, including all dependent resources (images, CSS, scripts).
Subscribes to a named event using a pub-sub system.
Parameters:
| Param | Type | Required | Description |
|---|---|---|---|
| event | string | + | Event name to subscribe to |
| callback | Function | + | Function to invoke when the event is emitted |
Returns: { off: Function } — call off() to unsubscribe.
Below are practical use cases demonstrating how to leverage the .on() method to subscribe to various event types:
import integration from 'path_to/integration';
const on = integration.on;
const unsubscriptions = [];
// 1. Listening for login button clicks
unsubscriptions.push(
on('login.click', () => {
// handles login-related logic whenever the event is emitted
})
);
// 2. Listening for login button clicks
unsubscriptions.push(
on('register.click', () => {
// handles registration logic whenever the event is emitted
})
);
// 3. Monitoring balance updates to trigger a UI refresh
unsubscriptions.push(
on('user.balance', () => {
// triggers a UI or data refresh each time the user's balance updates.
})
);
// 4. Handling balance transfers with a handler function
unsubscriptions.push(
on('user.balance_transfer', () => {
// updates application state when a balance transfer event is emitted
})
);
Each call to .on() returns an object with an .off() method. Storing these in the unsubscriptions array allows clean-up later:
Emits a message to other parts of the system (via postMessage).
Parameters:
| Param | Type | Required | Description |
|---|---|---|---|
| data | any | + | Payload to send |
| type | string | + | Event/message type |
Below are some examples of .emit() method usage:
import integration from 'path_to/integration';
integration.emit({ balanceTransferSuccess: val });
// Emitting a balanceTransferSuccess Event
// Sends an event notifying listeners that a balance transfer has successfully completed.
integration.emit({ balance: user?.balance, currency: user?.currency });
// Notifies subscribers that the user's balance and currency have been updated.
Thus, to add an iframe to a page, it is enough to initialize the integration module with the required configuration and call the mount method, and pass the ID of the DOM element in which the iframe should be located and the URL of the iframe as parameters:
import integration from "services/integration";
integration.init({
languages: ["en"],
});
integration.mount("iframe", "https://demo-iframe-brand.gr8.tech/en/?jwt=tokenvalue");
Scroll event¶
This file also implements the functionality of synchronizing the scroll event on the client's site and in the iframe. If the value of the top position of the iframe on the page is greater than the value of IFRAME_MAX_OFFSET (by default IFRAME_MAX_OFFSET = 0), then when scrolling elements inside the iframe, the outer page will also scroll until the top border of the iframe reaches the top of the viewing area.
Handling Deposit button click event¶
A dedicated postMessage event type, deposit.click, is emitted when the Deposit button in the Betslip is clicked. By subscribing to this event, clients can add custom functionality (e.g., navigation, analytics, or UI updates).
import integration from 'services/integration';
const on = integration.on;
const unsubscriptions = [];
unsubscriptions.push(on('deposit.click', () => {
analyticsService.pushDataLayer({});
navigateByPath('/deposit');
}));
Theme Mode Integration¶
Iframe supports dynamic theme switching between light and dark modes.
This approach allows the client application to toggle and retrieve the current theme mode using the integration module.
The integration module provides helper methods that abstract theme switching logic and communication with the iframe.
Available Helper Methods
- toggleThemeMode()
Toggles the theme mode between light and dark.
- getCurrentThemeMode()
Returns the currently active theme mode. The value of the currently active theme mode is taken from 'prefers-color-scheme' in the site's Local Storage or 'light' as default value if storage is empty.
import integration from 'services/integration';
import { helpers } from './integration';
const [mode, setMode] = useState(helpers.getCurrentThemeMode());
const handleChange = () => {
helpers.toggleThemeMode();
};
Initialization via postMessage¶
When the iframe sends an initialization postMessage of type sdkInit, the payload may contain a defaultThemeMode property:
Multi-Currency Balance Communication via postMessage¶
When the iframe user has a multi-currency balance, the embedded iframe communicates this information to the client site using the postMessage API. This ensures both sides stay synchronized about the available balances and the selected currency.
The iframe emits a postMessage with the following structure:
{
type: 'user.multiCurrencyBalance',
data: {
multiCurrencyBalance: {
USD: {
available: 999
},
EUR: {
available: 999
}
},
selectedCurrency: 'EUR'
}
}
multiCurrencyBalance: An object where each key is a currency code (e.g., USD, EUR) with its corresponding balance details.
selectedCurrency: The currently selected currency by the user.
Updating Currency from Client¶
The client site can change the active currency using the updateCurrency method from the integration module’s helpers.
import integration from 'services/integration';
import { helpers } from './integration';
const updateCurrency = (currency) => {
integration.helpers.updateCurrency(currency);
};
// Example usage:
updateCurrency('EUR');
This instructs the iframe to switch to the provided currency.
Forced balance refresh¶
The parent page can trigger a forced balance refresh inside the embedded iframe by sending a postMessage with type get-user-balance. This will make the iframe request the latest balance and update its internal state/UI.
import integration from 'services/integration';
const updateBalance = () => {
integration.emit({}, 'get-user-balance');
};
Sharing Bet Link¶
When generating a shareable bet link, the URL is built using the client site's origin and a base path. To provide this, the client must send a client-url postMessage containing window.location.href when the iframe loads.
By default, if no basePath is provided, the link falls back to {origin}/sports/{lang}?shareKey=.... If the sportsbook is mounted on a custom path, the client can pass an optional basePath field:
In the integration.js file, update the sdkInit subscription to include basePath alongside href:
messagePubSub.subscribe('sdkInit', ({ value }) => {
// ...
module.emit({ href: window.location.href, basePath: `${path-to-sportsbook}` }, 'client-url');
// ...
});
basePath values reference¶
basePath should represent the path segment(s) between the client's origin and the ?shareKey query parameter in the resulting share link.
Examples:
Client wants https://iframe.example.com?shareKey=... → basePath: ''
Client wants https://iframe.example.com/sportsbook?shareKey=... → basePath: 'sportsbook'
Client wants https://iframe.example.com/casino/sportsbook?shareKey=... → basePath: 'casino/sportsbook'
If basePath is not provided, the link falls back to the default format: {origin}/sports/{lang}?shareKey=...
Clients that don't provide basePath are not affected — the default behavior is preserved.
Handling Banner clicks with openLink Message¶
The iframe cannot directly open links in the same browser tab due to browser security restrictions on iframes (known as the same-origin policy).
Calls like window.top.location.replace() or window.top.open() are blocked if the iframe is embedded from a different domain.
To handle navigation safely, the iframe sends a postMessage with type openLink event to the parent page.
target: Navigation target ('_self', '_blank', etc.).
On the parent page, the client should listen for this message and handle the navigation.