JavaScript Navigator getVRDisplays() Method

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

What You’ll Learn

navigator.getVRDisplays() asked the browser for connected VR headsets as VRDisplay objects. Learn the Promise result, how it differs from activeVRDisplays, why it is deprecated and non-standard, and how to move to WebXR with five examples and try-it labs.

01

Kind

Method

02

Returns

Promise<VRDisplay[]>

03

Status

Deprecated · Non-standard

04

API family

Old WebVR

05

Related

activeVRDisplays

06

Modern path

navigator.xr

Introduction

Before WebXR, browsers experimented with WebVR. One entry point was navigator.getVRDisplays() — “which VR displays are available?”

That Promise resolved to an array of VRDisplay objects. From there, legacy apps could inspect display IDs and start presenting. Today you should not start new projects on WebVR.

⚠️
Available vs presenting

getVRDisplays() listed connected / known displays. activeVRDisplays listed only displays that were already presenting.

Understanding the getVRDisplays() Method

  • No parameters — call navigator.getVRDisplays().
  • Returns a Promise — resolves to an array of VRDisplay objects.
  • Empty array — no displays found (or VR idle / unsupported path).
  • Missing method — typical on modern browsers without WebVR.
  • Not for new apps — use WebXR (navigator.xr) instead.

📝 Syntax

Legacy WebVR form:

JavaScript
navigator.getVRDisplays()

Parameters

  • None.

Return value

  • A Promise that fulfills with an array of VRDisplay objects.

Modern replacement sketch

JavaScript
if (navigator.xr) {
  const ok = await navigator.xr.isSessionSupported("immersive-vr");
  console.log("immersive-vr supported:", ok);
  // Later: await navigator.xr.requestSession("immersive-vr");
} else {
  console.log("WebXR not available — use a framework or 2D fallback");
}

⚡ Quick Reference

GoalCode
Detect legacy APItypeof navigator.getVRDisplays === "function"
List available displaysawait navigator.getVRDisplays()
Count displays(await navigator.getVRDisplays()).length
Presenting onlynavigator.activeVRDisplays (also legacy)
Modern detect"xr" in navigator
WebXR VR mode?await navigator.xr.isSessionSupported("immersive-vr")

🔍 At a Glance

Four facts to remember about navigator.getVRDisplays().

Returns
Promise

VRDisplay array

Status
Deprecated

+ Non-standard

Family
WebVR

Superseded

Prefer
navigator.xr

WebXR Device API

📋 WebVR vs WebXR Entry Points

WebVR (getVRDisplays)WebXR (navigator.xr)
StatusDeprecated / Non-standardCurrent immersive standard path
What you getVRDisplay[] via PromiseXRSystem → sessions
Start experienceLegacy present APIs on VRDisplayrequestSession("immersive-vr")
New projectsAvoidPrefer (or use a framework)

Examples Gallery

Examples feature-detect first. On most modern machines without WebVR you will see a missing method or an empty array — that is the expected beginner outcome.

📚 Getting Started

Detect the legacy method and query available displays.

Example 1 — Feature Detection

Check whether getVRDisplays exists before calling it.

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

How It Works

If WebVR is missing but navigator.xr exists, follow the WebXR path instead.

Example 2 — List Available Displays

Await the Promise and report how many VRDisplay objects were returned.

JavaScript
async function listVrDisplays() {
  if (typeof navigator.getVRDisplays !== "function") {
    return "getVRDisplays not supported";
  }
  try {
    const displays = await navigator.getVRDisplays();
    return "VR displays found: " + displays.length;
  } catch (err) {
    return "Error: " + err.name;
  }
}

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

How It Works

Always wrap the call so missing support does not throw into UI code.

📈 Practical Patterns

Inspect display fields, compare with active displays, and migrate to WebXR.

Example 3 — Inspect displayId / displayName

When displays exist, log identifying fields from each VRDisplay.

JavaScript
async function inspectVrDisplays() {
  if (typeof navigator.getVRDisplays !== "function") {
    return "API missing";
  }
  const displays = await navigator.getVRDisplays();
  if (!displays.length) return "No VR displays";
  return displays
    .map((d, i) => {
      return (
        "#" + i +
        " id=" + d.displayId +
        " name=" + (d.displayName || "n/a") +
        " presenting=" + !!d.isPresenting
      );
    })
    .join("\n");
}

inspectVrDisplays().then(console.log).catch((err) => {
  console.log("Error: " + err.name);
});
Try It Yourself

How It Works

isPresenting on a listed display helps relate this API to activeVRDisplays.

Example 4 — Available vs Presenting

Compare getVRDisplays() with the legacy activeVRDisplays property.

JavaScript
async function compareVrApis() {
  const result = {
    getVRDisplays: "missing",
    availableCount: null,
    activeVRDisplays: "missing",
    presentingCount: null
  };

  if (typeof navigator.getVRDisplays === "function") {
    result.getVRDisplays = "available";
    try {
      const displays = await navigator.getVRDisplays();
      result.availableCount = displays.length;
    } catch (err) {
      result.availableCount = "error:" + err.name;
    }
  }

  if ("activeVRDisplays" in navigator) {
    result.activeVRDisplays = "available";
    result.presentingCount = navigator.activeVRDisplays.length;
  }

  return JSON.stringify(result);
}

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

How It Works

Both APIs are legacy. Use the comparison only when reading old WebVR tutorials.

Example 5 — Prefer WebXR Instead

Beginner migration helper: detect WebXR and check immersive-vr support.

JavaScript
async function preferWebXr() {
  if (!navigator.xr) {
    return {
      ok: false,
      reason: "no-navigator-xr",
      tip: "Use A-Frame / Three.js / Babylon.js or a 2D fallback"
    };
  }
  try {
    const immersiveVr = await navigator.xr.isSessionSupported("immersive-vr");
    return {
      ok: true,
      reason: "webxr",
      immersiveVr: immersiveVr,
      tip: "Call requestSession after a user gesture when ready"
    };
  } catch (err) {
    return { ok: false, reason: err.name };
  }
}

preferWebXr().then((result) => console.log(JSON.stringify(result)));
Try It Yourself

How It Works

This is the path new immersive apps should take — not getVRDisplays().

🚀 Common Use Cases

  • Legacy sample reading — understand old WebVR demos and blog posts.
  • Headset inventory (historical) — count connected VRDisplay devices.
  • Presenting vs available — compare with activeVRDisplays in old code.
  • Migration planning — map WebVR entry points to navigator.xr.
  • Framework choice — prefer A-Frame, Three.js, or Babylon.js for cross-browser XR.

🧠 How navigator.getVRDisplays() Worked

1

Feature-detect

Confirm typeof navigator.getVRDisplays === "function".

Detect
2

Await displays

The Promise resolves to zero or more VRDisplay objects.

Query
3

Inspect / present (legacy)

Old apps used display IDs and present APIs on each display.

Legacy
4

Migrate to WebXR

Use navigator.xr (or a framework) for new immersive work.

📝 Notes

  • Deprecated & Non-standard — MDN status banners for both (not Experimental).
  • Part of old WebVR; superseded by the WebXR Device API.
  • Usually missing on modern browsers without a headset / WebVR support.
  • Related: javaEnabled(), activeVRDisplays, xr, Window.

Deprecated / Non-standard Support

navigator.getVRDisplays() is deprecated and non-standard. It belonged to the old WebVR API and is missing in most modern browsers. Prefer navigator.xr or a maintained XR framework, and always feature-detect before calling.

Deprecated · Non-standard

Navigator.getVRDisplays()

Promise → VRDisplay[] — legacy WebVR entry point; migrate to WebXR.

Legacy Deprecated
Google Chrome WebVR removed — use WebXR where available
Unavailable
Microsoft Edge Prefer WebXR (Chromium)
Unavailable
Opera Prefer WebXR where available
Unavailable
Mozilla Firefox Legacy WebVR era ended — feature-detect
Unavailable
Apple Safari No WebVR getVRDisplays path
Unavailable
Internet Explorer No WebVR / WebXR support
Unavailable
getVRDisplays() Removed / rare

Bottom line: Do not ship new WebVR code. Detect navigator.xr, use isSessionSupported / requestSession, or adopt A-Frame, Three.js, or Babylon.js.

Conclusion

navigator.getVRDisplays() listed available VR headsets in the deprecated WebVR era. Learn it to read old samples, then build new immersive experiences with navigator.xr or a maintained framework.

Continue with javaEnabled(), xr, or the JavaScript hub.

💡 Best Practices

✅ Do

  • Feature-detect before calling
  • Prefer navigator.xr for new VR/AR
  • Provide a non-XR 2D fallback
  • Use frameworks for cross-browser XR
  • Treat empty arrays as a normal result

❌ Don’t

  • Start new apps on WebVR
  • Assume headsets exist without detection
  • Ignore WebXR migration docs
  • Rely on vendor-prefixed WebVR leftovers
  • Block the whole site when VR is missing

Key Takeaways

Knowledge Unlocked

Five things to remember about getVRDisplays()

Deprecated WebVR listing API — migrate immersive work to WebXR.

5
Core concepts
02

Status

Deprecated

+ Non-standard
🔌 03

Lists

available displays

Not only presenting
04

Prefer

navigator.xr

WebXR
🛡 05

Fallback

2D / frameworks

Always

❓ Frequently Asked Questions

It is a legacy WebVR method that returns a Promise resolving to an array of VRDisplay objects for VR headsets connected to the computer.
No. MDN marks it Deprecated and Non-standard. Prefer the WebXR Device API via navigator.xr, or a framework such as A-Frame, Three.js, or Babylon.js.
getVRDisplays() lists available VR displays (connected / known to the browser). activeVRDisplays lists only displays that are currently presenting (isPresenting === true).
The WebXR Device API. Start with navigator.xr, then isSessionSupported() and requestSession() for modes like immersive-vr.
Legacy WebVR APIs were typically restricted to secure contexts where they still existed. Feature-detect and assume HTTPS / localhost for any immersive work.
Usually the method is missing, or the Promise resolves to an empty array. That is expected without WebVR support and a headset.
Did you know?

WebVR and WebXR can sound similar, but they are different APIs. getVRDisplays() belongs to WebVR. New immersive VR work belongs on navigator.xr (WebXR) or a framework that wraps it.

Explore javaEnabled() Next

Learn the Baseline stub that always returns false.

javaEnabled() →

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