# How to build virtual tours in Bubble

- Tool: Bubble
- Difficulty: Beginner
- Time required: 20-25 min
- Compatibility: All Bubble plans
- Last updated: March 2026

## TL;DR

Creating virtual tours in Bubble involves embedding 360-degree panoramic viewers like Pannellum or Matterport into your app and linking multiple panoramas with interactive hotspots. This tutorial covers embedding a 360-degree viewer via HTML elements, connecting panoramas with navigation hotspots, building a tour management system for multiple properties or locations, and providing a smooth user experience across devices.

## Overview: Creating Virtual Tours in Bubble

This tutorial shows you how to build a virtual tour feature in your Bubble app using 360-degree panoramic images. You will learn to embed viewers like Pannellum (free, open-source) or Matterport (paid), create hotspot navigation between scenes, and build a management interface for tour creators.

## Before you start

- A Bubble app on any plan
- 360-degree panoramic images (captured with a 360 camera or stitched from photos)
- Images hosted on a public URL (Bubble file storage, AWS S3, or similar)
- Basic familiarity with HTML elements in Bubble

## Step-by-step guide

### 1. Set up the Tour database structure

In the Data tab, create these Data Types: (1) Tour — fields: title (text), description (text), creator (User), thumbnail (image), is_published (yes/no). (2) Scene — fields: tour (Tour), title (text), image_url (text — URL to the 360 panoramic image), order_index (number), pitch (number — default viewing angle vertical), yaw (number — default viewing angle horizontal). (3) Hotspot — fields: scene (Scene), target_scene (Scene), label (text), pitch (number — vertical position), yaw (number — horizontal position). These three types let you define tours with multiple linked scenes.

**Expected result:** Your database supports tours with multiple scenes connected by positioned hotspots.

### 2. Embed the Pannellum 360-degree viewer

Pannellum is a free, open-source panorama viewer. On your tour viewing page, add an HTML element sized to fill the content area (e.g., 100% width, 500px height). In the HTML content, add the Pannellum CSS and JS from their CDN, a div container for the viewer, and a JavaScript initialization script that loads the panoramic image URL from your Scene data. Use dynamic data to insert the current Scene's image_url into the JavaScript. The viewer provides mouse drag to look around, scroll to zoom, and fullscreen toggle automatically.

```
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/pannellum/build/pannellum.css"/>
<script src="https://cdn.jsdelivr.net/npm/pannellum/build/pannellum.js"></script>
<div id="panorama" style="width:100%;height:500px;"></div>
<script>
pannellum.viewer('panorama', {
  type: 'equirectangular',
  panorama: 'DYNAMIC_IMAGE_URL_HERE',
  autoLoad: true,
  defaultPitch: 0,
  defaultYaw: 0,
  compass: true,
  hotSpots: []
});
</script>
```

**Expected result:** A 360-degree panoramic viewer loads in your Bubble page, allowing users to look around by dragging.

### 3. Add interactive hotspots for scene navigation

Hotspots are clickable points within the panorama that navigate to another scene. In the Pannellum configuration, add hotspots to the hotSpots array. Each hotspot needs a pitch (vertical angle), yaw (horizontal angle), type ('scene'), text (label), and a click handler. Since Bubble HTML elements cannot directly call Bubble workflows, use a workaround: when a hotspot is clicked, update a hidden Input element's value on the page with the target scene's ID. Then use a 'Do when condition is true' event that watches for changes to that input and navigates to the target scene by updating the page data or custom state.

> Pro tip: To find the pitch and yaw coordinates for hotspot placement, use Pannellum's built-in debug mode which displays coordinates as you mouse over the panorama.

**Expected result:** Clicking a hotspot in the panorama navigates the user to the next scene in the tour.

### 4. Build the tour creation and management interface

Create an admin page for tour creators. Add a form to create new Tours with title, description, and thumbnail upload. Below, show a Repeating Group of Scenes belonging to the current Tour, sorted by order_index. Each Scene cell has an edit button to update the image URL, title, and viewing angles. Add an 'Add Scene' button that creates a new Scene linked to the Tour. For hotspot management, display each Scene with its hotspots listed, and provide a form to add new Hotspots with target scene selection (dropdown of other Scenes in the Tour) and pitch/yaw coordinates.

**Expected result:** Tour creators can add scenes, upload panoramic images, configure viewing angles, and place hotspots linking scenes together.

### 5. Create the public tour browsing page

Build a tour catalog page with a Repeating Group of published Tours (is_published = yes). Display each Tour's thumbnail, title, description, and a Start Tour button. The Start Tour button navigates to the tour viewer page, passing the Tour as page data. On the viewer page, load the first Scene (sorted by order_index, first item) and display it in the Pannellum viewer. Add Previous and Next buttons to cycle through scenes sequentially, and a scene list sidebar showing all scenes in the tour with the current one highlighted.

**Expected result:** Users can browse published tours and navigate through scenes using both hotspots and sequential navigation controls.

## Complete code example

File: `Workflow summary`

```text
VIRTUAL TOUR ARCHITECTURE
==========================

DATA TYPES:
  Tour:
    - title: text
    - description: text
    - creator: User
    - thumbnail: image
    - is_published: yes/no

  Scene:
    - tour: Tour
    - title: text
    - image_url: text (URL to 360 panoramic image)
    - order_index: number
    - pitch: number (default vertical angle)
    - yaw: number (default horizontal angle)

  Hotspot:
    - scene: Scene (source scene)
    - target_scene: Scene (destination scene)
    - label: text
    - pitch: number (vertical position in panorama)
    - yaw: number (horizontal position in panorama)

PAGE STRUCTURE:
  tour-catalog:
    - Repeating Group of published Tours
    - Start Tour button → navigate to viewer

  tour-viewer (page type: Tour):
    - Custom state: current_scene (Scene)
    - HTML element: Pannellum viewer
    - Scene list sidebar
    - Previous/Next navigation
    - Hotspot click → update current_scene

  tour-admin:
    - Tour creation form
    - Scene management (add, edit, reorder)
    - Hotspot placement (target scene, coordinates)

PANNELLUM INTEGRATION:
  Load via CDN (CSS + JS)
  Initialize with:
    - type: 'equirectangular'
    - panorama: Scene's image_url (dynamic)
    - autoLoad: true
    - hotSpots: array from Hotspot records
  Navigation: hotspot click → update custom state
    → re-initialize viewer with new scene
```

## Common mistakes

- **Using very large panoramic image files without compression** — 360-degree images can be 10-50MB each — loading uncompressed images makes the viewer extremely slow, especially on mobile devices Fix: Compress panoramic images to under 5MB and use JPEG format at 80% quality. Consider multiple resolution tiers for mobile vs desktop.
- **Hardcoding hotspot coordinates instead of storing them in the database** — Hardcoded coordinates in the HTML element cannot be updated dynamically and require editing HTML for every change Fix: Store hotspot coordinates in the Hotspot Data Type and build the hotSpots array dynamically from database records
- **Not providing alternative navigation beyond hotspots** — Users may not find all hotspots, especially on mobile where the viewing area is smaller, leaving them stuck in one scene Fix: Add a scene list sidebar and Previous/Next buttons as alternative navigation alongside in-panorama hotspots

## Best practices

- Compress panoramic images to under 5MB for fast loading on mobile devices
- Use Pannellum's autoLoad: true to start loading the panorama immediately
- Provide multiple navigation methods — hotspots, scene list, and sequential buttons
- Store all tour configuration in the database for easy editing without code changes
- Add a loading indicator while the panoramic image downloads
- Test on mobile devices since touch-based panning behaves differently from mouse drag
- Use Pannellum's compass feature to help users orient themselves within the panorama

## Frequently asked questions

### What tools can I use to capture 360-degree images?

Use a 360 camera like Ricoh Theta or Insta360 for automatic capture. For budget options, use a smartphone with Google Street View app which stitches multiple photos into a panorama. For professional quality, use a DSLR on a panoramic tripod head with stitching software.

### Is Pannellum free to use commercially?

Yes. Pannellum is released under the MIT license, which allows free commercial use without restrictions.

### Can I use Matterport instead of Pannellum?

Yes. Matterport provides an embed code for their tours. Paste the Matterport iframe into a Bubble HTML element. Matterport handles hosting, viewer, and navigation automatically but requires a paid subscription for multiple tours.

### How do I determine hotspot coordinates?

Enable Pannellum's debug mode by adding hotSpotDebug: true to the viewer configuration. When enabled, clicking anywhere on the panorama logs the pitch and yaw coordinates to the browser console. Use those coordinates when creating Hotspot records.

### Can RapidDev help build a virtual tour platform in Bubble?

Yes. RapidDev can build a complete virtual tour platform with panorama embedding, hotspot management, tour creation tools, and a public-facing catalog — ideal for real estate, hospitality, or tourism businesses.

### Do virtual tours work on mobile devices?

Yes. Pannellum supports touch-based panning and pinch-to-zoom on mobile browsers. However, performance depends on image size — keep panoramic images compressed for smooth mobile experience.

---

Source: https://www.rapidevelopers.com/bubble-tutorial/create-virtual-tours-in-bubble
© RapidDev — https://www.rapidevelopers.com/bubble-tutorial/create-virtual-tours-in-bubble
