Full experience: Vue + Three.js + Monolook
Step-by-step guide for creating a complete AR experience, based on the Springs of Love (Brussels) project.
Stack
| Package | Usage |
|---|---|
| Vue 3 | UI framework (Composition API) |
| Vue Router | Navigation between screens |
| Pinia | Global state |
| Three.js | WebGL 3D engine |
| Anime.js | UI animations |
| Vue3-Lottie | Lottie animations (loading, onboarding) |
| Bowser | Platform detection |
| Vite | Build tool |
Scaffolding
bash
npm create vite@latest my-experience -- --template vue
cd my-experience
npm install
npm install vue-router@4 pinia three animejs vue3-lottie bowserProject structure
src/
├── App.vue
├── main.js
├── router/
│ └── index.js
├── stores/
│ └── experience.js
├── views/
│ ├── StartView.vue # Start screen
│ └── ExperienceView.vue # AR view
├── components/
│ ├── ThreeScene.vue # 3D scene
│ ├── Header.vue
│ ├── Sidebar.vue
│ └── HotspotCard.vue
├── composables/
│ └── useMonolook.js # SDK logic
└── assets/
├── models/ # GLB, GLTF
├── textures/
└── audio/Experience flow
[StartView] → click → [ExperienceView]
↓
[Detect platform]
↙ ↘
[WebXR] [AppClip]
(Android/Quest) (iOS)
↘ ↙
[ThreeScene]
↓
[3D content + UI]Vite configuration
javascript
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
server: {
https: true // WebXR requires HTTPS
},
build: {
target: 'esnext'
}
})HTTPS required
WebXR requires HTTPS. Always configure server.https: true in development.
Entry point
javascript
// main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import router from './router'
import App from './App.vue'
createApp(App)
.use(createPinia())
.use(router)
.mount('#app')Routing system
javascript
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import StartView from '../views/StartView.vue'
import ExperienceView from '../views/ExperienceView.vue'
export default createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: StartView },
{ path: '/experience', component: ExperienceView }
]
})Platform detection
javascript
import Bowser from 'bowser'
const browser = Bowser.getParser(navigator.userAgent)
const os = browser.getOSName()
const isIOS = os === 'iOS'
const isAndroid = os === 'Android'
const isDesktop = !isIOS && !isAndroidNext step
This guide covers the base structure. For more detail on each component:
- Image Tracking with Three.js — Image tracking
- SLAM Web — Surface tracking
- iOS AppClip — Native bridge
- Deploy — Build and hosting