Skip to content

Permission Handling ​

When integrating Kivicube on the Web, the three permission areas that matter most are:

  • camera
  • motion and orientation (gyroscope)
  • media autoplay restrictions

iframe Permission Declaration ​

When the plugin opens the iframe, it automatically writes a set of allow capabilities including:

  • xr-spatial-tracking
  • camera
  • microphone
  • autoplay
  • fullscreen
  • gyroscope
  • accelerometer

So in most cases you do not need to build that string manually. Just make sure you do not overwrite it.

Camera Permission ​

When It Is Needed ​

  • Image AR
  • Basic AR/Gyroscope
  • any scene that depends on the real camera feed

What Happens When the User Rejects It ​

The plugin emits an error event with a marked payload:

js
iframe.addEventListener('error', (event) => {
  if (event.detail?.isUserDeniedCamera) {
    showCameraPermissionGuide();
  }
});

Compatibility Failure ​

If the current browser cannot open the camera at all, you may also receive an incompatibility event.

Motion and Orientation Permission ​

This mainly affects scenes that enable the gyroscope.

What Happens When the User Rejects It ​

js
iframe.addEventListener('error', (event) => {
  if (event.detail?.isUserDeniedGyroscope) {
    showGyroscopeGuide();
  }
});

Extra Collection Property ​

Collections support:

js
hideGyroscopePermission: true

This hides the default gyroscope permission prompt, which is useful on devices where that feature is no longer needed, such as iOS.

Media Autoplay Restrictions ​

Even if camera permission is granted, video and audio playback can still be limited by browser autoplay policies.

The most common triggers are:

  • forcing the Start Now Button to stay hidden
  • trying to play media outside a user gesture
  • stricter policies on iOS or in-app WebViews
  1. listen for error
  2. listen for incompatibility
  3. provide separate host-layer guidance for camera and gyroscope permissions
  4. prepare a degraded path when media playback fails
js
iframe.addEventListener('error', (event) => {
  const detail = event.detail || {};

  if (detail.isUserDeniedCamera) {
    showToast('Please allow camera access and try again.');
    return;
  }

  if (detail.isUserDeniedGyroscope) {
    showToast('Please allow motion and orientation access and try again.');
    return;
  }

  showToast(detail.message || 'The experience is temporarily unavailable.');
});

iframe.addEventListener('incompatibility', () => {
  showUnsupportedDialog();
});