Skip to content

create() API Reference

XRGallery.create(options): Promise<ViewerInstance>

Create and mount an XRGallery viewer instance.

const viewer = await XRGallery.create(options);

Parameters

CreateOptions

Parameter Type Required Description
element string \| HTMLElement \| null No Where to mount the viewer. CSS selector, DOM element, or React ref. Defaults to document.body.
sceneId string One of sceneId or config Scene ID to load from XRGallery cloud.
config XRGalleryConfig One of sceneId or config Inline tour configuration object.
firebaseConfig FirebaseConfig No Override the default Firebase config. Only used with sceneId.
title string No Sets document.title.

Mutually exclusive

You must provide exactly one of sceneId or config. Providing both (or neither) will throw an error.


Element Resolution

The element parameter is flexible:

XRGallery.create({ element: '#app', sceneId: '...' });
XRGallery.create({ element: '.viewer-container', sceneId: '...' });
const container = document.getElementById('viewer');
XRGallery.create({ element: container, sceneId: '...' });
const ref = useRef(null);
XRGallery.create({ element: ref.current, sceneId: '...' });
// Looks for existing <canvas id="renderCanvas">, falls back to document.body
XRGallery.create({ sceneId: '...' });

The viewer creates a <canvas id="renderCanvas"> inside the target element with width: 100% and height: 100%. The container element should have explicit dimensions.


Return Value

ViewerInstance

Method Return Description
dispose() void Stops the render loop and releases GPU/audio resources. Safe to call multiple times.
isDisposed() boolean Returns true if dispose() has been called.
const viewer = await XRGallery.create({ element: '#app', sceneId: 'abc123' });

// Check state
console.log(viewer.isDisposed()); // false

// Clean up
viewer.dispose();
console.log(viewer.isDisposed()); // true

// Safe to call again (no-op)
viewer.dispose();

Examples

Scene ID (XRGallery Cloud)

const viewer = await XRGallery.create({
  element: '#app',
  sceneId: 'abc123',
  title: 'Museum Virtual Tour'
});

The viewer uses the built-in XRGallery Firebase config to fetch the tour from Firestore. Analytics, password protection, and branding are handled automatically.

Inline Config (Self-Hosted)

const viewer = await XRGallery.create({
  element: '#app',
  config: {
    experience: {
      title: "Gallery Tour",
      defaultFOV: 1.2
    },
    stages: [
      {
        id: "entrance",
        name: "Entrance Hall",
        skybox: { type: "image", url: "/images/entrance-360.jpg" },
        hotspots: [
          {
            id: "welcome",
            type: "info",
            position: { x: 0, y: 1.6, z: -5 },
            label: "Welcome",
            infoTitle: "Welcome!",
            infoDescription: "Look around by dragging. Click hotspots to interact."
          },
          {
            id: "to-gallery",
            type: "navigation",
            position: { x: 3, y: 0, z: -3 },
            label: "Enter Gallery",
            targetStageId: "gallery",
            portalEffectStyle: "enhanced"
          }
        ]
      },
      {
        id: "gallery",
        name: "Main Gallery",
        skybox: { type: "image", url: "/images/gallery-360.jpg" },
        hotspots: [
          {
            id: "back",
            type: "navigation",
            position: { x: -3, y: 0, z: 2 },
            label: "Back",
            targetStageId: "entrance"
          }
        ]
      }
    ],
    globalAudio: {
      url: "/audio/ambient.mp3",
      volume: 0.3,
      loop: true
    }
  }
});

Custom Firebase Config

For connecting to your own Firebase project instead of XRGallery cloud:

const viewer = await XRGallery.create({
  element: '#app',
  sceneId: 'my-scene-id',
  firebaseConfig: {
    apiKey: "YOUR_API_KEY",
    authDomain: "your-project.firebaseapp.com",
    projectId: "your-project",
    storageBucket: "your-project.firebasestorage.app",
    messagingSenderId: "123456789",
    appId: "1:123456789:web:abc123"
  }
});

Error Handling

create() throws if initialization fails:

try {
  const viewer = await XRGallery.create({
    element: '#app',
    sceneId: 'abc123'
  });
} catch (error) {
  console.error('Failed to create viewer:', error.message);
  // Common errors:
  // - "XRGallery.create() requires exactly one of sceneId or config"
  // - "No element found for selector '#missing'"
  // - "Canvas element not found"
}

Legacy API

XRGallery.init(options)

The low-level initialization function used internally by viewer.html. Still available but not recommended for new integrations.

// Hosted mode
await XRGallery.init({
  firebaseConfig: { apiKey: '...', ... },
  sequenceId: 'abc123'
});

// Export mode
await XRGallery.init({
  config: { experience: {...}, stages: [...] }
});

Key differences from create():

  • Does not accept element — always looks for <canvas id="renderCanvas">
  • Does not return a ViewerInstance with dispose()
  • Uses sequenceId instead of sceneId
  • Requires explicit firebaseConfig for cloud mode

Use create() for all new code.