BabylonJS/Babylon.js · error
WebXR not supported on this browser.
Error message
WebXR not supported on this browser.
What it means
initializeAsync() checks for the WebXR API (navigator.xr). If the browser (or the current context, e.g. non-secure origin or an unsupported environment) does not expose navigator.xr, WebXR is simply unavailable and the manager throws immediately instead of starting a doomed session.
Source
Thrown at packages/dev/core/src/XR/webXRSessionManager.ts:345
if (this._xrNavigator.xr.native) {
return new NativeXRRenderTarget(this);
} else {
options = options || WebXRManagedOutputCanvasOptions.GetDefaults(engine);
options.canvasElement = options.canvasElement || engine.getRenderingCanvas() || undefined;
return new WebXRManagedOutputCanvas(this, options);
}
}
/**
* Initializes the manager
* After initialization enterXR can be called to start an XR session
* @returns Promise which resolves after it is initialized
*/
public async initializeAsync(): Promise<void> {
// Check if the browser supports webXR
this._xrNavigator = navigator;
if (!this._xrNavigator.xr) {
throw new Error("WebXR not supported on this browser.");
}
}
/**
* Initializes an xr session
* @param xrSessionMode mode to initialize
* @param xrSessionInit defines optional and required values to pass to the session builder
* @returns a promise which will resolve once the session has been initialized
*/
public async initializeSessionAsync(xrSessionMode: XRSessionMode = "immersive-vr", xrSessionInit: XRSessionInit = {}): Promise<XRSession> {
// A WebGPU engine requires a WebGPU-compatible XR session (per the WebXR/WebGPU binding spec).
// The "webgpu" feature descriptor is requested as a *required* feature: a WebGPU engine cannot
// fall back to a WebGL-compatible session, so if the UA/device cannot provide one we let
// requestSession reject and surface that error to the caller rather than silently handing back
// an incompatible session. WebGL engines leave xrSessionInit untouched.
if (this._engine?.isWebGPU) {
const requiredFeatures = xrSessionInit.requiredFeatures ? [...xrSessionInit.requiredFeatures] : [];
if (!requiredFeatures.includes("webgpu")) {
View on GitHub (pinned to 0592b347b8)
Solutions
- Serve the page over HTTPS (or localhost) so navigator.xr is exposed.
- Feature-detect first: `if (!('xr' in navigator))` and show a fallback UI / use Babylon's WebXRExperienceHelper fallback instead of calling initializeAsync.
- Use a browser that supports WebXR (Chrome/Edge with a headset or Emulator) and enable the required flags.
- For iframes, add `<iframe allow="xr-spatial-tracking ...">` and the correct Permissions-Policy header.
- On unsupported platforms, fall back to non-XR rendering (camera + device orientation) or a polyfill-based UX.
Example fix
// before
const xr = new WebXRSessionManager(scene);
await xr.initializeAsync(); // throws on Safari
// after
if ('xr' in navigator) {
const xr = new WebXRSessionManager(scene);
await xr.initializeAsync();
} else {
showNonXRWarning(); // fallback experience
} Defensive patterns
Strategy: fallback
Validate before calling
if (!('xr' in navigator)) {
showFallbackExperience();
return;
}
const xr = new WebXRSessionManager(scene);
await xr.initializeAsync(); Type guard
function webxrSupported(): boolean {
return typeof navigator !== 'undefined' && 'xr' in navigator && navigator.xr != null;
} Try / catch
try {
await xr.initializeAsync();
} catch (e) {
if (e instanceof Error && e.message === 'WebXR not supported on this browser.') {
showUnsupportedBrowserDialog();
startNonXRFallback(scene);
return;
}
throw e;
} Prevention
- Feature-detect navigator.xr before any XR code path
- Serve over HTTPS — WebXR requires a secure context
- Add xr-spatial-tracking to iframe allow/Permissions-Policy attributes
- Provide a non-XR fallback (orbit camera / device-orientation) for unsupported browsers
- Test on target browsers early (Safari/iOS lacks WebXR)
When it happens
Trigger: Running in a browser without WebXR support (Safari, Firefox desktop, older Chrome); opening the page over plain http instead of https (WebXR is gated to secure contexts); using an emulator/iframe without xr-spatial-tracking permissions; WebXR disabled in browser flags.
Common situations: Testing on a desktop browser without a headset/emulator; iOS Safari which lacks WebXR entirely; missing the `xr-spatial-tracking` Feature-Policy/Permissions-Policy header when embedding in an iframe; outdated browser version.
Related errors
- Deleting persistent anchors is not supported in this environ
- Anchors are not enabled in your browser
- XRSession.pauseDepthSensing is not supported by this XR runt
- XRSession.resumeDepthSensing is not supported by this XR run
- Invalid Space Warp framebuffer
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/d02475a4b036a5c0.
Report an issue: GitHub.