Immersive images, one element away.

xr-view is a custom HTML element for 360° and panoramic images. This guide covers installation, sizing, configuration, and runtime updates.

Quick start

Install the package, then import it once in your application.

npm install xr-view

Import from JavaScript

Importing the module registers <xr-view> with the browser's custom element registry.

import 'xr-view';

Add the element

Set src to the URL of an equirectangular image (a full photosphere).

<xr-view src="/images/photosphere.jpg"></xr-view>

Sizing

The component fills its available width and has a default height of 400px. Override its dimensions with ordinary CSS to fit your layout.

xr-view {
  width: 100%;
  height: min(70vh, 720px);
  border-radius: 16px;
}

Keep both dimensions greater than zero. xr-view observes its container and updates the camera whenever its rendered size changes.

Attributes

Configure the viewer directly in HTML. Attribute changes are reactive.

Attribute Type / default Description
src String / "" URL of the image to display.
type auto, 360, or pano / auto 360 renders a full equirectangular sphere. pano renders a curved partial-panorama surface for images that are not 2:1. auto measures the image and picks, treating anything within 5% of a 2:1 ratio as a photosphere. Pano and auto use render mode.
autopan Boolean / enabled Slowly rotates the view until the visitor interacts. Set the JavaScript property to false when you want a still initial view.
mode render or model render draws the image with Three.js on a WebGL canvas. model uses the platform <model> element for true 3D display within the page, on supported platforms (visionOS). Unsupported model mode falls back to render mode.

Mode example

<xr-view
  src="/images/panorama.jpg"
  type="pano"
  mode="render"
></xr-view>

Model mode

The <model> element displays real 3D content inline in the page, the way an image element displays a picture—the platform composites it rather than a canvas drawing it. On platforms that implement it, currently visionOS, model mode shows the image as genuine 3D geometry in the page instead of a rendered projection, and it is the default. xr-view generates the USDZ the element needs in the browser from the same src. Where the element is unavailable, the viewer uses render mode.

Update with JavaScript

Change the source without recreating the viewer, or turn automatic movement on and off at runtime.

const viewer = document.querySelector('xr-view');

viewer.src = '/images/second-photosphere.jpg';
viewer.autopan = false;

Load events

The viewer emits bubbling xr-view.load and xr-view.error custom events for the current non-empty source. Superseded and aborted requests do not emit either event.

viewer.addEventListener('xr-view.load', (event) => {
  console.log('Loaded', event.detail.src);
});

viewer.addEventListener('xr-view.error', (event) => {
  console.error('Could not load', event.detail.src, event.detail.error);
});

The class is also available as a named export when you need it directly.

import { XrView } from 'xr-view';

Built-in controls

  • Drag with a pointer or touch gesture to look around.
  • Use Fullview for an app-like viewport overlay.
  • Use Fullscreen for the browser's native fullscreen mode.
  • On supported devices, use WebXR to enter immersive VR.
  • Press Escape to leave Fullview or an active WebXR session.

A visitor's first pointer interaction stops auto-pan, keeping manual navigation under their control.

Iframe embed

Use the hosted embed page when adding the component directly is not practical. Encode the complete HTTPS image URL as the src query parameter.

<iframe
  src="https://xrview.dev/embed/?src=https%3A%2F%2Fsite.com%2F360img.jpg&type=360"
  width="600"
  height="400"
  title="360° image viewer"
  loading="lazy"
  allow="fullscreen; xr-spatial-tracking"
  allowfullscreen
></iframe>

The optional type parameter accepts auto, 360, or pano. Set autopan=false to disable initial movement.

Embedded images load directly in the visitor's browser. The image host must serve the file over HTTPS and allow cross-origin access with an Access-Control-Allow-Origin response header.

Image guidance

Standard browser-readable image URLs work for both supported projections.

360° photospheres

Use an equirectangular image with a 2:1 aspect ratio—for example, 4096×2048 or 8192×4096 pixels. Anything within 5% of 2:1 is treated as a full photosphere, so a slightly cropped export still wraps the whole sphere.

Panoramas

Wide shots that do not cover a full sphere display on a curved surface instead. Use an image that is wider than it is tall—a cylindrical stitch from a phone's panorama mode is a good fit. The wider the aspect ratio, the wider the arc the image wraps around the viewer, up to a half circle. The curved surface needs render mode, which auto selects for you.

Images fetched from another origin must allow cross-origin access. Compress large images carefully: dimensions preserve detail, while file size affects load time.

Browser support

The standard renderer requires custom elements, WebGL, and modern JavaScript module support. Fullscreen and WebXR controls appear or work only where the corresponding browser APIs are available.

If the image cannot be loaded, the viewer displays an error message. Test immersive features on the target device because WebXR support and permissions vary by browser and headset.

Report an issue →