@vitraun/webar
v0.2.9
Published
Vitraun WebAR widget as Web Component
Readme
@vitraun/webar
Official Vitraun Virtual Try-On package for web storefronts.
Embeds try-on via the <vitraun-vto> Web Component (npm or CDN). The integrator does not hardcode the try-on URL — the widget calls embed-init, receives vtoUrl, and loads the session inside Shadow DOM.
Install
npm install @vitraun/webarPeer dependency for the React hook: react (≥18).
Quick start
import '@vitraun/webar'<vitraun-vto
merchant-id="vtrn-mch-key-00000000-0000-4000-8000-000000000001"
widget-id="vtrn-wdg-key-00000000-0000-4000-8000-000000000002"
lang="en-US"
auto-open
></vitraun-vto>Plain HTML via jsDelivr:
<script src="https://cdn.jsdelivr.net/npm/@vitraun/webar@<version>/dist/widget.min.js"></script>
<vitraun-vto
merchant-id="vtrn-mch-key-..."
widget-id="vtrn-wdg-key-..."
lang="en-US"
></vitraun-vto>
<script>
document.querySelector('vitraun-vto')?.open()
</script>Replace <version> with the published semver (for example 0.3.0).
Ecommerce modal (recommended for online stores)
When the channel is in Ecommerce mode (default), open() shows a built-in overlay modal with the try-on iframe. You do not need a hidden 1×1 container — mount <vitraun-vto> anywhere and call open() from your CTA.
<vitraun-vto
merchant-id="vtrn-mch-key-..."
widget-id="vtrn-wdg-key-..."
lang="en-US"
isolated-sku="8028997081552"
init-on-action-open="true"
></vitraun-vto>
<button type="button" id="btn-try-on">Try on</button>
<script>
document.getElementById('btn-try-on').addEventListener('click', () => {
document.querySelector('vitraun-vto')?.open()
})
</script>Customize the modal per breakpoint via HTML attributes (overrides channel settings from the panel):
| Attribute | Description |
|-----------|-------------|
| embed-modal-desktop-layout | centered or fullscreen (desktop) |
| embed-modal-desktop-max-width | Max panel width in px when centered |
| embed-modal-desktop-backdrop-color | Backdrop color (desktop) |
| embed-modal-mobile-backdrop-color | Backdrop color (mobile) |
Mobile always opens fullscreen, regardless of saved layout. The widget emits modalOpen and modalClose DOM events when the overlay toggles.
For retailer or QR code modes, open() / close() keep the previous inline display behavior.
How it works
- The host page loads
@vitraun/webar(orwidget.min.jsfrom CDN). - The user triggers try-on (
open(), orauto-openon connect). - The try-on runs in an internal iframe; events reach the host as
CustomEvents on<vitraun-vto>.
Shared embed-init logic lives in @vitraun/core.
Panel prerequisites
- Register merchant ID and widget ID in the Vitraun panel
- Configure allowed embed hosts on the channel (when origin enforcement is enabled)
- Serve the host page over HTTPS
Configuration
| Option | Required | Description |
|--------|----------|-------------|
| merchant-id | Yes | Public merchant key (vtrn-mch-key-…) |
| widget-id | Yes | Public widget key (vtrn-wdg-key-…) |
| lang | No | Locale (default en-US) |
| env | No | Environment segment (empty = production; e.g. staging) |
| isolated-sku | No | Single-product (PDP) mode |
| basket-opens-in | No | blank, self, or event |
| checkout-opens-in | No | blank, self, or event |
| auto-open | No | Calls open() when the element connects |
| init-on-action-open | No | When true, try-on (and camera) start only after open() |
| console | No | When true, shows an in-widget Events debug console |
Try-On app origin is baked into the published bundle. Override with data-base-url only for staging or self-hosted apps. Rebuild with VITRAUN_WIDGET_EMBEDDED_BASE_URL=<origin> when needed.
Staging
<vitraun-vto
env="staging"
merchant-id="vtrn-mch-key-..."
widget-id="vtrn-wdg-key-..."
lang="en-US"
></vitraun-vto>Events
| Event | Typical use |
|-------|-------------|
| addToCart | Add SKU to cart |
| removeFromCart | Remove line item |
| redirectToCart | Open checkout |
| analysisFinished | Camera / analysis ready |
| statusChange, vtoUsage | Diagnostics |
| modalOpen, modalClose | Ecommerce overlay opened/closed (ecommerce mode only) |
On init failure the widget logs console.error with prefix [vitraun-vto] and a shopper-safe message (not gated by debug). Listen to statusChange with detail.status === 'error' for custom UI; detail.message and optional detail.errorCode mirror the console output.
The lang attribute is sent as Accept-Language on the embed-init request so the admin API can return localized error messages (for example pt-BR).
import { subscribeVitraunVTOEvents } from '@vitraun/webar'
const dispose = subscribeVitraunVTOEvents(widgetElement, (entry) => {
console.log(entry.type, entry.detail)
})
dispose()Advanced usage
Programmatic control:
const widget = document.querySelector('vitraun-vto')
widget?.open()
widget?.close()React event log hook:
import { useVitraunVTOEventLogs } from '@vitraun/webar/react'
const { events, clearEvents } = useVitraunVTOEventLogs(containerRef.current)Embed-init is handled internally by the widget — no separate init call is required on web.
Troubleshooting init failures
| Symptom | What to check |
|---------|----------------|
| [vitraun-vto] message + 401 on embed-init | Valid, active merchant-id and widget-id in the panel |
| Connection / network error in console | admin-api reachable at api-port; local HTTPS and /etc/hosts for *.local.vitraun.com |
| Timeout after 20s | CORS: page origin in admin-api CORS_ORIGINS; embed-init URL in Network tab |
The browser Network panel may still show raw POST … 401 — use the [vitraun-vto] console.error line for the shopper-safe explanation.
Distribution
Load the widget from npm, jsDelivr, or your own CDN — not from the Try-On Next.js app origin.
jsDelivr (after npm publish):
https://cdn.jsdelivr.net/npm/@vitraun/webar@<version>/dist/widget.min.js
https://cdn.jsdelivr.net/npm/@vitraun/webar@<version>/dist/events.min.jsPackage exports
| Export | Description |
|--------|-------------|
| @vitraun/webar | Registers <vitraun-vto> + event helpers |
| @vitraun/webar/react | useVitraunVTOEventLogs |
| @vitraun/webar/widget.min.js | Script-tag IIFE bundle |
| @vitraun/webar/events | Event helpers only |
