# `ActivateAROptions.overlayRoot`

> Contract 2.0.0 · package sha256 `a857eca95b35921109faf997094bb4192f12527d9d0fcd4be7e97f06425bad6e` · generated from `configurator-runtime.d.ts` by `services/onsite-scripter/scripts/build-contract-docs.mjs`; edit the source, not this file.

Property of [`ActivateAROptions`](ActivateAROptions.md) · labs, `@experimental` · since 2.0.0

```ts
overlayRoot?: HTMLElement;
```

Your own UI over the camera in Holostep's in-page AR (a swatch strip, a part toggle, add to
cart): an element you created before the call. On both in-page routes (the camera route on
iOS, WebXR on Android) it is shown over the camera for the session, filling the screen, and
put back where it was at the end. Holostep's own screens (the camera picture, Close, Place
again, the shutter, the hint line) are its first child, a layer under your content, and for
the session the runtime sets two CSS custom properties on it, removed at the end:
`--holo-ar-inset-top` and `--holo-ar-inset-bottom`, the height those screens take at the top
and the bottom, the safe area included (about 60 px + the top safe area and 76 px + the
bottom one on the camera route; 56 px and 72 px on WebXR). Keep your controls inside
`padding: var(--holo-ar-inset-top) 0 var(--holo-ar-inset-bottom)` and give them
`pointer-events: auto`. The element is shown however the page styled it; show and hide its
content on 'xr:start' and 'xr:end'. On the camera route a write it makes reaches the placed
product once it lands (5.11). Quick Look and Scene Viewer can't show page UI: there it is
unused. Check [`supports('activateAR.overlayRoot')`](Session.supports.md) first; where it answers false the option
is ignored.

**Default:** undefined (Holostep's screens alone, in a layer over the whole page, removed when AR closes)

## Example

Imports: values (`has`, `validate`, the `Holo*Error` classes, the pure helpers) from `@holostep-configurators/runtime-client`, types from `@holostep-configurators/runtime-client/contract`, `/math` and `/testing` names from those entries; `boot` from the runtime module the root's `loadRuntimeAtFloor` resolves to. A type your page defines is your app's: declare it there, never import it from the package.

Compiled under the contract's strict settings (`examples/declaration/16-ActivateAROptions.overlayRoot.ts`):

```ts
import type { Session } from '@holostep-configurators/runtime-client/contract';
declare const session: Session;
declare const signal: AbortSignal;
const bar = document.createElement('div');
bar.style.padding = 'var(--holo-ar-inset-top) 0 var(--holo-ar-inset-bottom)';
bar.style.pointerEvents = 'none';
const swatches = bar.appendChild(document.createElement('div'));
swatches.style.cssText = 'position: absolute; bottom: var(--holo-ar-inset-bottom); left: 0; right: 0';
swatches.style.pointerEvents = 'auto';
swatches.hidden = true;
document.body.append(bar);
session.on('xr:start', () => (swatches.hidden = false), { signal });
session.on('xr:end', () => (swatches.hidden = true), { signal });
// In the AR button's click handler (the shopper's gesture):
await session.activateAR(session.supports('activateAR.overlayRoot') ? { overlayRoot: bar } : {});
```

## Generic-API test (spec 3.1)

| Rule | Result |
| --- | --- |
| 1. Neutral name | pass: `overlayRoot` names no product |
| 2. A precedent | pass: [model-viewer canActivateAR and activateAR()](https://modelviewer.dev/docs/index.html#entrydocs-augmentedreality-methods-activateAR) (row `G66`); [XRSession.end()](https://developer.mozilla.org/en-US/docs/Web/API/XRSession/end) (row `G66`); [Navigator.share() (resolves when the share UI closes)](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/share) (row `G66`) |
| 3. Two apps, or labs | labs (`@experimental` at a stable path, reached through `has()` or `supports()`): it graduates when a second app uses it; apps today: configurator-template, tryon-template |
| 4. The cheaper fix first | decided per need in Appendix B: rows `G66` at tier labs (a member only where no rule, data, asset or app code serves the need) |
