Documentation

Displaying your virtual tours

Every VR Šetnja tour is a live web page you can share with a link or drop into any website with a single line of HTML. This guide covers both — plus URL options, deep links, social previews and a small API for controlling the tour from your own page.

Your tours live at vr.version2.hr. Examples below use the public demo tour — swap demo for your own tour’s slug.

A real embed, running right here — the exact snippet from Quick start produces this. Drag to look around; click a door to walk through.

Basics

Two ways to show a tour

There are two URLs for every tour, and you pick based on where it’s going.

Share a link

/t/your-slug

The full tour page — branding, a room menu, share and fullscreen buttons. Send it in a message, put it in an email, or link it from a button. This is also the page that generates rich previews on WhatsApp, Facebook and Slack.

Embed on a site

/embed/your-slug

A bare viewer built to live inside an <iframe> on your own website. No page chrome around it — just the tour, so it drops cleanly into a listing, a hotel page or a portfolio.

Both open the exact same tour. Use the /t/ link for sharing, and /embed/ for putting the tour inside another page.

Embed

Quick start — paste one iframe

Copy this into your page’s HTML where you want the tour to appear. It works on any website that lets you add HTML — no scripts, no libraries, no account.

HTML
<iframe
  src="https://vr.version2.hr/embed/demo?ui=minimal"
  width="100%"
  height="600"
  loading="lazy"
  allowfullscreen
  allow="gyroscope; accelerometer; fullscreen"
  style="border:0;border-radius:12px;"
  title="VR Šetnja: Demo"
></iframe>
Fixed 600px height. Replace demo with your slug, and adjust height to taste (e.g. 450, 750).

The allow attribute is important: it’s what keeps the move-your-phone-to-look-around (gyroscope) and fullscreen buttons working inside the frame. loading="lazy" means the tour only loads when the visitor scrolls near it, so it never slows down the rest of your page.

Embed

Responsive — fills its column

If your layout has a flexible width (most modern sites), use the responsive wrapper. The tour keeps a fixed aspect ratio and scales to whatever width it’s given — perfect on both desktop and mobile.

HTML
<div style="position:relative;width:100%;aspect-ratio:16/9;">
  <iframe
    src="https://vr.version2.hr/embed/demo"
    loading="lazy"
    allowfullscreen
    allow="gyroscope; accelerometer; fullscreen"
    style="position:absolute;inset:0;width:100%;height:100%;border:0;border-radius:12px;"
    title="VR Šetnja: Demo"
  ></iframe>
</div>
Swap aspect-ratio:16/9 for 4/3 or 1/1 if you want a taller or square frame.

Embed

Customise the embed (URL options)

Add options to the embed URL with ?name=value, joined by &. Anything invalid is rejected rather than silently ignored, so a typo is easy to spot.

These change what the visitor sees

OptionValuesDefaultEffect
uidefault · minimal · nonedefaultHow much control chrome shows. default = title + room menu + buttons. minimal = title + buttons, no room menu. none = just the panorama.
scenea scene identry roomOpen the tour in a specific room instead of the main one (see below).
branding1 · 010 hides the tour’s own title and logo pill (the panorama’s colours still apply).

Accepted but not active yet

These are part of the URL contract so your links keep working as features land — today they have no visible effect.

OptionValuesDefaultEffect
themeauto · light · darkautoReserved. The viewer is always a dark canvas for now.
autorotate0 · 10Reserved. Gentle idle drift is planned; no motion today.
tokena token idReserved for origin-restricted embeds once token management ships.

Example — minimal chrome, starting in a chosen room:

URL
https://vr.version2.hr/embed/demo?ui=minimal&scene=SCENE_ID

Deep links

Start in a specific room

By default a tour opens on its main room. To open it somewhere specific, add ?scene=SCENE_ID. This works on both the share link and the embed:

URL
https://vr.version2.hr/t/demo?scene=SCENE_ID
https://vr.version2.hr/embed/demo?scene=SCENE_ID
You don’t need to memorise scene ids — the Share panel builds these links for you.

You get the exact URL (and matching QR code) from the tour’s Share & embed panel, where a drop-down lets you pick the starting room.

Recipes

Platform recipes

The embed is a standard iframe, so it works anywhere that accepts HTML. A few specifics:

WordPress
Add a Custom HTML block (block editor) and paste the snippet. In the classic editor, switch to the Text tab first. Note: some locked-down hosts strip iframes from the visual editor — the Custom HTML block avoids that.
Wix, Squarespace, Webflow
Use the Embed / HTML element (Wix “Embed HTML”, Squarespace “Code” block, Webflow “Embed”) and paste the responsive snippet. Give the element room to grow.
Plain HTML site
Paste either snippet directly into your markup. Nothing else needed.
React / Next.js
It’s just an iframe — remember JSX casing (allowFullScreen, a numeric height, and a style object).
JSX
export function TourEmbed() {
  return (
    <iframe
      src="https://vr.version2.hr/embed/demo?ui=minimal"
      width="100%"
      height={600}
      loading="lazy"
      allowFullScreen
      allow="gyroscope; accelerometer; fullscreen"
      style={{ border: 0, borderRadius: 12 }}
      title="VR Šetnja: Demo"
    />
  );
}
Real-estate portals & marketplaces
Many portals don’t allow custom iframes in a listing. When that’s the case, paste the /t/ share link into the listing’s virtual-tour / video field, or print the QR code on the exposé.

Sharing

Link previews when sharing

Paste a /t/your-slug link into WhatsApp, Messenger, Slack, LinkedIn or iMessage and it unfurls into a rich card — the tour title, a one-line description and a preview image of the entry room. That image is generated automatically for every tour, so there’s nothing to set up.

Always share the /t/ link, not the /embed/ one, for previews and in search results. The embed URL is deliberately kept out of Google and generates no card — it’s a transport for iframes, not a destination.

Advanced · developers

Control the tour from your page

The embedded viewer talks to the page hosting it using the browser’s postMessage. You can react to what the visitor does, and drive the tour from your own buttons. Entirely optional — the iframe works fine without any of this.

Listen to the tour

The viewer sends these events. Always check event.origin first.

JavaScript
window.addEventListener("message", (event) => {
  // Only trust messages coming from the tour's origin.
  if (event.origin !== "https://vr.version2.hr") return;
  const msg = event.data;
  if (!msg || typeof msg.type !== "string") return;

  switch (msg.type) {
    case "vrsetnja:ready":
      // { tour: { id, slug, sceneCount }, currentScene: { id, title } }
      console.log("Tour ready —", msg.tour.sceneCount, "scenes");
      break;
    case "vrsetnja:scene-changed":
      console.log("Now viewing:", msg.to.title);
      break;
    case "vrsetnja:hotspot-clicked":
      console.log("Hotspot clicked:", msg.kind, msg.hotspotId);
      break;
    case "vrsetnja:fullscreen":
      console.log("Fullscreen:", msg.fullscreen);
      break;
  }
});
  • vrsetnja:readyFires once when the first room is fully shown.
  • vrsetnja:scene-changedThe visitor moved to another room.
  • vrsetnja:hotspot-clickedA hotspot (door or info point) was activated.
  • vrsetnja:fullscreenFullscreen was entered or exited.

Send a command

Move the tour to a room from your own UI (a floor-plan, a menu, a “next room” button):

JavaScript
const frame = document.querySelector("iframe");

// Jump the embedded tour to a specific room. The sceneId is the 26-char
// id from the tour's Share panel (start-scene picker).
frame.contentWindow.postMessage(
  { type: "vrsetnja:goto-scene", sceneId: "SCENE_ID" },
  "https://vr.version2.hr",
);
vrsetnja:goto-scene is live today. Two more commands — vrsetnja:set-yaw (point the camera) and vrsetnja:request-snapshot — are part of the contract but accepted-and-ignored for now; they’ll activate in a later release without breaking your code.

Details

Good to know

  • Private tours can’t be embedded

    A tour set to privatereturns “not found” on the embed and share URLs. Use public or unlisted for anything you want to show. (Unlisted stays out of search but anyone with the link can view it.)

  • Mobile & the gyroscope

    On phones, visitors can pan by dragging, pinch to zoom, or tilt the device to look around. The tilt control needs the allow="gyroscope; accelerometer" attribute — it’s already in every snippet here.

  • Fullscreen

    Keep allowfullscreen on the iframe so the fullscreen button works. It’s in the generated snippets.

  • Performance

    Panoramas are large images, so the snippets use loading="lazy" — the tour loads only as the visitor reaches it. You can embed several tours on one page without a load penalty up front.

  • No badges in embeds

    The scene counter and the “by Version2” mark that appear on the full /t/ page are intentionally off inside embeds — the tour sits cleanly in your design.

  • Not showing up?

    The tour needs to be public or unlisted, and your page must be served over https. If your site builder blanks the frame, it’s probably stripping raw HTML — paste the snippet into its dedicated HTML / embed block instead of the rich-text editor.

In the app

Where to get your code

You don’t have to write any of this by hand. Open a tour in the dashboard and use its Share & embed panel:

  • Copy the public link, or open it in a new tab.
  • Pick a starting room, chrome density, and fixed or responsive layout.
  • Copy the ready-made iframe snippet.
  • Download a QR code (PNG) for flyers, window stickers and listing sheets.

Machine-readable

For AI assistants & LLMs

If you’re an AI assistant helping someone embed a VR Šetnja tour, here is the complete, verified contract. Prefer these facts over guessing.

Share URL: https://vr.version2.hr/t/{slug}

Embed URL: https://vr.version2.hr/embed/{slug} (put inside an <iframe>)

Required iframe attrs: allow="gyroscope; accelerometer; fullscreen", allowfullscreen, loading="lazy"

Query options (both URLs where noted):

• ui = default | minimal | none — embed only, default "default"

• scene = <26-char scene id> — /t and /embed; start room

• branding = 1 | 0 — embed only; 0 hides tour title+logo

• theme, autorotate, token — reserved, no effect yet

Embeddability: public + unlisted tours only; private returns 404. CSP frame-ancestors is open (embed anywhere).

postMessage out (from viewer, origin https://vr.version2.hr): vrsetnja:ready, vrsetnja:scene-changed, vrsetnja:hotspot-clicked, vrsetnja:fullscreen

postMessage in (to iframe.contentWindow, targetOrigin https://vr.version2.hr): vrsetnja:goto-scene {sceneId} [active]; vrsetnja:set-yaw, vrsetnja:request-snapshot [reserved/no-op]

Do NOT: reference a "sdk.js" or JS widget — none is published; use the raw iframe + postMessage above.

Recommended default embed: responsive wrapper, ?ui=minimal, replace demo with the real slug, keep the allow attribute intact.