Skip to main content

Vue

Provider

Provide (useVircadia)

First setup your main.ts file to use the Vircadia World SDK using the useVircadia provider composable. Here is an example:

Example: /client/web_babylon_js/src/main.ts
import { createApp } from "vue";
import App from "./App.vue";
// Vuetify styles should load before custom styles
import "@mdi/font/css/materialdesignicons.css";
import "vuetify/styles";
import "./assets/main.css";
import { createPinia } from "pinia";

import {
useVircadia,
DEFAULT_VIRCADIA_INSTANCE_KEY,
Communication,
} from "@vircadia/world-sdk/browser/vue";

import { clientBrowserConfiguration } from "./vircadia.browser.config";

// Vuetify setup
import { createVuetify } from "vuetify";

// App setup
const app = createApp(App);

// Pinia setup
const pinia = createPinia();
app.use(pinia);

// create and register Vuetify instance
const vuetify = createVuetify({
icons: {
defaultSet: "mdi", // This is already the default value - only for display purposes
},
});
app.use(vuetify);

// Initialize Vircadia
const vircadiaWorld = useVircadia({
config: {
serverUrl:
clientBrowserConfiguration.VRCA_CLIENT_WEB_BABYLON_JS_DEFAULT_WORLD_API_URI_USING_SSL
? `https://${clientBrowserConfiguration.VRCA_CLIENT_WEB_BABYLON_JS_DEFAULT_WORLD_API_URI}${Communication.WS_UPGRADE_PATH}`
: `http://${clientBrowserConfiguration.VRCA_CLIENT_WEB_BABYLON_JS_DEFAULT_WORLD_API_URI}${Communication.WS_UPGRADE_PATH}`,
authToken:
clientBrowserConfiguration.VRCA_CLIENT_WEB_BABYLON_JS_DEBUG_SESSION_TOKEN,
authProvider:
clientBrowserConfiguration.VRCA_CLIENT_WEB_BABYLON_JS_DEBUG_SESSION_TOKEN_PROVIDER,
debug: clientBrowserConfiguration.VRCA_CLIENT_WEB_BABYLON_JS_DEBUG,
suppress:
clientBrowserConfiguration.VRCA_CLIENT_WEB_BABYLON_JS_SUPPRESS,
reconnectAttempts: 5,
reconnectDelay: 5000,
},
});

// Make the Vircadia instance available to all components
app.provide(DEFAULT_VIRCADIA_INSTANCE_KEY, vircadiaWorld);

// Mount the app
app.mount("#app");

// Auto-connect to the domain server after mounting, do not await
vircadiaWorld.client.Utilities.Connection.connect();

This registers the client via:

app.provide(DEFAULT_VIRCADIA_INSTANCE_KEY, vircadiaWorld);

And optionally auto-connect after mounting:

vircadiaWorld.client.Utilities.Connection.connect();

Inject (useVircadiaContext)

Then, in your components, you can inject the Vircadia instance using the useVircadiaInstance helper:

import { useVircadiaInstance } from "@vircadia/world-sdk/browser/vue";

const vircadiaWorld = useVircadiaInstance();
if (!vircadiaWorld) {
throw new Error('Vircadia instance not found');
}

Composable

Asset

In our client, we have a composable that manages the environment assets. It leverages the useVircadiaAsset composable:

Example: /client/web_babylon_js/src/composables/useBabylonEnvironment.ts
import { inject, ref } from "vue";

import { HDRCubeTexture, type Scene } from "@babylonjs/core";

import { useAsset, useVircadiaInstance } from "@vircadia/world-sdk/browser/vue";
// ^ Vircadia’s Vue SDK:
// - useAsset: composable to fetch an asset and process from Vircadia’s database.
// - useVircadiaInstance: composable to get the Vircadia World client instance.

// ───────── Babylon Environment loader composable ─────────
// Loads multiple HDR environments into a Babylon.js scene.
// - Reactive loading state
// - Handles Vircadia asset fetching
// - Applies HDR textures to the scene
export function useBabylonEnvironment(
hdrFiles: string[], // list of HDR file names on the Vircadia server in the entity.entity_assets table
) {
const isLoading = ref(false);
// ^ tracks whether we’re already loading—prevents duplicate calls

const vircadiaWorld = inject(useVircadiaInstance());

if (!vircadiaWorld) {
throw new Error("Vircadia instance not found");
}
// ^ Vircadia World client instance used by useAsset

async function loadAll(scene: Scene) {
// ^ the main entry point: loads each HDR file in sequence

if (!scene) {
console.error("Scene not found");
return;
}

if (isLoading.value) {
console.error("Environment loader already in progress");
return;
}

isLoading.value = true;

try {
for (const fileName of hdrFiles) {
// ───────── Vircadia asset fetch ─────────
const asset = useAsset({
fileName: ref(fileName), // reactively watch the file name
instance: vircadiaWorld, // the Vircadia World client connection
useCache: true, // cache the download in IndexedDB
});
await asset.executeLoad(); // actually fetches the blob from Vircadia’s assets

// once loaded, the SDK exposes a blob URL we can feed into Babylon
const url = asset.assetData.value?.blobUrl;
if (!url) throw new Error(`Failed to load ${fileName}`);

// ───────── Babylon.js HDR setup ─────────
const hdr = new HDRCubeTexture(
url, // the blob URL
scene, // attach to our scene
512, // size of each cube face
false, // no generateMipMaps
true, // invertY
false, // no async generation
true, // prefiltered
);
// wait for the texture to finish loading internally
await new Promise<void>((resolve) =>
hdr.onLoadObservable.addOnce(() => resolve()),
);

// apply it as the scene’s environment (lighting + skybox)
scene.environmentTexture = hdr;
scene.environmentIntensity = 1.2;
scene.createDefaultSkybox(hdr, true, 1000);
}
} catch (e) {
console.error(e); // log any Vircadia-load or Babylon errors
} finally {
isLoading.value = false;
}
}

return { isLoading, loadAll };
// ^ expose to your component so you can trigger loadAll() and react to isLoading
}

Entity

To interact with the client, you simply query to the tables in the database using the vircadiaWorld.client.Utilities.Connection.query method.

For example, to create an entity, you can do the following:

const result = await vircadiaWorld.client.Utilities.Connection.query({
query: "INSERT INTO entity.entities (general__entity_name, group__sync, general__expiry__delete_since_updated_at_ms) VALUES ($1, $2, $3) RETURNING general__entity_name",
parameters: [
entityName.value,
"public.NORMAL",
120000, // 120 seconds timeout for inactivity
],
});