Events
The platform emits browser CustomEvents on window. All events are prefixed with mindtraining: and their payload is always available in event.detail.
mindtraining:ready
Fired when: the script has finished loading and the global MindtrainingPlatform API is available on window.
When to use: this is the recommended hook to call init. By listening to this event you avoid race conditions between the script loading and your initialization code running.
event.detail
| Field | Type | Description |
|---|---|---|
api | object | Reference to window.MindtrainingPlatform |
window.addEventListener('mindtraining:ready', function (event) {
// event.detail.api === window.MindtrainingPlatform
MindtrainingPlatform.init('mindtraining', {
viewer: { loggedIn: false },
})
})Script already loaded? If your listener is registered after the script has already executed, the event won't fire again. Use this guard pattern:
function initializeMindtraining() {
MindtrainingPlatform.init('mindtraining', {
viewer: { loggedIn: false },
})
}
if (window.MindtrainingPlatform) {
initializeMindtraining()
} else {
window.addEventListener('mindtraining:ready', initializeMindtraining, { once: true })
}mindtraining:config
Fired when: the platform configuration is updated — both after the initial init() call and after any subsequent updateConfig() call.
When to use: use this event to react to configuration changes from outside the platform, such as synchronizing your own UI state (e.g. reflecting a subscription change or login state update that the platform just received).
event.detail
The full normalized PlatformInitConfig object at the time of the change.
| Field | Type | Description |
|---|---|---|
viewer | object | Current viewer/user settings |
viewer.userId | string | null | The active user ID |
viewer.loggedIn | boolean | Whether the user is authenticated |
viewer.subscribed | boolean | Whether the user has an active subscription |
ui | object | Current UI settings |
ui.mode | 'web' | 'app' | Rendering mode |
ui.actions | object | Registered action callbacks |
access | object | Current access rules per game type |
window.addEventListener('mindtraining:config', function (event) {
const config = event.detail
console.log('User logged in:', config.viewer?.loggedIn)
console.log('User subscribed:', config.viewer?.subscribed)
console.log('Active access rules:', config.access?.games)
})Game and navigation events
The following events are emitted during gameplay and navigation. Use them for analytics, tracking, host-side integrations, and observability.
mindtraining:game:loaded
Fired when: a game session or game screen is ready for user interaction.
When to use: use this event to track internal game pageviews, measure which games actually load, or trigger host-side logic based on game type.
event.detail
| Field | Type | Description |
|---|---|---|
gameType | string | Game type (e.g. crossword, sudoku) |
gameId | string | Unique game identifier |
variant | string | Game variant (e.g. default, mini) |
route | string | Internal route path |
source | string | Source of the game (e.g. today, archive) |
window.addEventListener('mindtraining:game:loaded', function (event) {
Analytics.track('mindtraining_game_loaded', event.detail)
})mindtraining:game:playing
Fired when: the user starts real interaction with the game (e.g. first move or input).
When to use: use this event to distinguish between a game loaded and a game actually played, measure activation, or track engagement.
event.detail
| Field | Type | Description |
|---|---|---|
gameType | string | Game type |
gameId | string | Unique game identifier |
variant | string | Game variant |
startedAt | string | ISO 8601 timestamp when play started |
window.addEventListener('mindtraining:game:playing', function (event) {
Analytics.track('mindtraining_game_playing', event.detail)
})mindtraining:game:completed
Fired when: the user finishes a game successfully.
When to use: use this event for complete funnels, difficulty analytics, or host-side ranking and gamification.
event.detail
| Field | Type | Description |
|---|---|---|
gameType | string | Game type |
gameId | string | Unique game identifier |
variant | string | Game variant |
completedAt | string | ISO 8601 timestamp when play ended |
durationMs | number | Duration of the session in milliseconds |
score | number | Final score (if applicable) |
window.addEventListener('mindtraining:game:completed', function (event) {
Analytics.track('mindtraining_game_completed', event.detail)
})mindtraining:game:abandoned
Fired when: the user leaves a game session after play has started and before completing it.
When to use: use this event to detect friction, measure drop-off by game or variant, or improve retention flows.
event.detail
| Field | Type | Description |
|---|---|---|
gameType | string | Game type |
gameId | string | Unique game identifier |
variant | string | Game variant |
durationMs | number | Time spent before abandoning |
progress | number | Progress (0–1) at abandonment |
window.addEventListener('mindtraining:game:abandoned', function (event) {
Analytics.track('mindtraining_game_abandoned', event.detail)
})mindtraining:game:state:saved
Fired when: the game state is persisted (e.g. for “continue playing” functionality).
When to use: use this event to track retention, “continue playing” flows, or verify that saved state is working correctly.
event.detail
window.addEventListener('mindtraining:game:state:saved', function (event) {
Analytics.track('mindtraining_game_state_saved', event.detail)
})mindtraining:access:blocked
Fired when: the platform detects that a surface (today’s game, archive, etc.) is blocked for the user.
When to use: use this event to trigger contextual paywalls, measure unmet demand, or customize host messages based on the blocked reason.
event.detail
window.addEventListener('mindtraining:access:blocked', function (event) {
Analytics.track('mindtraining_access_blocked', event.detail)
if (event.detail.blockedReason === 'subscription_required') {
Paywall.show({ context: 'game_archive' })
}
})mindtraining:route:changed
Fired when: the internal route of the platform changes (e.g. navigation within the SPA).
When to use: use this event for virtual pageviews, or to sync analytics with the platform’s internal navigation.
event.detail
window.addEventListener('mindtraining:route:changed', function (event) {
Analytics.track('mindtraining_route_changed', event.detail)
})mindtraining:pageview
Fired when: the platform registers a navigable view that is relevant for analytics.
When to use: use this event for pageview tracking in analytics tools, reporting by section and game type, or attribution of internal SPA navigation.
event.detail
| Field | Type | Description |
|---|---|---|
pathname | string | Current route path |
title | string | Page title |
gameType | string | Game type (if applicable) |
gameId | string | Game identifier (if applicable) |
variant | string | Game variant (if applicable) |
source | string | Source of the view (e.g. today, archive) |
window.addEventListener('mindtraining:pageview', function (event) {
Analytics.track('mindtraining_pageview', event.detail)
})mindtraining:user:action
Fired when: the user performs a key interaction (e.g. clicks archive, selects a game).
When to use: use this event to track relevant clicks, run experiments, or instrument UI without wiring each button from the host.
event.detail
| Field | Type | Description |
|---|---|---|
action | string | Action identifier (e.g. click_archive) |
location | string | UI location (e.g. home_header) |
gameType | string | Game type (if applicable) |
variant | string | Game variant (if applicable) |
index | number | Zero-based position of the clicked game block/item in its rendered list (if applicable) |
url | string | External URL selected from navigation (if applicable) |
Current action values:
| Value | Meaning |
|---|---|
click_play | User clicks a play/open game CTA |
click_archive | User clicks an archive/history CTA |
click_start | User starts a game from the intermediate screen |
click_back | User clicks a back/navigation CTA |
click_nav | User clicks an external navigation link |
Current location values:
| Value | Surface |
|---|---|
home_block_game | Game card/block on the home screen |
home_block_dynamic_games | Dynamic games block on the home screen |
historical_game_block | Historical/recent games block |
intermediate_game_screen | Intermediate screen shown before entering a game |
game_navigation | In-game navigation header |
site_nav | Site navigation menu |
game_navigation_menu | In-game navigation menu |
window.addEventListener('mindtraining:user:action', function (event) {
Analytics.track('mindtraining_user_action', event.detail)
})mindtraining:share:requested
Fired when: the user attempts to share content from the platform.
When to use: use this event for share-intent analytics, or to bridge with the host app's native share flow.
event.detail
| Field | Type | Description |
|---|---|---|
gameType | string | Game type |
gameId | string | Game identifier |
url | string | URL to share |
title | string | Title to share |
window.addEventListener('mindtraining:share:requested', function (event) {
Analytics.track('mindtraining_share_requested', event.detail)
})mindtraining:error
Fired when: a flow, load, or interaction error occurs that is relevant to the host.
When to use: use this event for observability, alerting, or host-side fallback UI.
event.detail
| Field | Type | Description |
|---|---|---|
scope | string | Error scope (e.g. game-load) |
code | string | Error code (e.g. GAME_DATA_FETCH_FAILED) |
message | string | Human-readable message |
recoverable | boolean | Whether the user can recover from the error |
window.addEventListener('mindtraining:error', function (event) {
Analytics.track('mindtraining_error', event.detail)
if (!event.detail.recoverable) {
ErrorUI.show(event.detail)
}
})Recommended events for analytics
A practical approach for host analytics is to listen to:
mindtraining:ready- to know when initialization is safemindtraining:config- to track configuration changesmindtraining:game:loaded- to measure game loadsmindtraining:pageview- to track pageviewsmindtraining:game:playing- to measure activationmindtraining:game:completed- to measure completionsmindtraining:access:blocked- to measure unmet demandmindtraining:error- to monitor errors
window.addEventListener('mindtraining:game:loaded', function (event) {
Analytics.track('mindtraining_game_loaded', event.detail)
})
window.addEventListener('mindtraining:game:playing', function (event) {
Analytics.track('mindtraining_game_playing', event.detail)
})
window.addEventListener('mindtraining:pageview', function (event) {
Analytics.track('mindtraining_pageview', event.detail)
})
window.addEventListener('mindtraining:access:blocked', function (event) {
Analytics.track('mindtraining_access_blocked', event.detail)
})