Web Integration
A host-presented WebView drives the native AR engine with TreedisVPS.send(type, data). The web API shares the native controller command names, coordinate frame and structured events. See the Swift guide and Kotlin guide for VPSWebBridge, host adapters, and the complete command/event tables.
Initialization
Define event callbacks before sending commands. The host must already have installed the bridge and be accepting commands. Native controllers queue commands until their AR view is attached; the host supplies tour loading, route requests and environment handling.
function send(type, data = {}) {
TreedisVPS.send(type, data);
}
window.onLocalizationStatusChanged = (localized) => {
// Show or hide your scanning UI.
};
window.onLoadingProgress = (step, progress) => {
// Update your loading UI; progress is 0..1.
};
window.onError = (error) => {
// Show a useful host error state.
};
// Optional: only needed when an overlay forwards taps in a different scale.
send('setWindowSize', { width: window.innerWidth, height: window.innerHeight });
send('setEnvironment', { environment: 'Production' });
send('setTourInfo', { slug: 'your-tour-slug' });
send('startLocalization');
The host handles setEnvironment by configuring its API/CDN clients and VPS server. Environment names and account configuration belong to the host adapter; the SDK has no hardcoded SaaS or Connected Workers environment.
Common commands
| Command | Data | Behavior |
|---|---|---|
setTourInfo |
{slug, matterId?} |
Host loads the experience; omitted model uses the tour's model |
startLocalization |
{} |
Starts scanning/retrying until localized |
relocalize |
{} |
Requests another localization check |
reset |
{} |
Ends the experience and clears content |
startNavigation |
{destinationName, x, y, z, navigationType?} |
Navigates to a position using the host route provider |
stopNavigation |
{} |
Clears the route |
recomputePath |
{} |
Requests a route from the current pose |
setPath |
{destinationName, nodes:[{x,y,z}]} |
Follows a supplied single-floor path without automatic rerouting |
confirmTeleport / endTeleport |
{} |
Begins / ends a physical floor change |
showARObject / hideARObject |
{id: '123', type: 'TAG'} |
Changes object visibility; ID is a string |
setMeshVisible |
{visible: true} |
Shows the scan mesh overlay |
setLocalizationHint |
{x,y,z,radius?,floorMinY?,floorMaxY?} |
Applies a hint in tour coordinates |
clearLocalizationHint |
{} |
Removes the hint |
getPosition, raycastTag |
{requestId?} |
Requests position / centre-view tag |
captureCameraFrame |
{requestId?,uploadUrl?} |
Requests camera-only JPEG, optionally uploaded |
click |
{x,y} |
Forwards an intercepted top-left-origin tap |
Use public Y-up metre coordinates for every position, including localization hints. Convert external marker coordinates in the host before sending a hint. Object IDs are strings; integer JSON IDs are normalized to strings. Route requests use a destination position and the host route provider.
send('startNavigation', {
destinationName: 'Conference Room A',
x: 2, y: 1, z: -4,
navigationType: 'shortest'
});
window.onNavigationTeleport = (direction, floorName, type) => {
// Ask for confirmation. Send confirmTeleport when the user starts moving
// between floors; send endTeleport only when they physically arrive.
};
window.onNavigationDistance = (metres) => {};
window.onNavigationComplete = () => {};
window.onPose = (x, y, z, headingDegrees) => {};
window.onARObjectClick = (id, type) => {};
Thread commands support placement mode, start/confirm/cancel, spawn/update, completion, and removal. The host persists threads and implements push, integrity, sign-out, UI loading and session diagnostics through its adapters.
Events
Most events call their matching named global function with positional arguments. They do not arrive inside onMessage:
window.onPosition = (result) => {
// {requestId, localized, pose?, rotation?}; rotation is a forward vector.
};
window.onRaycast = (result) => {};
window.onCameraFrame = (result) => {};
window.onThreadPlaced = (x, y, z, sweepID) => {};
window.onLocalizationResult = (success, confidence) => {};
Diagnostic messages use the same structured callback data as the other events:
window.onMessage = ({ type, data }) => {
if (type === 'localizationWarning') {
// Soft scanning hint, not proof that the AR anchor has been lost.
}
if (type === 'localizationSuccess') {
// An accepted localization.
}
};
Diagnostic message types include log, localization_status (Searching/Success), localizationWarning, localizationSuccess, warning and info. These provide feedback alongside the typed AR events.
Query commands keep data.requestId in their structured replies. Send data as an object, including when calling receive(json) through a host adapter.
Host requirements
On native iOS/Android, construct and retain VPSWebBridge before loading a WKWebView/Android WebView, allow only the intended HTTPS origins, and disconnect it when removing the page. Android requires a current System WebView with web-message and document-start support. The bridge exposes commands only to the main frame and delivers callbacks only to allowed origins. The app owns navigation policy, login/cookies, permission prompts, and page presentation.
There is no browser-only AR engine in this bridge. A page opened in ordinary Safari does not gain TreedisVPS.send unless an AR host provides it. See Troubleshooting for host and readiness checks.

