Skip to content
PD

Emaze Tours — Interactive Virtual Tour Builder

A Canva/Emaze-style web app where anyone builds an interactive 3D virtual tour in a drag-and-drop editor, then publishes it to a shareable link or embeds it via iframe.

Problem

Building an interactive virtual tour or 3D presentation normally means design skills or an expensive SaaS — there was no simple in-house tool for non-designers to create and publish one.

Result

A web editor that renders a 3D room and lets users drop image, video, text and HTML layers onto it with familiar move/resize/rotate controls, save to Supabase, and publish each tour at its own URL or embed it anywhere via iframe.

Tech Stack

Next.js 16 (App Router)React 19TypeScript (strict)Three.js + React Three Fiber + DreiReact MoveableZustandTailwind CSS v4 + shadcn/uiSupabase (Postgres + Storage)ZodDocker + Nginx

Overview

Emaze Tours is a virtual-tour builder in the spirit of Canva and Emaze: a web app where a user assembles an interactive 3D room in a visual editor, drops objects onto it — images, YouTube videos, text, even sandboxed HTML — arranges them with familiar move/resize/rotate handles, and then publishes the result to a shareable /tour/{slug} URL or embeds it anywhere via iframe. It’s built on Next.js 16 with a React Three Fiber 3D backdrop and a Moveable + Zustand 2D editing layer on top, with Supabase for persistence and file storage.

Problem

Interactive “virtual tour” and 3D-presentation experiences look impressive but are painful to make. The options are learning design software, wrestling with heavyweight 3D tooling, or renting an expensive SaaS like the original Emaze — none of which suits a non-designer who just needs to lay out a room, drop in a few images and captions, and share a link. The goal was an in-house builder that keeps the immersive 3D look but makes authoring feel as simple as arranging shapes on a slide.

Solution

The core idea is deceptively simple: render the room in 3D, but edit in 2D. The room is a real React Three Fiber scene, which gives the depth and lighting that make a tour feel immersive; the objects placed inside it are flat 2D layers with plain x, y, width, height, rotation transforms, manipulated through React Moveable — the same drag-resize-rotate interaction people already know from Canva. That decision removes the hardest part of 3D authoring (true spatial manipulation) while keeping the payoff. A user creates a tour, adds typed objects, arranges them, and hits publish; the tour is saved to Supabase and served at its own URL or inside an iframe, with a responsive viewer that scales the scene for desktop, tablet and mobile.

Features

  • Visual editor — build a tour on a 3D room backdrop using familiar move / resize / rotate / delete controls
  • Typed objects — image upload (PNG/JPG/WebP), YouTube video, styled text (font, size, colour, alignment) and sandboxed HTML embeds
  • Publish & embed — every tour gets a /tour/{slug} link and an iframe embed
  • Responsive viewer — the scene scales cleanly across desktop, tablet and mobile
  • Supabase backend — Postgres for projects and objects, Storage for uploaded images
  • Strict, layered codebase — TypeScript with no any, Zod-validated, split into types/validation → repositories → services → actions → UI

Architecture

The app is an Emaze-style “3D presentation, 2D editing” system. The room renders as a React Three Fiber scene while every object is a 2D layer with flat transforms, so editing never requires reasoning about 3D space. State lives in a Zustand store; React Moveable provides the transform handles. On the backend, Supabase holds the schema (projects, objects) and a public storage bucket for images, and the codebase enforces a clean dependency direction — types & Zod validation → repositories → services → server actions → UI — so business rules never leak into components. It ships as a standalone Docker build behind Nginx. As an MVP, auth is intentionally deferred (permissive RLS with an owner_id reserved in the schema), so the security model is ready to tighten the moment Supabase Auth is switched on.

Results

  • A working MVP of an Emaze-style tour builder: create → edit → publish, end to end
  • Immersive 3D room feel with an editing experience as simple as a slide canvas
  • Tours publishable by link and embeddable via iframe, with a responsive viewer
  • Supabase-backed persistence and image storage, deployable as a Docker container behind Nginx
  • A strict, layered TypeScript codebase that’s clean to extend past the MVP

What Was Learned

The unlock was refusing to make 3D editing actually 3D. Rendering the room with React Three Fiber buys the immersive look, but keeping objects as 2D layers with flat transforms means the editor can reuse the well-understood Canva-style interaction model — and users never hit the wall that real 3D manipulation puts in front of non-designers. The second thing that paid off was strict layering from day one: pushing all rules through validation → repositories → services → actions kept even an MVP honest, so the codebase reads like a product, not a prototype, and the path from “auth-off MVP” to a locked-down multi-user app is a configuration change rather than a rewrite.

Services used in this project

Related case studies

Need a similar system?

Tell me about your challenge — I will propose an architecture and the shortest path to a working product.