Skip to main content
RapidDev - Software Development Agency
App Featuresmedia-content21 min read

How to Add AR Previews to Your App — Copy-Paste Prompts Inside

Augmented reality previews overlay a 3D model or image on the user's live camera feed so they can place a product in their real environment before buying. The feature needs ARKit (iOS) or ARCore (Android) via ar_flutter_plugin, .usdz and .glb model files in Supabase Storage, camera permission handling, and a screenshot export. Expect 2–4 days with FlutterFlow plus manual AR plugin wiring; web-only tools like Lovable and V0 cannot deliver true AR — WebXR on iOS Safari is too limited in 2026.

4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members

Feature spec

Advanced

Category

media-content

Build with AI

2–4 days with FlutterFlow + manual AR plugin wiring

Custom build

3–6 weeks custom dev

Running cost

$0–25/mo (Supabase for model storage); bandwidth scales with .glb file size × loads

Works on

WebMobile

Everything it takes to ship Augmented Reality Previews — parts, prompts, and real costs.

TL;DR

Augmented reality previews overlay a 3D model or image on the user's live camera feed so they can place a product in their real environment before buying. The feature needs ARKit (iOS) or ARCore (Android) via ar_flutter_plugin, .usdz and .glb model files in Supabase Storage, camera permission handling, and a screenshot export. Expect 2–4 days with FlutterFlow plus manual AR plugin wiring; web-only tools like Lovable and V0 cannot deliver true AR — WebXR on iOS Safari is too limited in 2026.

What an Augmented Reality Preview Feature Actually Is

An AR preview feature places a 3D model of your product into the user's physical space through their phone camera — a furniture retailer lets shoppers see a sofa in their living room; a cosmetics brand shows lipstick shades on the user's face. The core technology is ARKit on iOS (16+) and ARCore on Android (9+), both accessed through the Flutter ar_flutter_plugin. The feature's three hard problems are: sourcing correctly formatted 3D models (.usdz for iOS, .glb for Android), handling camera permission denial gracefully, and compositing the camera feed with the Flutter overlay correctly in a screenshot. Web-based tools (Lovable, V0) cannot deliver true AR — the WebXR Device API lacks ARKit plane detection on iOS as of 2026. This is a mobile-native feature.

What users consider table stakes in 2026

  • Live camera feed as the background with zero perceptible lag between device movement and AR overlay update
  • 3D model or image overlay that tracks a flat surface (furniture, decor) or the user's face (cosmetics, eyewear) in real time
  • Pinch-to-scale gesture adjusting the placed model between 0.5× and 3× of its original size
  • Drag gesture to reposition the placed model on the detected surface without it drifting
  • Screenshot capture button that saves the composed AR view (camera feed + overlay) to the device photo library
  • Clear 'Try in your space' CTA on the product detail page explaining what the user is about to experience
  • Graceful fallback screen with static product images when the device does not support AR or camera permission is denied

Anatomy of the Feature

Six components. AR session management and camera permission handling are where first builds stall. The model format pipeline is a parallel workstream that must be planned before development begins.

Layers:UIDataBackendService

AR session manager

Backend

Initializes and manages the ARKit (iOS) or ARCore (Android) session. In Flutter, the ar_flutter_plugin package wraps both native frameworks behind a unified Dart API. The session handles plane detection, hit-testing (finding where the user taps on a detected surface), and anchor placement (pinning the 3D model to a world coordinate).

Note: ar_flutter_plugin requires a Custom Action in FlutterFlow (Dart code). The plugin works on real devices only — never in FlutterFlow's in-browser preview or in a simulator without ARCore support.

3D model renderer

Service

Renders the 3D model anchored to the detected surface. iOS uses SceneKit with .usdz files (the format Apple mandates for Quick Look AR). Android uses ARCore's SceneViewer with .glb or .gltf files. Model files are stored in Supabase Storage and fetched by URL at session start. For web fallback: Google's Model Viewer web component provides 3D rotation (not true AR) in a browser.

Note: Models must use PBR metallic-roughness materials for correct rendering on Android. Blender and Sketchfab exports often default to other material models — validate every .glb file with Google's gltf-validator web tool before uploading.

Camera permission layer

UI

Requests camera access using Flutter's permission_handler package. Must handle three states: granted (start AR session), denied (show explainer with 'Try again' button), and permanentlyDenied (show dialog explaining how to enable camera in Settings, then call openAppSettings() to deep-link to device Settings).

Note: iOS requires NSCameraUsageDescription in Info.plist with a specific usage string. Android requires CAMERA permission in AndroidManifest.xml. FlutterFlow exposes both in Settings → Permissions.

Surface / face tracker

Backend

Detects flat horizontal or vertical planes (ARKit Plane Detection, ARCore Plane Discovery) for furniture-style AR, or tracks facial landmarks (Apple Vision framework, ARKit Face Tracking) for cosmetics try-on. An animated ring overlay on the detected floor surface indicates to the user where the model will be placed.

Note: Plane detection struggles on plain white or highly reflective floors. Add a hint overlay — 'Point at a textured surface for best results' — that appears when plane detection confidence is low.

Capture and share

UI

Saves the AR view as a PNG to the device photo library. Flutter's RenderRepaintBoundary.toImage() does NOT capture the camera texture (it is an external texture not in the Flutter widget tree) — requires platform-specific capture: ARSCNView.snapshot() on iOS, Frame.acquireCameraImage() composite on Android, or the screen_capturer package for a native screen buffer capture.

Note: The Share Plus package triggers the native share sheet after capture, letting users post directly to Instagram, TikTok, or messaging apps.

Model asset store

Data

Supabase Storage bucket holding .usdz and .glb model files (1–20 MB each). A products table with ar_assets rows links each product to its platform-specific model URLs. scale_factor stores the initial display scale so a chair renders at chair-size, not doll-size or building-size.

Note: Use signed URLs for private model assets (paid or licensed 3D models). Public buckets are fine for freely available models. Specify the platform column ('ios' or 'android') on each ar_assets row so the app fetches the correct format for the current device.

The data model

Two tables link products to their platform-specific AR models; run this in the Supabase SQL editor:

schema.sql
1-- Products table (extend if you already have one)
2create table if not exists public.products (
3 id uuid primary key default gen_random_uuid(),
4 name text not null,
5 description text,
6 thumbnail_url text,
7 created_at timestamptz not null default now()
8);
9
10-- AR assets linked to products
11create table public.ar_assets (
12 id uuid primary key default gen_random_uuid(),
13 product_id uuid references public.products(id) on delete cascade not null,
14 platform text not null check (platform in ('ios', 'android', 'web')),
15 model_url text not null,
16 thumbnail_url text,
17 scale_factor float not null default 1.0,
18 created_at timestamptz not null default now()
19);
20
21alter table public.ar_assets enable row level security;
22alter table public.products enable row level security;
23
24-- Public read for product catalog (adjust if catalog is private)
25create policy "Anyone can view products"
26 on public.products for select
27 using (true);
28
29create policy "Anyone can view AR assets"
30 on public.ar_assets for select
31 using (true);
32
33-- Admins only for insert/update (assuming admin role or service key)
34-- Add admin-specific policies here if needed
35
36create index ar_assets_product_platform_idx
37 on public.ar_assets (product_id, platform);

Heads up: The composite index on (product_id, platform) makes the per-device asset lookup fast — the app queries WHERE product_id = ? AND platform = 'ios' to get the right model format. Store model_url as the Supabase Storage path (not the full signed URL) and generate signed URLs at request time for private assets.

Build it — pick your path

Each tool fits this feature differently. Switch tabs to compare fit, time, the exact steps, and a copy-paste prompt.

Hand-built by developersFit for this feature:

Full native stack: Swift/ARKit (iOS) + Kotlin/ARCore (Android), or a complete Flutter app with ar_flutter_plugin and full Dart code. The right path when AR quality and feature depth (face tracking, multi-user anchors, model optimization) directly affect product value.

Step by step

  1. 1Native Swift + ARKit (iOS) and Kotlin + ARCore (Android), or Flutter with ar_flutter_plugin and complete Dart code — full access to every ARKit and ARCore API without FlutterFlow abstraction layers
  2. 23D model pipeline: product photography → photogrammetry tool (Polycam, RealityCapture, or Poly.cam) or 3D artist → .usdz conversion via Apple's Reality Converter + .glb validation via Google's gltf-validator → Draco compression for bandwidth optimization → Supabase Storage
  3. 3Server-side model optimization via a Supabase Edge Function: validate model formats on upload, reject files with unsupported material types before they reach the asset library
  4. 4Advanced features: Apple Vision framework for face tracking (cosmetics try-on), ARCore Cloud Anchors for multi-user shared AR sessions, ARKit's LiDAR-based occlusion on Pro iPhones for photorealistic model placement behind furniture

Where this path bites

  • ARKit/ARCore expertise is required — this is not a generalist web development skill
  • 3D model asset pipeline (photography, modeling, format conversion, optimization) is a separate workstream that can add weeks and budget to the project
  • iOS App Store requires a full app submission; TestFlight for beta testing — the AR experience cannot be previewed in a browser

Third-party services you'll need

AR rendering uses native device frameworks (free). You pay only for 3D model hosting and optionally for model creation tools:

ServiceWhat it doesFree tierPaid from
Supabase StorageHosts .usdz and .glb model files (1–20 MB each) and product thumbnail images; serves via global CDN1 GB included on Supabase Free plan — covers roughly 50–200 models depending on file size$0.021/GB/mo storage + $0.09/GB/mo bandwidth (approx)
Apple Quick Look / ARKitNative iOS AR session, plane detection, .usdz model rendering — built into iOS 16+, no API key or costFree, built-in on iOS 16+Free
Google Scene Viewer / ARCoreNative Android AR session, .glb model rendering — built into Android 9+ via Google Play Services for ARFree, built-in on Android 9+Free
Sketchfab3D model hosting with viewer embed; large library of existing models that can be licensed$0 hobby plan (limited uploads)$79/mo Pro (approx)
Meshy.ai / Poly.camAI-generated 3D models from product photos (photogrammetry or text-to-3D); reduces need for a 3D artistLimited free credits$20–100/mo approx (unverified, check current pricing)

Swipe the table sideways to see pricing.

What it costs to run

Drag through the tiers to see how your monthly bill scales with users — no surprises later.

Estimated monthly running cost

$5/mo

Supabase free tier covers storage if total model files are under 1 GB (roughly 50–100 models at 5–10 MB each). Small CDN bandwidth cost for serving models: 100 users × 5 model loads × 5 MB = 2.5 GB × $0.09 = $0.23/mo. Round to ~$0–5 depending on model library size.

Estimates use verified 2026 pricing and assume typical usage per user. Your real bill depends on activity, storage, and third-party plans.

What breaks when AI tools build this

The failures people actually hit on their first build — the symptom, why it happens, and the exact fix.

AR session never starts in FlutterFlow Test Mode

Symptom: FlutterFlow's in-browser preview runs in a web environment that has no access to native ARKit or ARCore APIs. When ar_flutter_plugin tries to initialize the AR session in this environment, the call fails silently — the camera feed never appears and the AR page looks completely broken. This is not a bug in your implementation.

Fix: All AR testing must happen on a real physical device. In FlutterFlow, use Test on Device (download and install the debug APK on Android, or use TestFlight for iOS) to get a native build on your phone. Never demo the AR feature in the FlutterFlow browser preview — it will always appear broken.

Camera permission denied permanently with no recovery path

Symptom: AI tools and most scaffolded code make a single camera permission request. On iOS and Android, if the user taps 'Deny' once (or 'Don't Ask Again' on Android), all future permission requests are silently rejected without prompting the user again. The AR page appears to hang or shows a black camera feed with no explanation.

Fix: Use permission_handler to check PermissionStatus after every request. On permanentlyDenied, call openAppSettings() which deep-links to the device's Settings app where the user can manually enable camera access. Show a clear dialog before this redirect: 'Camera access is required for AR previews. Tap Open Settings to enable it.' Specify all three states (granted, denied, permanentlyDenied) in your prompt.

.usdz loads on iOS but .glb shows a black box on Android

Symptom: ARCore requires .glb files using the glTF 2.0 specification with PBR metallic-roughness materials. 3D models exported from common tools (Blender, Sketchfab) may use unsupported material types (KHR_materials_unlit, or non-standard extensions) that ARCore cannot render — resulting in a black or invisible model at placement time.

Fix: Validate every .glb file with Google's gltf-validator (available as a web tool at khronos.github.io/glTF-Validator/) before uploading to Supabase Storage. Export from Blender using 'Format: glTF 2.0', 'Materials: PBR Metallic Roughness' settings. Test on a real Android 10+ device — the ARCore viewer behaves differently from desktop WebGL previews.

Plane detection anchor drifts on low-texture floors

Symptom: ARKit and ARCore use visual feature points from the camera feed to detect flat surfaces. On plain white floors, solid-color carpets, or highly reflective (glossy) surfaces, there are too few visual features for reliable plane detection. The detected plane drifts as the device moves, causing the placed model to slide around instead of staying fixed.

Fix: Add a hint overlay that appears when plane detection confidence is below a threshold: 'Point your camera at a patterned surface for better AR tracking.' Use ARKit's worldAlignment = .gravityAndHeading for more stable anchors on iOS. Display the animated ring indicator only when a plane is actively detected, not continuously — this sets correct user expectations about when placement is reliable.

Screenshot captures a black frame instead of the AR composite

Symptom: Flutter's RenderRepaintBoundary.toImage() captures only the Flutter widget layer overlay (buttons, UI chrome) and not the camera texture, which is rendered as a native platform view (an 'external texture') outside the Flutter widget tree. The resulting screenshot is a black background with only the AR UI buttons visible.

Fix: Use the screen_capturer Flutter package which captures the native screen buffer including the camera texture. On iOS, alternatively use ARSCNView.snapshot() called via a Method Channel. On Android, use MediaProjection or Frame.acquireCameraImage() and composite manually. Specify 'use screen_capturer package for screenshot, not RenderRepaintBoundary' in your Custom Action prompt.

Best practices

1

Validate every .glb file with Google's gltf-validator before uploading to Supabase Storage — invalid material types cause invisible models on Android without any error message to the user

2

Handle all three camera permission states explicitly: granted (start AR), denied (show rationale + try again button), permanentlyDenied (show Settings redirect dialog) — a missing permanentlyDenied handler silently breaks the feature for returning users who already denied once

3

Store model_url as a Supabase Storage path (not a full signed URL) and generate signed URLs on demand — signed URLs expire, and hardcoded URLs break when bucket configuration changes

4

Add a scale_factor column to your ar_assets table and apply it on model load — models without calibrated scale often appear the size of a toy or a building, ruining the spatial preview experience

5

Show a surface detection ring animation on the floor before allowing model placement — this teaches users to move their phone slowly across the room and dramatically reduces 'the AR doesn't work' support requests

6

Add a 'How to use AR' tooltip overlay on first launch (shown only once, dismissed by tap) explaining that the user should point at a flat surface — first-time AR users consistently miss this step

7

Use Draco compression on .glb files (reducible to 10–30% of original size) before uploading to Storage — a 20 MB model on a slow connection produces a loading bar long enough for users to abandon the feature

8

Always ship a static product image fallback for devices that fail the ARCore/ARKit support check or deny camera permission — AR-capable devices are still not universal

When You Need Custom Development

FlutterFlow with Custom Actions covers basic surface-placement AR for a product catalog. These requirements go beyond what FlutterFlow can reliably deliver:

  • App requires face tracking for cosmetics or eyewear try-on using Apple Vision framework or Snap AR Lens Studio — these APIs require native Swift/Kotlin code and are not accessible through Flutter plugins in FlutterFlow
  • 3D models need to be generated from user-uploaded product photos using photogrammetry — this requires a server-side processing pipeline (Polycam API, RealityCapture, or custom NeRF pipeline) that is separate from the app entirely
  • Real-time multi-user AR collaboration is required — shared ARCore Cloud Anchors or Apple's SharePlay AR session need native implementation and significant backend work
  • Retail industry AR accessibility standards or specific accuracy requirements (furniture AR must be true-to-scale within 2%) mandate native ARKit LiDAR-based occlusion and measurement calibration

RapidDev builds these features for production

Real auth, database, and payments — fixed price, delivered in weeks. You own 100% of the code.

Get a fixed-price quote

Frequently asked questions

Does AR work on all Android phones or only newer ones?

ARCore requires Android 9+ (Pie) and a device on Google's ARCore supported devices list. As of 2026, the vast majority of actively used Android phones qualify — but very low-end devices (under $100) and older flagship models from 2017 and earlier may not. Use ARCoreApk.checkAvailability() at app launch to detect support and route unsupported users to the 2D fallback.

Do I need a 3D artist to create the models, or can I convert product photos automatically?

Photogrammetry tools like Poly.cam, Polycam, and RealityCapture can generate a rough 3D model from 20–40 product photos taken from different angles — no 3D artist needed for simple objects. Complex items (transparent glass, highly reflective surfaces, very thin parts) still need a 3D modeler. AI text-to-3D tools (Meshy.ai) can generate plausible models from a text description for prototyping, though output quality varies significantly. Budget for manual cleanup by a 3D artist for production quality.

Will AR previews work in poor lighting conditions?

ARKit and ARCore both degrade in very dark environments — plane detection and tracking require visible textures and features in the camera feed. Below roughly 50 lux (dim indoor lighting) you will see increased anchor drift and failed plane detection. Add lighting hints in your surface detection guidance UI: 'For best results, use in a well-lit room.' ARKit includes an ambient light estimate you can read to show a warning when lighting is too low.

Can users share their AR screenshot directly to Instagram or TikTok?

Yes. Capture the screen using the screen_capturer Flutter package (which includes the camera texture), then trigger Share Plus's share() method with the file path. On iOS and Android, this opens the native share sheet where users can choose Instagram, TikTok, Messages, or any installed app as the target. Some apps (notably Instagram Stories) support direct sharing via their URI schemes — wire these separately if you want one-tap share to a specific platform.

How large are the 3D model files and will they slow down my app?

Raw .glb exports from Blender or Sketchfab are typically 5–50 MB per model. Apply Draco mesh compression (integrated into Blender's glTF exporter and the gltf-pipeline tool) to reduce this to 1–5 MB per model. Show a download progress bar when models load over cellular — a 20 MB model on a slow 4G connection takes 5–15 seconds and users will assume the feature is broken without a visible indicator.

Is ARKit only for iOS — what do Android users get?

ARKit is Apple-only (iOS 16+ and iPadOS). Android users get ARCore, which provides comparable functionality: plane detection, hit testing, anchor placement, and light estimation. Both are accessed through Flutter's ar_flutter_plugin with a unified API. The only difference your app needs to handle is the model format: .usdz for iOS, .glb for Android. Store both in Supabase Storage and select the correct one based on Platform.isIOS at runtime.

Can the AR preview show a product in multiple colors without loading a new model?

Yes, for simple color swaps. ARKit and ARCore both support material property changes at runtime — you can update the albedo color of a material on an already-placed model without reloading the entire .usdz or .glb file. This requires native code or a Flutter method channel call to the AR session, specifying the material index and the new color value. It is not supported out of the box in ar_flutter_plugin — plan it as a custom extension if color switching is a product requirement.

How accurate is the scale — will furniture AR previews be true-to-size?

On standard phones, ARKit and ARCore achieve ±5–10% scale accuracy on flat surfaces, which is sufficient for most furniture previews. On iPhone Pro models with a LiDAR scanner (iPhone 12 Pro and later), ARKit uses depth data to improve both scale accuracy and placement speed significantly — LiDAR phones detect surfaces 4–5× faster and achieve ±2–3% scale accuracy. If true-to-scale accuracy is a product promise, target LiDAR-equipped iPhones as your primary device tier and communicate this to users.

RapidDev

Need this feature production-ready?

RapidDev builds augmented reality previews into real apps — auth, database, payments — at $13K–$25K.

Book a free consultation

30-min call. No commitment.

Want this built for you?

We ship production apps at a fixed price — $13K–$25K, 6–10 weeks, source code yours. You've seen what it takes; we do it every week.

Get a fixed-price quote

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.