Skip to content

In-room AR and try-on: what your page needs ​

Holostep can place a configured product in the shopper's room from the page itself, without leaving for a separate AR app. This page lists what your page, your embed and your headers need so that it works. Most pages need nothing for in-room AR. Try-on and photo capture need a one-time header change and, for try-on, a button.

In-room AR (placing a product in the room) ​

No tenant code is needed for calls without a GLB file. The activateAR() call you already make keeps its signature and its meaning. When your account is enabled for in-page AR, that call opens the in-page presenter on phones that support it and falls back to the native presenter (Scene Viewer or Quick Look) everywhere else, exactly as today.

What your page needs:

  1. Permissions. In-room AR uses only the xr-spatial-tracking feature. Its default allowlist is self, so a page served from your own origin needs no Permissions-Policy change. A camera=() header does not block in-room AR. If your page embeds the viewer in an iframe and its Permissions-Policy names xr-spatial-tracking or fullscreen, include the configurator origin in those allowlists (see the try-on section for the form), or the shopper gets the native presenter.

  2. Iframes. When the viewer runs inside an iframe, the iframe element must allow the feature and fullscreen:

    html
    <iframe src="https://your-configurator.example" allow="xr-spatial-tracking; fullscreen"></iframe>

    Without fullscreen, the browser refuses the AR session inside the iframe and the shopper gets the native presenter instead. If you plan to enable try-on or capture later, add camera to the list now: allow="xr-spatial-tracking; camera; fullscreen".

  3. Keep the ?holoXr query parameter. When a shopper comes back from AR on another device or from the hosted page, the return URL carries ?holoXr=<code>. Holostep reads it on load, restores the configuration and emits the xr:cta event. A router or redirect that strips unknown query parameters breaks that return.

Good to know (no action) ​

  • Objects you detach and re-add. Some pages remove a backdrop or helper objects before calling activateAR() and add them back when the call resolves. Keep doing that if you want to; it needs no change. While an AR session holds the scene, objects added back are queued or hidden until the session ends, so they never appear in the shopper's room.
  • Fullscreen. Entering AR ends your page's own fullscreen, and it is not restored. If your page runs the viewer fullscreen, listen for the xr:session-end event and ask for fullscreen again from the shopper's next tap; browsers require a tap for that.
  • Anti-aliasing. A viewer configured with antialias: false renders without anti-aliasing in AR too.
  • Auto-launch pages. A page that calls activateAR() on load, without a tap, always gets the native presenter. The in-page presenter needs the tap that the browser requires for an AR session.
  • Calls that pass a GLB file. activateAR({ glbUrl }) keeps the native presenter with that file, as today. To get the in-page presenter, call activateAR() without glbUrl when session.info().ar.presenter reads holostep-webxr.

Try-on and photo capture ​

Try-on (a product on the shopper's face or feet) and photo capture use the camera from the page. Before Holostep enables either for your account, your page needs:

  1. The camera feature, in two places:

    • The configurator app's own response. Holostep changes camera=() to camera=(self) in the app's headers when your account enables try-on or capture. Nothing for you to do.
    • Your page, if it embeds the configurator in an iframe. The iframe needs camera in its allow list. If your page also sends its own Permissions-Policy, every feature it names must include the configurator's origin, and likewise for xr-spatial-tracking and fullscreen if your header names them. camera=(self) on your page blocks the iframe even with allow="camera": the browser applies the parent's allowlist before it reads the iframe's allow. A page that sends no Permissions-Policy needs only the iframe allow list.
    http
    Permissions-Policy: camera=(self "https://your-configurator.example"), microphone=(), geolocation=()
    html
    <iframe
      src="https://your-configurator.example"
      allow="xr-spatial-tracking; camera; fullscreen"
    ></iframe>
  2. Content Security Policy. Try-on and capture run a worker from a blob: URL and load WebAssembly. If your page sends a CSP, it must allow worker-src blob: and 'wasm-unsafe-eval' in script-src. When either is missing, the shopper is routed to the hosted page and the integrator gets a console error. In-room AR needs neither.

  3. A Try-on button that calls tryOn() where you want try-on offered. The in-room AR button is not reused for it.

Holostep checks the camera header only for accounts that have try-on or capture enabled. Pages that offer in-room AR alone keep camera=() and pass.

Checklist ​

FeatureHeaderIframe allowCSPCode
In-room ARnone (an embedding page that sends the header lists the configurator origin)xr-spatial-tracking; fullscreennonenone
Try-on, captureconfigurator app: camera=(self) (Holostep); embedding page with a header: camera=(self "<configurator origin>")xr-spatial-tracking; camera; fullscreenworker-src blob:, 'wasm-unsafe-eval'a Try-on button