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();
});