JavaScript Navigator xr Property

Beginner
⏱️ 10 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Experimental

What You’ll Learn

navigator.xr is the experimental entry point to the WebXR Device API. Learn feature detection, XRSystem, isSessionSupported(), immersive-vr checks, secure-context rules, five examples, and try-it labs.

01

Kind

Read-only property

02

Returns

XRSystem

03

Status

Experimental

04

Context

Secure (HTTPS)

05

API family

WebXR Device API

06

Key method

isSessionSupported()

Introduction

Virtual reality (VR) and augmented reality (AR) on the web start with one property: navigator.xr. When it exists, you get an XRSystem object that can ask whether a session mode is available and then start an XRSession.

You do not draw immersive scenes with navigator.xr alone. Think of it as the front door: detect it, check support, then request a session (usually from a button click) and render with WebGL / WebGPU or a framework such as Three.js, Babylon.js, or A-Frame.

💡
WebXR vs WebVR

Older tutorials mention navigator.activeVRDisplays and WebVR. That path is deprecated. New projects should use navigator.xr and WebXR.

Understanding the xr Property

The property itself is only the entry point. The useful pieces live on the returned XRSystem object.

  • Feature detect"xr" in navigator (MDN) or truthy navigator.xr.
  • isSessionSupported(mode) — Promise<boolean> for modes like "immersive-vr", "immersive-ar", or "inline".
  • requestSession(mode) — starts an XRSession (usually from a user gesture).
  • devicechange — event when XR devices appear or disappear.
  • Secure context — HTTPS / localhost required.
  • Limited support — depends on browser + hardware; always fall back.

📝 Syntax

General form of the property:

JavaScript
navigator.xr

Value

  • An XRSystem object used to interface with the WebXR Device API (when supported).

Common patterns

JavaScript
// MDN-style feature detect
if ("xr" in window.navigator) {
  // WebXR can be used!
} else {
  // WebXR isn't available
}

// Check immersive VR support (async)
async function checkImmersiveVr() {
  if (!navigator.xr) return false;
  return navigator.xr.isSessionSupported("immersive-vr");
}

// Enable a button only when immersive-vr is supported (MDN XRSystem pattern)
if (navigator.xr) {
  immersiveButton.addEventListener("click", onButtonClicked);
  navigator.xr.isSessionSupported("immersive-vr").then((isSupported) => {
    immersiveButton.disabled = !isSupported;
  });
}

⚡ Quick Reference

GoalCode
Get WebXR systemnavigator.xr
Feature detect"xr" in navigator
Immersive VR supported?await navigator.xr.isSessionSupported("immersive-vr")
Start a sessionawait navigator.xr.requestSession("immersive-vr")
Secure context?window.isSecureContext
Legacy WebVR (avoid)navigator.activeVRDisplays

🔍 At a Glance

Four facts to remember about navigator.xr.

Returns
XRSystem

WebXR entry point

Status
Experimental

Not Baseline

Context
HTTPS

Secure required

Next step
isSessionSupported

Then requestSession

📋 WebVR vs WebXR

Old WebVRModern WebXR
Entry pointnavigator.getVRDisplays() / activeVRDisplaysnavigator.xr (XRSystem)
StatusDeprecated / Non-standardExperimental (current standard path)
Support checkDisplay enumerationisSessionSupported(mode)
Start experienceVRDisplay.requestPresent()requestSession(mode)
Use in new apps?NoYes (with feature detection)

Examples Gallery

Examples follow MDN navigator.xr / XRSystem patterns. Prefer Try It Yourself — many desktops report xr missing or isSessionSupported as false without a headset / compatible browser.

📚 Getting Started

Detect WebXR and confirm you are in a secure context.

Example 1 — Feature Detection

MDN-style support check before using WebXR.

JavaScript
if ("xr" in window.navigator) {
  console.log("WebXR can be used!");
} else {
  console.log("WebXR isn't available");
}
Try It Yourself

How It Works

If the property is missing, skip immersive UI and show a 2D fallback.

Example 2 — Secure Context Check

WebXR needs HTTPS (or localhost). Pair the API check with isSecureContext.

JavaScript
const lines = [
  "xr: " + ("xr" in navigator ? "available" : "missing"),
  "isSecureContext: " + window.isSecureContext,
  "typeof navigator.xr: " + typeof navigator.xr
];
console.log(lines.join("\n"));
Try It Yourself

How It Works

Even when the browser supports WebXR, an insecure http:// origin can block the API.

📈 Practical Patterns

Ask for session support and wire a safe Enter VR button.

Example 3 — isSessionSupported("immersive-vr")

Ask whether immersive VR may be available before advertising a headset button.

JavaScript
async function checkImmersiveVr() {
  if (!("xr" in navigator) || !navigator.xr) {
    return "WebXR not available";
  }
  try {
    const ok = await navigator.xr.isSessionSupported("immersive-vr");
    return "immersive-vr supported: " + ok;
  } catch (err) {
    return "isSessionSupported error: " + err.name;
  }
}

checkImmersiveVr().then(console.log);
Try It Yourself

How It Works

isSessionSupported should not open device pickers — it only advises whether to advertise the mode.

Example 4 — Enable Enter VR Button

MDN XRSystem pattern: disable the button until immersive VR is supported.

JavaScript
const immersiveButton = { disabled: true };

function onButtonClicked() {
  // Call navigator.xr.requestSession("immersive-vr") from a real click
  console.log("User clicked Enter VR (requestSession goes here)");
}

if (navigator.xr) {
  // In a real page: immersiveButton.addEventListener("click", onButtonClicked);
  navigator.xr.isSessionSupported("immersive-vr").then((isSupported) => {
    immersiveButton.disabled = !isSupported;
    console.log("Enter VR disabled: " + immersiveButton.disabled);
  });
} else {
  console.log("No navigator.xr — keep Enter VR disabled");
}
Try It Yourself

How It Works

Start requestSession only from a user gesture after support is confirmed.

Example 5 — Prefer WebXR Over WebVR

Beginner migration helper: choose the modern API when both worlds appear in old docs.

JavaScript
function pickImmersiveApi() {
  if ("xr" in navigator && navigator.xr) {
    return "Use WebXR via navigator.xr";
  }
  if ("activeVRDisplays" in navigator) {
    return "Legacy WebVR detected — do not use for new apps";
  }
  return "No WebXR / WebVR entry point — show 2D fallback";
}

console.log(pickImmersiveApi());
Try It Yourself

How It Works

Teach newcomers one rule: if navigator.xr exists, build on WebXR — not WebVR.

🚀 Common Use Cases

  • Immersive VR experiences — museums, product demos, training sims.
  • Augmented reality — when immersive-ar is supported on the device.
  • Enter VR buttons — enable only after isSessionSupported.
  • Framework apps — Three.js / Babylon.js / A-Frame still start from WebXR.
  • Progressive enhancement — keep a normal 2D page when XR is missing.

🧠 How navigator.xr Works

1

Detect the property

Check "xr" in navigator on a secure page.

Detect
2

Ask about session modes

Call isSessionSupported("immersive-vr") (or AR / inline).

Support
3

Request a session on click

Use requestSession from a user gesture to start XR.

Session
4

Render immersive content

Drive frames with the XRSession (often via WebGL / a framework).

📝 Notes

  • Experimental & Limited availability — not Baseline; feature-detect always.
  • Not Deprecated or Non-standard — Experimental banner only.
  • Secure context required (HTTPS / localhost).
  • Returns XRSystem; main next steps are isSessionSupported() and requestSession().
  • Related: activeVRDisplays, canShare(), wakeLock, Window.

Limited / Experimental Support

navigator.xr belongs to the experimental WebXR Device API and is not Baseline. Support depends on the browser and XR hardware / drivers. Always feature-detect, use HTTPS, call isSessionSupported(), and keep a non-XR fallback.

Experimental · Not Baseline

Navigator.xr

XRSystem entry point — detect WebXR, check session modes, then request a session.

Limited Experimental
Google Chrome WebXR on compatible devices / flags
Limited
Microsoft Edge WebXR / follow Chromium support
Limited
Mozilla Firefox WebXR where enabled / hardware available
Limited
Opera Follow Chromium WebXR support
Limited
Apple Safari Limited / platform-dependent — feature-detect
Limited
Internet Explorer No navigator.xr / WebXR support
Unavailable
xr Limited

Bottom line: Detect navigator.xr, check isSessionSupported for your mode, start sessions from a user gesture, and never require a headset for core page content.

Conclusion

navigator.xr is the experimental front door to WebXR. Detect it on HTTPS, ask isSessionSupported before advertising immersive modes, start sessions from a user gesture, and keep a clear 2D fallback when XR is missing.

Continue with canShare(), activeVRDisplays, or the JavaScript hub.

💡 Best Practices

✅ Do

  • Feature-detect "xr" in navigator
  • Use HTTPS / localhost
  • Call isSessionSupported before enabling Enter VR
  • Start requestSession from a user gesture
  • Prefer WebXR over deprecated WebVR APIs

❌ Don’t

  • Assume Baseline support everywhere
  • Require a headset for core content
  • Build new apps on activeVRDisplays
  • Ignore secure-context requirements
  • Assign to navigator.xr

Key Takeaways

Knowledge Unlocked

Five things to remember about xr

Experimental WebXR entry point — detect, check modes, fall back.

5
Core concepts
02

Status

Experimental

Limited
🔒 03

Context

secure HTTPS

Required
🔎 04

Check

isSessionSupported

Modes
🎯 05

Prefer

WebXR over WebVR

Migrate

❓ Frequently Asked Questions

A read-only XRSystem object — the entry point to the WebXR Device API for VR and AR sessions in the current browsing context.
MDN marks it Experimental and Limited availability (not Baseline). It is not Deprecated or Non-standard. Always feature-detect and provide a non-XR fallback.
Yes. MDN lists navigator.xr as a secure-context feature (HTTPS or localhost) in supporting browsers.
After detecting navigator.xr, call await navigator.xr.isSessionSupported("immersive-vr"). The promise resolves to true or false.
The WebXR Device API. Start with navigator.xr, then isSessionSupported() and requestSession() instead of the old WebVR VRDisplay APIs.
Usually no — starting an immersive session typically requires a user gesture (for example a button click). Check support first, then request the session from a click handler.
Did you know?

navigator.xr existing does not guarantee a headset is plugged in. Always follow up with isSessionSupported() for the mode you want, then only enable Enter VR / Enter AR UI when that check succeeds.

Explore canShare() Next

Check whether share data can be sent with the Web Share API.

canShare() →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful