WebXR
WebXR connects a web application with supported immersive presentation and spatial input. It supplies session, pose and timing mechanisms; the application still needs rendering, interaction design, asset management and an ordinary way to use essential content when XR is unavailable.
Begin by choosing the experience: inline presentation, immersive virtual reality or immersive augmented reality. Probe the relevant capability and request only the features needed for that experience. A capability result is an invitation to attempt entry, not proof that a session will start or remain usable.
TL;DR
- Keep capability detection, user-requested entry and active-session state separate.
- Choose reference spaces according to the interaction and supported features.
- Handle input-source changes and missing tracking without inventing poses.
- Treat AR hit testing as an optional capability with its own lifecycle.
- Validate real-device performance and retain accessible non-immersive content.
Quick Example
This complete async function checks an immersive-VR capability and returns a UI message. Call await xrAvailability() from the application’s capability-check flow in a supported secure context. It never requests an immersive session or accesses a camera/headset feed.
The local browser fixture returned ready: false and the proposed 2D fallback message. That is a tested unavailability path in this environment. It does not establish that a complete accessible 2D application exists, that entry permission works, or that reference spaces, controllers, hit testing and rendering operate on a real device.
Core Concepts
A session owns the experience
A supported mode and an active session are different states. Entry can fail, features can be unavailable, and a session can end. Keep the UI synchronized with actual state, preserve necessary application progress and release owned resources when the session ends. WebXR session model
Reference spaces define coordinates
Reference spaces relate tracked poses to a meaningful coordinate system. Viewer, local, floor-related and bounded spaces serve different interactions. Choose an available space deliberately; an estimated floor or a changing origin should not silently become an application guarantee about the room. Reference spaces
Rendering remains the application’s job
WebXR does not load models or render a scene for you. It supplies timing, views and spatial information that a renderer uses. Keep graphics integration and asset cost separate from session support. WebXR fundamentals
Design the entry and exit path first
Keep the ordinary page functional before XR entry. Explain what the immersive action offers, use a recognizable control and report failure without trapping the reader in a blank scene. Required information or a core transaction should not disappear merely because a device lacks a headset.
Treat the capability probe as a limited signal. Browser permissions and policy can affect its result, and a later entry attempt can still fail. Keep the rejection path ordinary and recoverable. Avoid repeatedly requesting entry after a person declines.
For a real session, distinguish application data from session-owned graphics and input objects. On exit, release the latter while preserving the former according to the product’s intended behavior. Test entering again so stale listeners, scene state and resources do not accumulate.
Connect spaces, input and hit tests carefully
Define the scene’s units and coordinate conventions. Use the session’s pose information for the correct frame and reference space. If a pose is unavailable, skip or adapt the dependent interaction rather than substituting a remembered pose and reporting it as current.
Reference-space resets and tracking loss need an explicit response. A placed object may require reorientation, a fresh placement step or a clear indication that tracking is uncertain. The right choice depends on the experience; it should not be hidden behind an apparently stable render.
Handle input sources as a changing collection. A controller, hand or transient screen input can have different capabilities. Base interaction on supported actions and observable input properties, then provide prompts that match the current source. Do not require one controller layout without a supported alternative if the intended audience uses others.
AR hit testing is an extension with its own requested feature and hit-test-source lifecycle. A result supplies spatial information for a chosen test, not a guarantee that an object is physically safe or semantically understood. Cancel owned hit-test subscriptions when no longer needed; the specification warns against relying on eventual garbage collection for cleanup. Hit-test module
None of these device paths was exercised by the availability fixture. Use an authorized target-device session to verify required spaces, actual input, feature denial, tracking loss and placement behavior before claiming support.
Set a frame budget and a fallback contract
Immersive rendering has a timing budget determined by the actual device/session path. Measure representative scenes rather than adopting an invented universal frame-rate guarantee. Include CPU work, graphics work, asset loading and other application activity in the investigation.
Keep expensive preparation outside the critical frame callback where practical. Bound allocations and avoid unnecessary per-frame DOM work. Compare representative object counts, textures, effects and interactions on the supported devices; a simple empty scene cannot establish a complex scene’s performance.
Define acceptable degradation before overload. A simpler scene or reduced optional effects can preserve an interaction, but verify the actual outcome rather than claiming a generic quality switch solves every performance problem. Maintain clear exit and ordinary-page controls.
Specify what the 2D fallback allows: viewing the same essential information, performing a core action, reading a description or using another accessible interaction. The fixture only returns a message; the product must implement and test the promised experience.
Keep spatial and input data collection proportionate to the feature. Treat permissions and device signals as boundaries to handle, not obstacles to bypass. Reconsider an XR-only requirement when the product cannot offer a usable alternative or maintain target-device testing over supported browser changes.
Best Practices
Validate every state transition
Test unsupported, probing, entry requested, active, interrupted and ended states. Keep UI messages tied to observed state.
Scope device claims
Record the actual browser, device, mode and granted features. Do not turn a desktop capability check into a headset compatibility statement.
Make fallback useful
Provide an accessible path to essential content and actions. Test that path with the same care as immersive entry.
Common Mistakes
Bad: Treating a true capability probe as an active session.
Correct: Request entry through the intended user interaction and handle success, denial and later termination.
Bad: Assuming every reference space describes a measured physical room.
Correct: Use the selected space’s documented semantics and handle estimated origins, resets and missing poses.
Bad: Claiming AR hit-test support from a VR probe.
Correct: Request and test the intended AR mode, feature and device path separately.
FAQ
Is WebXR a scene renderer?
No. It provides session, spatial and timing interfaces. Rendering and asset management belong to the application or its chosen graphics library.
Does this example start VR?
No. It returns a capability-based message. The observed local result was the fallback branch, without an immersive session.
Should the fallback be a disabled button?
A disabled control can explain availability, but essential content and actions need a useful ordinary path. Define and test what that path actually provides.
Related Topics
- Frontend Development — Design application state and accessible fallback behavior.
- WebCodecs — Keep low-level browser support claims configuration-specific.
- Lit — Represent capability and session states through explicit components.