Create an immersive shopping experience using Custom Widgets for 360-degree product views, 3D model rendering, and AR product placement. Use the panorama_viewer package for swipeable 360-degree image sequences, model_viewer for interactive .glb 3D models with rotate and zoom, and AR Quick Look or SceneViewer for placing products in the user's real space. Treat 360-degree and 3D as progressive enhancements over standard product images so products without immersive assets still display normally.
Building Immersive Product Visualization for E-Commerce in FlutterFlow
Online shoppers cannot touch or examine products physically. This tutorial bridges that gap with three levels of immersive product viewing: 360-degree image sequences for spin-around views, interactive 3D model rendering for detailed inspection, and AR placement to see how products look in the user's real space. All three are implemented as progressive enhancements on standard product pages.
Prerequisites
- A FlutterFlow project with an existing product catalog or e-commerce setup
- Products with 360-degree image sequences (12-36 images) or .glb 3D model files
- Familiarity with FlutterFlow Custom Widgets (Dart code)
- For AR features: physical iOS or Android device (not simulator)
Step-by-step guide
Extend the product data model with immersive asset fields
Extend the product data model with immersive asset fields
Add these fields to your products collection: imageUrls (String Array, standard product photos), has360 (Boolean), images360Urls (String Array, 12-36 images taken from different angles), has3dModel (Boolean), model3dUrl (String, URL to .glb or .gltf file), hasAr (Boolean), arModelUrl (String, URL to .usdz for iOS or .glb for Android). These boolean flags enable progressive enhancement: the product page checks each flag and shows the corresponding viewer only when assets exist. Products without immersive assets display the standard photo carousel.
Expected result: Products have optional fields for 360-degree image sequences, 3D models, and AR models with boolean flags indicating availability.
Build the 360-degree product viewer as a Custom Widget
Build the 360-degree product viewer as a Custom Widget
Create a Custom Widget named Product360Viewer. It receives a list of image URLs (the 360-degree sequence). Display the first image and track horizontal swipe gestures with a GestureDetector. As the user swipes left or right, advance or reverse through the image sequence to create a spinning effect. Preload all images on widget initialization for smooth transitions. Add a small instruction label: 'Swipe to rotate'. Show a loading indicator while images preload. Wrap the viewer in a Container with the same aspect ratio as your product images.
1// Custom Widget: Product360Viewer2import 'package:flutter/material.dart';3import 'package:cached_network_image/cached_network_image.dart';45class Product360Viewer extends StatefulWidget {6 final List<String> imageUrls;7 final double width;8 final double height;9 const Product360Viewer({10 super.key,11 required this.imageUrls,12 required this.width,13 required this.height,14 });1516 @override17 State<Product360Viewer> createState() => _Product360ViewerState();18}1920class _Product360ViewerState extends State<Product360Viewer> {21 int _currentIndex = 0;22 double _dragAccumulator = 0;2324 @override25 Widget build(BuildContext context) {26 return SizedBox(27 width: widget.width,28 height: widget.height,29 child: GestureDetector(30 onHorizontalDragUpdate: (details) {31 _dragAccumulator += details.delta.dx;32 final sensitivity = widget.width /33 widget.imageUrls.length;34 if (_dragAccumulator.abs() > sensitivity) {35 setState(() {36 if (_dragAccumulator > 0) {37 _currentIndex = (_currentIndex - 1)38 % widget.imageUrls.length;39 } else {40 _currentIndex = (_currentIndex + 1)41 % widget.imageUrls.length;42 }43 if (_currentIndex < 0) {44 _currentIndex += widget.imageUrls.length;45 }46 _dragAccumulator = 0;47 });48 }49 },50 child: Stack(51 alignment: Alignment.bottomCenter,52 children: [53 CachedNetworkImage(54 imageUrl:55 widget.imageUrls[_currentIndex],56 fit: BoxFit.contain,57 width: widget.width,58 height: widget.height,59 ),60 Container(61 padding: const EdgeInsets.all(8),62 color: Colors.black26,63 child: const Text(64 'Swipe to rotate',65 style: TextStyle(66 color: Colors.white,67 fontSize: 12),68 ),69 ),70 ],71 ),72 ),73 );74 }75}Expected result: Users swipe horizontally on the product image to spin it around 360 degrees through a sequence of pre-captured images.
Add the 3D model viewer with rotate and zoom controls
Add the 3D model viewer with rotate and zoom controls
Create a Custom Widget named Product3DViewer that uses the model_viewer_plus package to render .glb or .gltf 3D model files. Pass the model3dUrl as a parameter. The ModelViewer widget provides built-in touch controls: one-finger drag to rotate, pinch to zoom, two-finger drag to pan. Enable auto-rotate as default so the model spins slowly when not being touched. Set a neutral background color matching your product page theme. Add camera-controls, auto-rotate, and ar attributes to the ModelViewer widget. This gives users detailed inspection capability beyond what photos provide.
1// Custom Widget: Product3DViewer2import 'package:flutter/material.dart';3import 'package:model_viewer_plus/model_viewer_plus.dart';45class Product3DViewer extends StatelessWidget {6 final String modelUrl;7 final double width;8 final double height;9 const Product3DViewer({10 super.key,11 required this.modelUrl,12 required this.width,13 required this.height,14 });1516 @override17 Widget build(BuildContext context) {18 return SizedBox(19 width: width,20 height: height,21 child: ModelViewer(22 src: modelUrl,23 alt: 'A 3D model of the product',24 autoRotate: true,25 cameraControls: true,26 backgroundColor:27 const Color.fromARGB(255, 245, 245, 245),28 ),29 );30 }31}Expected result: Products with 3D models render an interactive viewer where users rotate, zoom, and inspect the model from any angle.
Implement AR product placement for real-world preview
Implement AR product placement for real-world preview
Add a 'View in AR' button on the product page, visible only when hasAr is true. On iOS, use the ar attribute on the ModelViewer widget which launches AR Quick Look with the .usdz model file. On Android, launch Scene Viewer via a URL intent: intent://arvr.google.com/scene-viewer/1.0?file={glbUrl}#Intent. Detect the platform using Theme.of(context).platform and use the appropriate approach. The user points their camera at a flat surface, and the product appears at real-world scale. They can walk around it and see how it fits in their space.
Expected result: Users tap View in AR and see the product placed on a real surface through their camera, at true-to-life scale.
Assemble the product page with progressive enhancement
Assemble the product page with progressive enhancement
On the ProductDetailPage, build the image section with conditional logic. Start with a PageView carousel of standard imageUrls as the default. Below the carousel, add a Row of toggle buttons: Photos (always visible), 360 View (visible only when has360 is true), 3D Model (visible when has3dModel is true). Use Page State to track the selected view mode. When Photos is selected, show the PageView. When 360 View is selected, replace it with the Product360Viewer Custom Widget. When 3D Model is selected, show the Product3DViewer. Place the View in AR button below the viewer, visible when hasAr is true. This ensures every product has a functional page regardless of available assets.
Expected result: Product pages gracefully upgrade from standard photos to 360-degree, 3D, and AR views based on available assets for each product.
Complete working example
1FIRESTORE DATA MODEL:2 products/{productId}3 name: String4 price: Double5 imageUrls: [String] (standard photos)6 has360: Boolean7 images360Urls: [String] (12-36 angle photos)8 has3dModel: Boolean9 model3dUrl: String (.glb or .gltf URL)10 hasAr: Boolean11 arModelUrl: String (.usdz for iOS, .glb for Android)1213PAGE: ProductDetailPage (Route: productId)14 Page State: viewMode ('photos' | '360' | '3d')1516 WIDGET TREE:17 Column18 ├── Container (viewer area, fixed aspect ratio)19 │ If viewMode == 'photos':20 │ PageView (imageUrls carousel)21 │ If viewMode == '360':22 │ Custom Widget: Product360Viewer(images360Urls)23 │ If viewMode == '3d':24 │ Custom Widget: Product3DViewer(model3dUrl)25 ├── Row (view mode toggles)26 │ ├── Button: Photos (always visible)27 │ ├── Button: 360 View (if has360)28 │ └── Button: 3D Model (if has3dModel)29 ├── Button: View in AR (if hasAr)30 │ iOS: AR Quick Look (.usdz)31 │ Android: Scene Viewer intent (.glb)32 ├── Text (product name, price)33 └── Button (Add to Cart)3435PROGRESSIVE ENHANCEMENT:36 All products: standard photo carousel37 Products with has360: + 360 spin viewer38 Products with has3dModel: + 3D model viewer39 Products with hasAr: + AR placement button4041360 VIEWER: GestureDetector swipe → cycle through image array423D VIEWER: model_viewer_plus with rotate/zoom/pan controls43AR: Platform-specific launch (Quick Look iOS, Scene Viewer Android)Common mistakes when creating a Virtual Reality Shopping Experience in FlutterFlow
Why it's a problem: Requiring all products to have 360-degree or 3D assets before launching
How to avoid: Make 360-degree and 3D views a progressive enhancement. Show a standard photo carousel by default and add immersive viewers only when assets are available for that specific product.
Why it's a problem: Loading all 36 high-resolution 360-degree images at once
How to avoid: Use compressed images (500-800px wide) for the 360 spinner. Preload images progressively and show a loading indicator. Cache images locally after first load.
Why it's a problem: Not providing AR model files in both .usdz and .glb formats
How to avoid: Generate both .usdz (iOS) and .glb (Android) versions of each AR model. Detect the platform at runtime and use the appropriate file URL.
Best practices
- Treat immersive viewers as progressive enhancements over standard product photos
- Compress 360-degree image sequences to reasonable sizes (500-800px) for fast loading
- Provide both .usdz (iOS) and .glb (Android) AR model files for cross-platform support
- Show a loading indicator while 360 images or 3D models are downloading
- Add instruction labels like 'Swipe to rotate' and 'Pinch to zoom' for discoverability
- Use cached_network_image for 360 sequences to avoid re-downloading on revisits
- Enable auto-rotate on 3D models so users immediately see that the model is interactive
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I want to build a VR/immersive shopping experience in FlutterFlow with 360-degree product image spinners, 3D model viewers using model_viewer_plus, and AR product placement for iOS and Android. Show me the product data model with immersive asset flags, Custom Widget code for 360 and 3D viewers, AR launch logic per platform, and how to progressively enhance product pages.
Create a product detail page with an image area at the top and three toggle buttons below it labeled Photos, 360 View, and 3D Model. Below that add a View in AR button and the product name and price text.
Frequently asked questions
How do I create 360-degree product image sequences?
Use a turntable setup with a camera taking photos every 10 degrees (36 images) or every 30 degrees (12 images). Services like Sirv or Cloudinary can host and optimize 360 image sets. Some smartphones with rotating stands can capture these automatically.
Where do I get 3D model files for my products?
Options include: hiring a 3D artist on platforms like Fiverr or Upwork, using photogrammetry apps like Polycam to scan physical products, or using AI tools like Meshy that generate 3D models from photos. Export as .glb for web/Android and .usdz for iOS.
Does AR work in the browser or only in native apps?
AR Quick Look (iOS) and Scene Viewer (Android) work from native apps. For web, model_viewer_plus supports WebXR which enables AR in Chrome on Android. iOS Safari has limited WebXR support, so native is recommended for iOS AR.
How much do immersive assets increase conversion rates?
Industry data shows 360-degree views increase conversion by 10-30%, and AR placement features reduce return rates by up to 25%. The investment in asset creation typically pays for itself through reduced returns alone.
Can I use video instead of 360-degree image sequences?
A turntable video works but lacks interactivity. Users cannot stop, reverse, or control the spin speed. Image sequences provide full user control. If video is all you have, use a standard video player as a fallback.
Can RapidDev help build an immersive shopping experience?
Yes. RapidDev can implement 360-degree viewers, 3D model integration, AR placement, virtual showrooms, and photogrammetry pipelines for creating product models at scale.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation