External Game Component
ExternalGame is a UI block that can be placed inside any type=page node alongside built-in controls. The component renders an iframe that points to a developer-hosted URL and mediates the contract between the ResultFly runtime and the game.
Placement and identification
- Pages keep using the existing
components[]array. This control is available under theGamescategory in Studio and serialized astype: "external_game". - Each instance receives a deterministic
componentId(UUIDv4) during configuration. The ID is injected into the iframe URL/handshake and is later used inside analytics and the session log. - Publishing rules treat this control the same way as native games: it must exist on a page node that is reachable from
app_start.
Configuration schema
Editors supply the following settings when inserting or editing the block:
| Field | Type | Required | Description |
|---|---|---|---|
type | string | ✅ | Always external_game. Used by the renderer to map to the wrapper. |
url | string | ✅ | HTTPS endpoint hosted by the partner. It becomes the iframe src after platform adds query parameters. |
allowedOrigins | string[] | ✅ | Whitelist of origins the wrapper will accept postMessage events from. Editors can add multiple environments (dev, staging, prod). |
height | number | "auto" | ✅ | Nominal height in pixels. When "auto", the wrapper waits for resize events from the game before fixing the height. |
aspectRatio | string | ➖ | e.g. "16:9" or "4:5". Used to compute placeholder height before the iframe responds. |
loadingMode | "eager" | "lazy" | ➖ | Controls whether the iframe boots immediately or when scrolled into view. Defaults to "eager" for gameplay-critical blocks. |
initPayload | object | ➖ | Arbitrary JSON editors pass to the game. Delivered inside the initialization message. |
timeoutMs | number | ➖ | Override for handshake timeout (default 8 000 ms). Prevents hung games from blocking the page. |
analyticsTags | string[] | ➖ | Optional list of custom labels emitted with every game telemetry event. |
All configuration values are stored in platform-spec and surfaced through Studio forms. Validation happens both client-side and during publishing to ensure URLs are HTTPS and within the allowed domain list configured by admins.
Runtime behavior
- Iframe creation — the renderer constructs an iframe with
sandbox="allow-scripts allow-pointer-lock allow-popups"andreferrerpolicy="strict-origin-when-cross-origin".allow-same-originis omitted by default to keep the iframe isolated; admins can toggle it per block only when the target origin belongs to ResultFly. - Query parameters — the wrapper appends read-only context parameters to the
url:resultflySession– unique session identifier for the user visit.resultflyPage– current page node ID.resultflyComponent– component UUID.resultflyLocale–ll-CClocale of the runtime.resultflyPreview–"true"when running inside Studio preview.
- Handshake — after the iframe fires
load, the wrapper sendspostMessage({ type: "resultfly:init", payload })with the context payload described in the Contract & SDK doc. - Telemetry bridging — messages coming back from the iframe are validated against the contract. The wrapper forwards accepted events to the ResultFly analytics bus (component progress, completion, error).
- Error gating — if the iframe fails to acknowledge (
external-game.ready) within the configured timeout, the component renders a fallback UI informing the user that the game is unavailable and also emits an error event.
Studio preview and publishing
- When the block is opened in Studio preview, we use the same runtime wrapper but tag the session as preview. Editors can change URLs and immediately verify the contract without publishing.
- During publish, the pipeline performs a lightweight health check:
- Resolve DNS + validate HTTPS certificate.
- Fire a
HEADrequest to the provided URL. (No code execution—just availability.) - Warn if response is not
<200, 400)or if the host is not on the organization allowlist.
- Projects may include multiple external games. Each block maintains its own health status so partial outages do not block a release if the admin accepts the risk.
Responsibilities and guarantees
- ResultFly guarantees isolation via sandboxed iframes, ensures that only allowed origins can send data, and records analytics based on validated events.
- External developers are responsible for hosting, performance, creative assets, accessibility compliance inside the iframe, and handling the contract defined in the integration doc.
- Editors remain responsible for keeping the configuration accurate (URL, allowed origins, timeouts) and verifying the experience before publishing.
Last updated on