JavaScript Navigator activeVRDisplays Property

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

What You’ll Learn

navigator.activeVRDisplays comes from the old WebVR API. It returns every VRDisplay that is currently presenting. Learn what it returned, why it is deprecated, how to feature-detect it safely, and what to use instead with WebXR.

01

Kind

Read-only property

02

Returns

VRDisplay[]

03

Status

Deprecated · Experimental

04

Context

Secure (HTTPS)

05

API family

Old WebVR

06

Modern path

navigator.xr

Introduction

The browser’s navigator object exposes information about the user agent and device capabilities. Years ago, WebVR added VR helpers on Navigator, including activeVRDisplays.

That property answered a simple question: which VR headsets are presenting right now? Only displays with VRDisplay.isPresenting === true appeared in the array.

⚠️
Deprecated & non-standard

MDN: do not use this in new code. WebVR was superseded by the WebXR Device API. Learn activeVRDisplays for legacy code and interviews, then migrate to navigator.xr.

This tutorial stays beginner-friendly: every example feature-detects first, so demos still make sense on laptops without a headset.

Understanding the activeVRDisplays Property

When supported, reading navigator.activeVRDisplays gives you an array of VRDisplay objects that are actively presenting immersive content.

  • It is read-only — you inspect, you do not assign.
  • An empty array means nothing is presenting (or you checked when VR was idle).
  • Missing property means the browser does not expose legacy WebVR here.
  • Requires a secure context (HTTPS / localhost) where it still exists.

📝 Syntax

General form of the property:

JavaScript
navigator.activeVRDisplays

Value

  • An array of VRDisplay objects currently presenting.
  • Often empty when no headset is in a presenting session.

Common patterns

JavaScript
// Always feature-detect first
if ("activeVRDisplays" in navigator) {
  const displays = navigator.activeVRDisplays;
  for (const display of displays) {
    console.log("Display " + display.displayId + " is active.");
  }
} else {
  console.log("WebVR activeVRDisplays is not available.");
}

// Prefer WebXR for new work
if (navigator.xr) {
  // Use navigator.xr.isSessionSupported / requestSession
}

⚡ Quick Reference

GoalCode
Read active displaysnavigator.activeVRDisplays
Feature detect"activeVRDisplays" in navigator
Count presentingnavigator.activeVRDisplays.length
Log each iddisplay.displayId
Secure context?window.isSecureContext
Modern VR/ARnavigator.xr (WebXR)

🔍 At a Glance

Four facts to remember about activeVRDisplays.

Type
VRDisplay[]

Presenting only

Status
deprecated

Legacy WebVR

HTTPS
required

Secure context

Replace with
navigator.xr

WebXR API

📋 WebVR activeVRDisplays vs WebXR

WebVR (activeVRDisplays)WebXR (navigator.xr)
StatusDeprecated / non-standardCurrent platform API
Entry pointnavigator.activeVRDisplaysnavigator.xr
What you getPresenting VRDisplay listXRSystem → sessions
Start experienceLegacy VRDisplay requestPresentrequestSession("immersive-vr")
New projectsAvoidPrefer (or use a framework)

Examples Gallery

Examples follow MDN Navigator.activeVRDisplays patterns, plus safe detection and WebXR guidance. Use View Output or Try It Yourself for each case.

📚 Getting Started

Detect support and list presenting displays when available.

Example 1 — Feature Detection

Check whether the property exists before reading it.

JavaScript
const supported = "activeVRDisplays" in navigator;
console.log(supported ? "activeVRDisplays available" : "activeVRDisplays missing");
// Typical modern desktop: activeVRDisplays missing
Try It Yourself

How It Works

Use in (or navigator.activeVRDisplays !== undefined) so missing support does not throw when you later read the property incorrectly in wrappers.

Example 2 — MDN-Style showActive()

Loop presenting displays and log each displayId.

JavaScript
function showActive() {
  if (!("activeVRDisplays" in navigator)) {
    console.log("WebVR activeVRDisplays not supported");
    return;
  }
  const displays = navigator.activeVRDisplays;
  if (!displays.length) {
    console.log("No presenting VR displays");
    return;
  }
  for (const display of displays) {
    console.log("Display " + display.displayId + " is active.");
  }
}

showActive();
Try It Yourself

How It Works

This mirrors MDN’s example, with guards so beginners see a clear message without a headset.

📈 Practical Patterns

Counts, secure contexts, and the WebXR replacement path.

Example 3 — Count Presenting Displays

Treat the array length as a simple “is anything presenting?” check.

JavaScript
function getActiveCount() {
  if (!("activeVRDisplays" in navigator)) return -1; // not supported
  return navigator.activeVRDisplays.length;
}

const n = getActiveCount();
if (n < 0) console.log("not supported");
else if (n === 0) console.log("supported, none presenting");
else console.log(n + " display(s) presenting");
Try It Yourself

How It Works

Separating “missing API” from “empty array” helps debug legacy polyfills and old browsers.

Example 4 — Secure Context Check

WebVR/WebXR features often require HTTPS.

JavaScript
const lines = [];
lines.push("isSecureContext: " + window.isSecureContext);
lines.push(
  "activeVRDisplays: " +
    ("activeVRDisplays" in navigator ? "present" : "absent")
);
console.log(lines.join("\n"));
Try It Yourself

How It Works

Even on HTTPS, modern browsers may omit the deprecated property. Secure context is necessary but not sufficient.

Example 5 — Prefer WebXR (navigator.xr)

For new code, detect WebXR instead of WebVR.

JavaScript
function describeVrApis() {
  if (navigator.xr) {
    return "Use WebXR via navigator.xr (recommended)";
  }
  if ("activeVRDisplays" in navigator) {
    return "Only legacy WebVR activeVRDisplays found";
  }
  return "No WebXR or WebVR entry points detected";
}

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

How It Works

MDN recommends frameworks (A-Frame, Three.js, Babylon.js) or WebXR polyfills while browser support continues to evolve.

🚀 Common Use Cases

  • Legacy WebVR apps — see which displays are already presenting.
  • Migration audits — find old activeVRDisplays usage to replace with WebXR.
  • Feature detection education — practice safe in checks on Navigator.
  • Not for new VR products — build on WebXR or a maintained 3D framework.
  • Interview / history — know WebVR existed and was replaced.

🧠 How activeVRDisplays Works

1

Browser exposes Navigator

Your page reads capabilities from navigator.

Navigator
2

Filter presenting displays

Only VRDisplay objects with isPresenting === true.

Filter
3

Return an array

Empty when idle; populated while presenting.

Array
4

Prefer WebXR today

New apps should use navigator.xr, not this property.

📝 Notes

  • Deprecated and non-standard — avoid in production.
  • Secure context required where the property still exists.
  • Superseded by the WebXR Device API (navigator.xr).
  • Empty array ≠ missing API — feature-detect separately.
  • Related learning: appCodeName, Window, EventTarget, JavaScript hub.

Limited / Legacy Browser Support

navigator.activeVRDisplays belongs to the deprecated WebVR API. Support was never universal and has been removed or omitted in many modern browsers. Prefer navigator.xr (WebXR) for new work.

Deprecated · Legacy WebVR

Navigator.activeVRDisplays

Do not rely on this property for new VR/AR products. Use it only to understand or migrate legacy code.

Legacy Not for new apps
Google Chrome Legacy WebVR removed / omitted in modern versions
Avoid
Mozilla Firefox WebVR path deprecated; prefer WebXR where available
Avoid
Apple Safari No practical WebVR activeVRDisplays path
Unavailable
Microsoft Edge Chromium Edge: treat as unavailable for new code
Avoid
Opera Follow Chromium WebVR/WebXR status
Avoid
Internet Explorer No WebVR activeVRDisplays support
Unavailable
activeVRDisplays Deprecated

Bottom line: Feature-detect if you must touch legacy WebVR. For new immersive experiences, use WebXR (navigator.xr) or a maintained framework.

Conclusion

navigator.activeVRDisplays once listed presenting WebVR displays. Today it is a deprecated legacy detail: feature-detect if you maintain old code, otherwise move to navigator.xr and modern WebXR patterns.

Continue with appCodeName, Window methods, or the JavaScript hub.

💡 Best Practices

✅ Do

  • Feature-detect before reading the property
  • Prefer navigator.xr for new VR/AR
  • Serve immersive demos over HTTPS
  • Plan migration off WebVR in legacy apps
  • Consider A-Frame / Three.js / Babylon.js

❌ Don’t

  • Build new products on activeVRDisplays
  • Assume every browser still exposes WebVR
  • Confuse “empty array” with “API missing”
  • Skip secure-context requirements
  • Treat non-standard APIs as future-proof

Key Takeaways

Knowledge Unlocked

Five things to remember about activeVRDisplays

Legacy WebVR list of presenting displays — prefer WebXR now.

5
Core concepts
🔁 02

Filter

isPresenting

Rule
⚠️ 03

Status

deprecated

Legacy
🔒 04

HTTPS

secure context

Security
🚀 05

Replace

navigator.xr

WebXR

❓ Frequently Asked Questions

It is a read-only Navigator property from the old WebVR API. It returns an array of VRDisplay objects that are currently presenting (VRDisplay.isPresenting is true).
No. MDN marks it deprecated and non-standard. Prefer the WebXR Device API via navigator.xr for new VR/AR work, or a framework like A-Frame, Three.js, or Babylon.js.
Either no VR display is presenting right now, or the property exists but nothing is in an immersive presenting state. On most modern browsers without WebVR, the property may be missing entirely.
Yes in supporting browsers: it is available only in secure contexts (HTTPS or localhost).
The WebXR Device API. Start with navigator.xr, then isSessionSupported() and requestSession() for immersive-vr or other modes.
No. It is read-only. You inspect presenting displays; you do not assign to the property.
Did you know?

WebVR and WebXR are different generations. Seeing activeVRDisplays in old samples is a clue you are looking at WebVR. New samples talk about XRSession and navigator.xr.requestSession() instead.

Learn appCodeName Next

Another Navigator property — always returns Mozilla.

appCodeName →

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