Events
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.
Event Scope
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.
Trigger Conditions
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 |
load
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.
error
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:
- the scene or collection ID does not exist
- camera permission was denied
- motion and orientation permission was denied on iOS
- asset download failed
incompatibility
Scenes or collections also trigger incompatibility when preflight compatibility checks fail.
Typical cases include:
- the current browser does not support the required camera capability
- the current in-app WebView is not suitable for WebAR
- the current mode is unavailable on this client
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.
ready
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);
});downloadAssetStart
Triggered when scene assets start downloading.
downloadAssetProgress
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)}%`);
});downloadAssetEnd
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().
loadSceneStart
Triggered when assets start being loaded into the scene runtime.
loadSceneEnd
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.
sceneStart
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.
tracked
Triggered when a recognition-based scene successfully tracks the target.
Common uses:
- hide host-layer scan guidance
- show a custom photo button
- fire analytics
lostTrack
Triggered when a recognition-based scene loses the tracked target.
openUrl
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:
- show a second confirmation dialog
- route through its own navigation system
- record analytics before navigating
Collection-Only Events
sceneReady
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.
sceneDestroy
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
}Event Order Reference
Scene
Usually:
load
-> ready
-> downloadAssetStart
-> downloadAssetProgress
-> downloadAssetEnd
-> loadSceneStart
-> loadSceneEnd
-> sceneStartCollection
Usually:
load
-> ready
-> sceneReady
-> downloadAssetStart
-> downloadAssetProgress
-> downloadAssetEnd
-> loadSceneStart
-> loadSceneEnd
-> sceneStartRecommended Listener Set
For 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);