English
Appearance
English
Appearance
For the full event list and detail types, see iframe Events.
All events are listened for directly on the iframe object.
iframe.addEventListener("eventName", (event) => {
const { detail } = event;
const { api, sceneInfo } = detail;
console.log(api, sceneInfo);
});Except for the standard iframe load and error events, all other plugin events are CustomEvent objects.
Whenever you need business data, read it from detail.
The exact detail shape depends on the event. See each event definition for specifics.
The main events you should listen for on an iframe are flow events. They describe the overall lifecycle of the content, from initialization and asset download through loading, entering the experience, and changing recognition state.
If you want to listen for runtime object events, such as a model click or a video finishing playback, use api.on() from the Advanced API.
load and error are foundational events that may come from either the browser or the plugin layer.
See also: iframe#error_and_load_event_behavior
Whether the other events are available depends on account permissions and domain authorization.
Detailed conditions
| Account type | Domain authorized? | Events available? |
|---|---|---|
| Free / Starter | Unauthorized and cannot purchase authorization | No |
| All users | Unauthorized, but host page is accessed via localhost or LAN IP | Yes |
| Pro / Enterprise | Authorization not purchased | No |
| Pro / Enterprise | Authorized | Yes |
Standard browser event indicating that the iframe page itself has finished loading.
This only means Kivicube page code is running. It does not mean scene assets are fully downloaded.
Any error that occurs inside the plugin triggers this event.
It also fires when the user denies camera permission or gyroscope permission.
Example detection:
iframe.addEventListener("error", (e) => {
if(e.detail?.isUserDeniedCamera) {
console.log('The user denied camera permission');
}
if (e.detail?.isUserDeniedGyroscope) {
console.log('The user denied gyroscope permission');
}
});detail types:
interface ErrorType {
message: string;
isCameraNotFound?: boolean; // Camera not found. The hardware may be missing or broken.
isUserDeniedCamera?: boolean; // User manually denied camera permission
isUserDeniedGyroscope?: boolean; // User manually denied gyroscope permission (iOS)
}
interface ResponseServerError {
message: string;
code: number;
}
interface ErrorCustomEvent {
detail: string | ErrorType | ResponseServerError;
}Common cases include:
Scenes or collections also trigger incompatibility when preflight compatibility checks fail.
Typical cases include:
The detail structure is not fully fixed, but it often includes marker objects such as unsupportCamera, so it is best treated as a signal to show a compatibility fallback UI.
Triggered when scene or collection data is available and opening begins.
On scene pages, event.detail.sceneInfo contains basic scene information, and event.detail.api is the scene advanced API object.
On collection pages, event.detail.collectionInfo contains basic collection information, and event.detail.api is the collection advanced API object.
detail types:
interface ReadyDetail {
sceneInfo: SceneInfo | CollectionInfo;
api: SceneApi | CollectionApi; // See the Advanced API docs for the exact runtime type.
}
interface ReadyCustomEvent {
detail: ReadyDetail;
}Type definitions:
iframe.addEventListener("ready", (event) => {
const { detail } = event;
const { api, sceneInfo, collectionInfo } = detail;
console.log(api, sceneInfo, collectionInfo);
});Triggered when scene assets start downloading.
Triggered when download progress changes. detail ranges from 0.0 to 1.0.
iframe.addEventListener('downloadAssetProgress', (event) => {
console.log(`Download progress: ${(event.detail * 100).toFixed(0)}%`);
});Triggered when asset download finishes.
If the Start Now Button is not hidden, the flow usually waits for the user to click that button before entering loadSceneStart.
If you plan to customize the Start Now Button with advanced APIs, this is also a common moment to call getStartButtonRect() / setStartButtonRect().
Triggered when assets start being loaded into the scene runtime.
Triggered when scene loading finishes.
As a general rule, this is a safe time to register object events, read object lists, and do runtime object processing.
Triggered when the scene actually starts.
For non-recognition scenes, it usually fires quickly. For Image AR or Basic AR/Gyroscope scenes, it means the experience has entered a usable state, even though recognition state may still continue changing.
Triggered when a recognition-based scene successfully tracks the target.
Common uses:
Triggered when a recognition-based scene loses the tracked target.
Triggered when the scene tries to perform an "open webpage" action. detail is usually the target URL.
If you enabled disableOpenUrl, this event still fires, so the host layer can decide whether to:
Triggered when the collection starts cloud recognition.
interface CloudarStartDetail {
collectionId: string;
sceneList: string[];
}Common uses:
Triggered when collection cloud recognition finishes and returns a result.
interface CloudarEndDetail {
sceneId: string;
}detail.sceneId is the matched scene ID for this recognition result.
Triggered when the collection switches to a concrete scene and receives that scene's data.
detail.sceneInfo has the same structure as sceneInfo in a scene ready event.
detail.api has the same type as api in a scene ready event.
Triggered when the collection is about to destroy the current scene and switch to the next one.
interface SceneDestroyDetail {
sceneId: string; // ID of the scene being destroyed
}Usually:
load
-> ready
-> downloadAssetStart
-> downloadAssetProgress
-> downloadAssetEnd
-> loadSceneStart
-> loadSceneEnd
-> sceneStartFor cloud-recognition collections, it is usually:
load
-> ready
-> cloudarStart
-> cloudarEnd
-> sceneReady
-> downloadAssetStart
-> downloadAssetProgress
-> downloadAssetEnd
-> loadSceneStart
-> loadSceneEnd
-> sceneStartFor image-ar collections, it is usually:
load
-> ready
-> cloudarStart
-> cloudarEnd
-> sceneReady
-> downloadAssetStart
-> downloadAssetProgress
-> downloadAssetEnd
-> loadSceneStart
-> loadSceneEnd
-> sceneStart
-> tracked
-> lostTrack
-> cloudarStart
-> cloudarEndFor most projects, it is a good idea to listen for at least:
iframe.addEventListener('ready', onReady);
iframe.addEventListener('downloadAssetProgress', onProgress);
iframe.addEventListener('sceneStart', onSceneStart);
iframe.addEventListener('tracked', onTracked);
iframe.addEventListener('lostTrack', onLostTrack);
iframe.addEventListener('openUrl', onOpenUrl);
iframe.addEventListener('error', onError);
iframe.addEventListener('incompatibility', onIncompatibility);If your project uses a cloud-recognition collection, it is also a good idea to listen for:
iframe.addEventListener('cloudarStart', onCloudarStart);
iframe.addEventListener('cloudarEnd', onCloudarEnd);