AtlasAR Cloud

Docs

Viewer SDK: 3D and AR on any website

The same viewer as the AtlasAR WordPress plugin, for Shopify, custom shops, React or plain HTML. Add one script and one tag; your visitors turn the product in 3D and place it in their room with AR.

Quick start

  1. Make a model with AtlasAR Cloud (the WordPress plugin, the dashboard's Create 3D page or POST /v1/models/upload) and copy its id, for example mdl_4f8Q….
  2. Add the script once per page and a tag where the viewer should be:
HTML
<script src="https://cloud.wpaugmentedreality.com/sdk/v1/atlasar.js" defer></script>

<atlasar-viewer model="mdl_4f8Q…"></atlasar-viewer>

That is all: no API key in the page (the model's files are public), no framework. The viewer loads when it scrolls into view, so pages stay fast. Try it on the example page (add ?model=mdl_… to its address).

Your own files

Not using AtlasAR Cloud hosting? Point the viewer at your own files. Add a USDZ for iPhone AR; without one, iPhones show the 3D view only.

HTML
<atlasar-viewer src="/models/chair.glb" ios-src="/models/chair.usdz"
    poster="/models/chair.webp" alt="Oak dining chair"></atlasar-viewer>

Files on another domain must allow cross-origin loading (Access-Control-Allow-Origin). AtlasAR Cloud's files already do.

Show a "View in 3D" button that opens the viewer in a popup, with full screen and close buttons. Nothing loads until the click.

HTML
<atlasar-viewer model="mdl_4f8Q…" display="popup" button-label="View in 3D"></atlasar-viewer>

Prefer the viewer on the page, but only after a click? Use load="interaction": the poster shows with a "View in 3D" button.

AR on phones

  • Android opens Scene Viewer, iPhone and iPad Quick Look (needs a USDZ), and browsers with WebXR use it in the page. Choose with ar-modes="webxr scene-viewer quick-look".
  • Floor items stand on the floor; set ar-placement="wall" for art, mirrors and tiles. AtlasAR Cloud models are already at their real size.
  • On a computer, a View on your phone button shows a QR code of the page, so the visitor can continue on a phone. Turn it off with qr="false".
  • Your own AR button: ar-button="custom" ar-button-text="See it in your room" ar-button-background="#0f766e".

Browsers without 3D

Some browsers cannot draw 3D (no WebGL: old phones, locked-down computers, some privacy settings). The viewer never shows an empty box there:

  • It shows the poster, or 360° images the visitor turns by dragging or with the arrow keys: turntable="front.jpg right.jpg back.jpg left.jpg".
  • On a phone it still offers View in your room, which opens the phone's own AR app with a plain link.
  • Anything you put inside the tag (for example an <img>) is shown when JavaScript is off, and hidden otherwise.

To see it, add renderer="fallback".

Virtual try-on

Glasses and hats can be tried on with the front camera. Add tryon="glasses" or tryon="hat": a Try it on button appears on the viewer. The try-on code and the face tracker load only when the visitor clicks it.

HTML
<atlasar-viewer model="mdl_4f8Q…" tryon="glasses" tryon-label="Try them on"></atlasar-viewer>
  • Privacy: the visitor first sees what happens and chooses Allow camera access. The video stays in the browser: nothing is recorded, uploaded or sent to us. Change the text with tryon-consent.
  • Photos: the shutter button saves a picture on the visitor's device (no upload). Free photos carry a small "Powered by AtlasAR"; turn photos off with tryon-snapshot="false".
  • No camera? The consent screen offers Try it on a sample face: the same try-on on a built-in portrait, so visitors without a camera (and you, while fitting a model) can see the result. Use your own picture with tryon-sample="/img/face.jpg", or hide the button with tryon-sample="false".
  • Needs: an https page and a browser with WebGL; a camera for the live try-on. Use a model whose front faces the camera, at its real size.
  • Premium (atlasar-pro.js): the product turns with the head in 3D, the back of a hat hides behind the head, photos are twice as sharp and have no badge.

Fitting a model (Premium)

Most models fit by themselves. If one sits too high or too small, open the try-on with tryon-calibrate on a page only you visit: sliders appear in the try-on window. When it fits, press Copy settings and put the result in tryon-calibration:

HTML
<atlasar-viewer model="mdl_4f8Q…" tryon="hat"
    tryon-calibration='{"offsetY":12,"scale":1.08}'></atlasar-viewer>

Events: atlasar:tryon-open, atlasar:tryon-ready, atlasar:tryon-sample (the sample face was chosen), atlasar:tryon-snapshot and atlasar:tryon-close.

Settings saved with a model

Instead of writing options in every page, save them with the model once. Every site that shows <atlasar-viewer model="mdl_…"> picks them up within a minute, with no code change. Options written in the page still win.

  • Dashboard: Viewer SDK → Settings saved with a model: choose the model, change the title, background, AR placement, try-on, and the Premium dimensions, hotspots, variants and try-on fitting.
  • API: PUT /v1/models/:id/viewer with the site's key and the same option names. Unknown or invalid values are refused, so a typo never reaches your shop.
cURL
curl -X PUT "https://cloud.wpaugmentedreality.com/v1/models/mdl_4f8Q…/viewer" \
  -H "Authorization: Bearer ar_live_…" -H "Content-Type: application/json" \
  -d '{"viewer":{"title":"Oak chair","autoRotate":true,"dimensions":{"show":true,"unit":"cm"}}}'

Premium settings can be saved on any plan; they show while the site is Premium, so nothing is lost if a site moves between plans.

Analytics

The viewer counts how shoppers use each 3D view: seen, turned or zoomed, popup opened, AR started, try-on opened, sample face used, try-on photo taken (and, with Premium modules, hotspot clicks, other models viewed and variant changes). Only totals leave the page, in small batches: no cookies, no visitor id, no page address or device data. Bots are not counted.

  • AtlasAR Cloud models (model="mdl_…") count by themselves. See the totals in the dashboard under Analytics, or with GET /v1/stats.
  • Your own files: send the counts to your own address with analytics and analytics-id (the WordPress plugin does this and keeps them on the shop's site).
  • Turn it off for a viewer with analytics="none".
HTML
<!-- Counts to your own endpoint (it receives { v: 1, counts: { "42": { "view": 1, "ar": 1 } } } as text/plain) -->
<atlasar-viewer src="/models/chair.glb" analytics="/api/3d-stats" analytics-id="42"></atlasar-viewer>

Add your own events from code: AtlasAR.analytics.count('my-event', 'my_key') counts every atlasar:my-event, and AtlasAR.analytics.track(viewer, 'my_key') counts once.

Tools: optimise, convert and flat products

AtlasAR.tools works on models in the browser, for your own admin screens. Nothing is uploaded: everything happens on the visitor's device. The code (about 900 KB) loads on the first call, never with the page.

JavaScript
// Make a GLB lighter, at a real height of 32 cm (levels: maximum, high, balanced, low, minimum)
const { blob, stats, budget } = await AtlasAR.tools.optimise(file, { heightCm: 32, level: 'balanced' });
// stats: { triangles, glb_mb, texture_px, level, … }   budget: 'pass' | 'warn' | 'fail'

// OBJ or FBX to GLB (textures inside the file are kept)
const glb = await AtlasAR.tools.convert(fbxFile);

// A flat product from one photo, at its real size, with the iPhone file
const { glb: art, usdz } = await AtlasAR.tools.flat(photo, { kind: 'canvas', widthCm: 60, heightCm: 40 });

AtlasAR.tools.levels;        // the level table (same as AtlasAR Cloud's)
AtlasAR.tools.defaultLevel;  // 'high'
LevelTrianglesLargest textureImage quality
maximum150,0004096 px95
high default50,0002048 px85
balanced30,0001024 px80
low15,0001024 px70
minimum8,000512 px60

Flat kinds: canvas, poster, framed, rug, tile. For big files, or to optimise from a server, use AtlasAR Cloud's API: it uses the same levels.

All options

Write them as attributes (auto-rotate) or pass them from JavaScript in camelCase (autoRotate). A wrong value falls back to the default, so a typo never breaks the page.

AttributeDefaultWhat it does
model—An AtlasAR Cloud model id (mdl_…). Sets the files, name and size.
src / ios-src—Your own GLB, and a USDZ for iPhone AR.
poster, alt—, "3D model"Image shown while loading; text for screen readers.
displayinlineinline or popup (a button that opens it).
button-label, title"View in 3D", the model nameThe popup's button and heading.
loadvisiblevisible (when scrolled near), interaction (after a click) or immediate.
width, height, align, margin, padding100%, 400px, left, 0, 2px 0Size and position of the viewer.
backgroundtransparentBackground colour behind the model.
camera-orbit45deg 55deg 4mThe starting angle and distance.
auto-rotate, camera-controls, disable-zoom, disable-tapoff, on, off, offTurning and zooming.
interaction-prompt, interaction-prompt-thresholdauto, 2000The "drag me" hint and how long to wait (ms) before it shows.
environment-image, skybox-imageneutral, —Lighting, and an optional background panorama.
tone-mapping, exposure, shadow-intensityneutral, 1, 1Colour and light.
ar, ar-modeson, webxr scene-viewer quick-lookAR, and which AR apps to use.
ar-placement, ar-scale, xr-environmentfloor, auto, onFloor or wall; allow resizing in AR; lighting from the room.
ar-button, ar-button-text, ar-button-background, ar-button-colordefault, "View in AR", #3a3a3a, #ffffffThe AR button: default, custom (yours) or none.
qr, qr-url, qr-brandon, this page, "AtlasAR"The QR code on computers.
renderer, turntableauto, —Force the fallback; 360° images for it.
css—Your CSS for this viewer only.
tryon, tryon-labeloff, "Try it on"glasses or hat: the camera try-on and its button.
tryon-consent, tryon-snapshot(our text), onThe camera consent text; the photo button.
tryon-calibration, tryon-calibrate—, offPremium: fitting values; the fitting sliders.
tryon-sampleonThe "Try it on a sample face" button: false hides it; a picture URL uses your own face.
analytics, analytics-id— (AtlasAR Cloud models: on)Where the counts go and what they count for; none turns counting off. See Analytics.

JavaScript API

JavaScript
const viewer = AtlasAR.mount('#product-3d', {
  model: 'mdl_4f8Q…',
  display: 'popup',
  autoRotate: true,
});

viewer.update({ background: '#f5f5f4' }); // change options
viewer.open();                            // popup: open from your own button
viewer.destroy();                         // remove it

AtlasAR.capabilities();  // what this browser can do (webgl, quickLook, mobile…)
AtlasAR.tryon.open({ src: 'glasses.glb', tryon: 'glasses' }); // the try-on from your own button
AtlasAR.VERSION;

The tag works with any framework (React, Vue, Svelte): it is a standard custom element. Set options with attributes, or with the options property for objects.

Events

Events bubble, so you can listen on the tag or on document.

  • atlasar:ready: the viewer is shown. event.detail.renderer is model-viewer or fallback.
  • atlasar:load: the model has loaded. atlasar:error: it could not (event.detail.reason).
  • atlasar:ar-status: AR started, stopped or failed. atlasar:open / atlasar:close: the popup.
  • atlasar:tryon-open, atlasar:tryon-ready, atlasar:tryon-sample, atlasar:tryon-snapshot, atlasar:tryon-close: the try-on.
  • Premium: atlasar:hotspot, atlasar:item-change, atlasar:variant-change.
JavaScript
document.addEventListener('atlasar:ar-status', (e) => {
  if (e.detail.status === 'session-started') console.log('AR opened on', e.target);
});

Styling and translation

Change colours with CSS variables on the tag or any parent: --atlasar-accent, --atlasar-button-bg, --atlasar-button-fg, --atlasar-radius and --atlasar-font. Every text can be translated from JavaScript:

JavaScript
AtlasAR.mount('#product-3d', {
  model: 'mdl_4f8Q…',
  strings: { viewIn3d: 'In 3D ansehen', close: 'Schließen', qrButton: 'Auf dem Handy ansehen' },
});

Content-Security-Policy

The SDK uses no inline scripts or styles. If your site sends a Content-Security-Policy, allow the AtlasAR Cloud host and these:

Content-Security-Policy
script-src  'self' https://cloud.wpaugmentedreality.com 'wasm-unsafe-eval';
style-src   'self' 'sha256-yhlpZVZMy2vXExwTGihUWVSrOxyhMuvj+Ygg7pyBWek=';
img-src     'self' data: blob: https://cloud.wpaugmentedreality.com;
connect-src 'self' blob: data: https://cloud.wpaugmentedreality.com;
worker-src  'self' blob:;

The try-on starts its face tracker from a blob: address (browsers only start workers from the page's own site), so keep worker-src blob:. If you send a Permissions-Policy header, allow camera=(self) on pages with try-on.

The style hash is model-viewer's own stylesheet; 'wasm-unsafe-eval' lets the decoders that make models small run.

npm and self-hosting

The SDK is plain JavaScript (ES modules), with no framework. For bundlers, the package exports the module build; its 3D engine files load from AtlasAR Cloud unless you host them yourself:

JavaScript
import AtlasAR from '@atlasar/viewer';

// Only if you copy the SDK's files (atlasar.js, vendor/) to your own server:
AtlasAR.configure({ assetsBase: '/static/atlasar/', apiBase: 'https://cloud.wpaugmentedreality.com/' });

The npm package is coming soon; until then, use the script tag.

Free and Premium

Everything above is free: the viewer, AR, the popup, the QR code, the fallback and the try-on with a small badge on photos. The Premium additions below come in a second script, atlasar-pro.js, loaded after the first. On WordPress, the AtlasAR Pro plugin has them.

For AtlasAR Cloud models the site's plan decides: on a Free site, a model's saved Premium settings stay hidden and the Premium try-on stays off, even with atlasar-pro.js on the page. A site with an AtlasAR Pro licence is Premium.

HTML
<script src="https://cloud.wpaugmentedreality.com/sdk/v1/atlasar.js" defer></script>
<script src="https://cloud.wpaugmentedreality.com/sdk/v1/atlasar-pro.js" defer></script>

Hotspots (Premium)

Labels pinned to points on the model, for example the material of a seat. Positions and normals are in metres in the model's own space, the same values the AtlasAR plugin's hotspot editor saves. Labels are shown as text.

HTML
<atlasar-viewer model="mdl_4f8Q…"
    hotspots='[{"position":"0 0.45 0.2","normal":"0 1 0","label":"Solid oak seat"}]'></atlasar-viewer>

A click fires atlasar:hotspot with the hotspot's index and label.

Dimensions (Premium)

Width, height and depth drawn around the model with dashed lines, hidden while AR is open. With "mode":"auto" they are measured from the model (AtlasAR Cloud models are at their real size); with "manual" your values are shown as you wrote them.

HTML
<atlasar-viewer model="mdl_4f8Q…" dimensions='{"show":true,"unit":"cm"}'></atlasar-viewer>

<!-- manual: -->
dimensions='{"show":true,"unit":"inch","mode":"manual","width":{"value":24},"height":{"value":36},"length":{"value":20}}'

Units: mm, cm, m, inch, ft. Change the line colour with --atlasar-dim-color.

Several models with thumbnails (Premium)

One viewer, several models (a set, a bundle, colours as separate files). Thumbnails under the model switch between them; keyboard users move between them with the arrow keys.

JavaScript
AtlasAR.mount('#product-3d', {
  items: [
    { src: '/models/sofa.glb', iosSrc: '/models/sofa.usdz', thumbnail: '/img/sofa.webp', alt: 'Sofa' },
    { src: '/models/chair.glb', thumbnail: '/img/chair.webp', alt: 'Armchair' },
  ],
});
// element.showItem(1) switches from code; atlasar:item-change tells you which one is shown.

Colour and material variants (Premium)

Show the option the shopper picks in your own product form. Map your option names to the model's built-in material variants (KHR_materials_variants), or to a separate model file per option. Names match without regard to case.

JavaScript
const viewer = AtlasAR.mount('#product-3d', {
  model: 'mdl_4f8Q…',
  variants: {
    mapping: { Red: 'red_leather', Black: 'black_leather' }, // built-in material variants
    models:  { Walnut: '/models/chair-walnut.glb' },          // a separate file
  },
  variant: 'Red', // shown first
});

document.querySelector('#colour').addEventListener('change', (e) => {
  if (!viewer.setVariant(e.target.value)) console.warn('No 3D variant for', e.target.value);
});

setVariant() returns false for an option it does not know, and the model stays as it is. A model's own variant names work without a mapping; element.variants() lists them. atlasar:variant-change fires after each change.