For developers

Embed interactive 3D & AR in your own website

One iframe — no plugins, no 3D engine to build. Your customers rotate the model, switch finishes, and view it at real-world scale in their space with AR, right inside your product pages. Navigation and buttons stay on your side; the viewer just responds.

Try it live

The buttons below live outside the frame and drive it via postMessage — exactly how you'd wire them to your own UI. On a phone, tap View in AR inside the viewer.

Variants — loading…
Background
Vignette
Display

Everything inside the bordered frame is the Placewize embed (a single <iframe>). The variant buttons, background swatches, and QR around it live on your page.

Your embed code

This is the exact embed for what's shown above — it updates live as you change the controls. The project and org slugs are shown as placeholders; swap in your own from your project's share link.

<iframe
  src="https://www.placewize.com/embed/viewer/YOUR-PROJECT-SLUG?org=YOUR-ORG-SLUG&vignette=1&bg=dcd7cd&fullscreen=1"
  allow="xr-spatial-tracking; camera; accelerometer; gyroscope; fullscreen"
  style="width:100%; height:600px; border:0"
></iframe>

1. Drop in the embed

Paste this where you want the viewer. Replace the project and org slugs with your own (find them in your Placewize project's share link). The allow attributes enable AR and fullscreen.

<iframe
  src="https://www.placewize.com/embed/viewer/YOUR-PROJECT-SLUG?org=YOUR-ORG-SLUG&fullscreen=1"
  allow="xr-spatial-tracking; camera; accelerometer; gyroscope; fullscreen"
  style="width:100%; height:600px; border:0"
></iframe>

2. URL options

orgrequiredYour organisation slug.
variant=<id>optionalStart on a specific variant (otherwise the default is shown).
bg=<hex>optionalSolid background colour, e.g. bg=0d1117 (the # is optional).
fullscreen=1optionalShow a fullscreen toggle button in the viewer.
transparent=1optionalTransparent canvas — the 3D floats over your own page background (overrides bg).
bare=1optionalJust the 3D window: hides every control (layer switcher, AR button, fullscreen). Drive it entirely from your page via postMessage.
ar=1optionalKeep the built-in "View in AR" button visible in bare mode (still shows on AR phones only). Pair with bare=1 for a clean viewer that still has native AR.

3. Control it from your page

The viewer talks to your page over postMessage. Listen for the variant list, then drive it from your own buttons:

// The embed announces itself when it loads, with the list of variants.
window.addEventListener('message', (event) => {
  const data = event.data
  if (data?.type === 'ready') {
    // data.variants → [{ id, name, variantType, isDefault }]
    buildYourButtons(data.variants)
  }
  if (data?.type === 'variantChanged') {
    // fired after a switch completes — data.variantId
  }
})
const frame = document.querySelector('iframe').contentWindow

// Switch the model shown inside the viewer:
frame.postMessage({ type: 'setVariant', variantId: 'the-variant-id' }, '*')

// Change the background colour:
frame.postMessage({ type: 'setBackground', color: '#0d1117' }, '*')

// Launch AR from your own button (handy with bare=1, where the built-in AR button is hidden).
// The viewer tells you when AR is available so you can show/hide your button:
frame.postMessage({ type: 'launchAR' }, '*')

4. Fullscreen on iPhone

Desktop and Android use native fullscreen automatically. iPhone Safari can't fullscreen an element, so the viewer asks your page to resize the iframe instead — handle these two messages (this sandbox already does, which is why the fullscreen button works here on iPhone):

// iPhone Safari can't fullscreen an element, so the viewer asks your page to resize
// the iframe. Handle these two messages to support fullscreen on iOS (and post a
// confirmation back so the viewer's icon stays in sync):
window.addEventListener('message', (event) => {
  const frame = document.querySelector('iframe')
  if (event.data?.type === 'requestFullscreen') {
    frame.classList.add('pw-fullscreen')
    event.source.postMessage({ type: 'fullscreenChanged', isFullscreen: true }, '*')
  }
  if (event.data?.type === 'exitFullscreen') {
    frame.classList.remove('pw-fullscreen')
    event.source.postMessage({ type: 'fullscreenChanged', isFullscreen: false }, '*')
  }
})
.pw-fullscreen { position: fixed; inset: 0; width: 100vw; height: 100vh; z-index: 9999; }

5. Show a QR on desktop

Desktop visitors can't use AR — so show them a QR to continue on their phone, where AR works (that's the panel next to the viewer above, visible only on desktop). Point the image at our QR endpoint; no need to generate images yourself:

<!-- Scan-to-mobile QR, shown on desktop only (touch devices already have AR).
     Point the image at our QR endpoint — no need to generate the image yourself. -->
<div class="pw-qr">
  <img
    src="https://www.placewize.com/api/qr?data=https%3A%2F%2Fyoursite.com%2Fyour-product-page&size=320"
    alt="Scan to view in AR on your phone" width="160" height="160" />
  <p>Scan with your phone's camera to view in AR</p>
</div>
.pw-qr { display: none; text-align: center; }
@media (hover: hover) and (pointer: fine) { .pw-qr { display: block; } }

Endpoint: https://www.placewize.com/api/qr?data=<url-encoded target>&size=256 → returns an SVG. Point data at the page that contains your embed.

Augmented reality

A View in AR button appears automatically on AR-capable phones — iPhone (Quick Look) and Android (Scene Viewer). Nothing to configure beyond keeping the allow attributes on your iframe. On desktop it's hidden. Keeping bare=1 but still want the native AR button? Add ar=1. Prefer your own button instead? Leave ar off and launch AR yourself via postMessage (below).

6. Just the 3D window (transparent & fully controlled)

Want the model to sit right inside your own design — no controls, no background, your own AR button? Combine transparent=1 (the 3D floats over your page, no background) and bare=1 (hides every built-in control). The viewer becomes a headless 3D window you drive entirely over postMessage. If you also add ar=1 the native View-in-AR button stays visible (phones only); otherwise it's hidden and you launch AR yourself:

// With ?bare=1 the built-in AR button is hidden — trigger AR from your own control instead.
// The viewer posts { type: 'arAvailability', available } on load and whenever the device/variant
// changes, so you know whether to show your button (AR only works on phones):
window.addEventListener('message', (event) => {
  if (event.data?.type === 'arAvailability') {
    myArButton.style.display = event.data.available ? 'block' : 'none'
  }
})

// then, on click:
myArButton.onclick = () =>
  document.querySelector('iframe').contentWindow.postMessage({ type: 'launchAR' }, '*')

For a transparent embed, don't set allowtransparency/background on the iframe — just give the iframe's container the background you want the 3D to sit on.

Need a hand integrating? Email hello@placewize.com.