{"id":1528,"date":"2026-06-20T17:00:00","date_gmt":"2026-06-20T22:00:00","guid":{"rendered":"https:\/\/tolinku.com\/blog\/?p=1528"},"modified":"2026-03-07T03:53:07","modified_gmt":"2026-03-07T08:53:07","slug":"deep-linking-ar-vr-apps","status":"publish","type":"post","link":"https:\/\/tolinku.com\/blog\/deep-linking-ar-vr-apps\/","title":{"rendered":"Deep Linking for AR and VR Applications"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">AR and VR apps deal with spatial content: 3D models, scenes, environments, and anchored objects. Deep linking into these apps means not just opening a screen, but placing the user in a specific spatial context. A deep link to an AR furniture app should open with the selected sofa already loaded and ready to place in the room.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This guide covers deep linking patterns for AR and VR across Apple&#39;s visionOS\/ARKit, Google&#39;s ARCore, and standalone VR platforms. For the foundational deep linking standards, see <a href=\"https:\/\/tolinku.com\/blog\/deep-linking-standards-2026\/\">deep linking standards in 2026<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><img decoding=\"async\" src=\"https:\/\/tolinku.com\/blog\/wp-content\/uploads\/2026\/03\/ar-vr-headset.jpeg\" alt=\"Person wearing VR headset experiencing virtual reality\">\n<em>Photo by <a href=\"https:\/\/www.pexels.com\/@eren-li\" rel=\"nofollow noopener\" target=\"_blank\">Eren Li<\/a> on Pexels<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">AR Deep Linking on iOS (ARKit + RealityKit)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Quick Look AR Links<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Apple supports AR content through <a href=\"https:\/\/developer.apple.com\/documentation\/arkit\/previewing_a_model_with_ar_quick_look\" rel=\"nofollow noopener\" target=\"_blank\">Quick Look<\/a>, which lets users view 3D models in their environment directly from a web link:<\/p>\n\n\n\n<pre><code class=\"language-html\">&lt;!-- Web page with AR deep link --&gt;\n&lt;a rel=&quot;ar&quot; href=&quot;sofa-model.usdz&quot;&gt;\n  &lt;img src=&quot;sofa-preview.jpg&quot; alt=&quot;Modern Sofa - View in AR&quot;&gt;\n&lt;\/a&gt;\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When a user taps this link on an iOS device, the 3D model opens in Quick Look AR mode. No app required. This is the simplest form of AR deep linking.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For app-specific AR experiences, use Universal Links to open the AR scene in your app:<\/p>\n\n\n\n<pre><code class=\"language-swift\">class ARSceneController: UIViewController {\n    override func viewDidLoad() {\n        super.viewDidLoad()\n\n        guard let url = navigationContext?.deepLinkURL else { return }\n        let pathComponents = url.pathComponents\n\n        \/\/ \/ar\/furniture\/modern-sofa \u2192 load sofa model in AR\n        if pathComponents.contains(&quot;ar&quot;), pathComponents.count &gt;= 3 {\n            let category = pathComponents[2] \/\/ &quot;furniture&quot;\n            let modelSlug = pathComponents[3] \/\/ &quot;modern-sofa&quot;\n            loadARModel(category: category, slug: modelSlug)\n        }\n    }\n\n    func loadARModel(category: String, slug: String) {\n        let modelURL = ModelCatalog.url(for: slug)\n        let anchor = AnchorEntity(plane: .horizontal)\n        let model = try? ModelEntity.load(contentsOf: modelURL)\n        anchor.addChild(model ?? ModelEntity())\n        arView.scene.anchors.append(anchor)\n    }\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Scene Links with Parameters<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">AR deep links can include spatial parameters:<\/p>\n\n\n\n<pre><code>\/ar\/furniture\/modern-sofa                    \u2192 Load model in default placement\n\/ar\/furniture\/modern-sofa?color=navy         \u2192 Load with specific color variant\n\/ar\/furniture\/modern-sofa?scale=0.8          \u2192 Load at 80% scale\n\/ar\/room\/living-room?layout=open-concept     \u2192 Load a room configuration\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">AR Deep Linking on Android (ARCore)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Scene Viewer<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Google&#39;s <a href=\"https:\/\/developers.google.com\/ar\/develop\/scene-viewer\" rel=\"nofollow noopener\" target=\"_blank\">Scene Viewer<\/a> is the Android equivalent of Apple Quick Look. It renders 3D models in AR without requiring your app:<\/p>\n\n\n\n<pre><code class=\"language-html\">&lt;!-- Intent URL for Scene Viewer --&gt;\n&lt;a href=&quot;intent:\/\/arvr.google.com\/scene-viewer\/1.0?file=https:\/\/yourapp.com\/models\/sofa.glb&amp;mode=ar_preferred&amp;title=Modern+Sofa&amp;link=https:\/\/yourapp.com\/products\/modern-sofa#Intent;scheme=https;package=com.google.android.googlequicksearchbox;action=android.intent.action.VIEW;end;&quot;&gt;\n  View in AR\n&lt;\/a&gt;\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>link<\/code> parameter in the Scene Viewer intent is a deep link back to your app or web page. When the user taps the title in Scene Viewer, they go to your product page.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">App-Specific AR via App Links<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">For custom AR experiences in your own app:<\/p>\n\n\n\n<pre><code class=\"language-kotlin\">class ARActivity : AppCompatActivity() {\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n\n        val uri = intent.data ?: return\n        \/\/ https:\/\/yourapp.com\/ar\/products\/modern-sofa?variant=navy\n        val productSlug = uri.pathSegments.lastOrNull() ?: return\n        val variant = uri.getQueryParameter(&quot;variant&quot;)\n\n        arViewModel.loadModel(productSlug, variant)\n    }\n}\n<\/code><\/pre>\n\n\n\n<pre><code class=\"language-xml\">&lt;activity android:name=&quot;.ARActivity&quot;\n    android:exported=&quot;true&quot;&gt;\n    &lt;intent-filter android:autoVerify=&quot;true&quot;&gt;\n        &lt;action android:name=&quot;android.intent.action.VIEW&quot; \/&gt;\n        &lt;category android:name=&quot;android.intent.category.DEFAULT&quot; \/&gt;\n        &lt;category android:name=&quot;android.intent.category.BROWSABLE&quot; \/&gt;\n        &lt;data android:scheme=&quot;https&quot;\n              android:host=&quot;yourapp.com&quot;\n              android:pathPrefix=&quot;\/ar\/&quot; \/&gt;\n    &lt;\/intent-filter&gt;\n&lt;\/activity&gt;\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">VisionOS and Spatial Computing<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Universal Links on visionOS<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Apple Vision Pro runs visionOS, which supports Universal Links the same way iOS does. The difference is in how you present the content:<\/p>\n\n\n\n<pre><code class=\"language-swift\">\/\/ visionOS app: handle deep link to open a volumetric window\nclass AppDelegate: NSObject, UIApplicationDelegate {\n    func application(_ application: UIApplication,\n                     continue userActivity: NSUserActivity,\n                     restorationHandler: @escaping ([UIUserActivityRestoring]?) -&gt; Void) -&gt; Bool {\n        guard let url = userActivity.webpageURL else { return false }\n\n        if url.pathComponents.contains(&quot;3d-model&quot;) {\n            let modelSlug = url.lastPathComponent\n            openVolumetricWindow(for: modelSlug)\n            return true\n        }\n\n        return false\n    }\n\n    func openVolumetricWindow(for modelSlug: String) {\n        \/\/ Open a volumetric window showing the 3D model\n        \/\/ Users can walk around it in their physical space\n    }\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Immersive Space Links<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Deep links can open full immersive spaces on visionOS:<\/p>\n\n\n\n<pre><code class=\"language-swift\">@main\nstruct MyVRApp: App {\n    var body: some Scene {\n        WindowGroup {\n            ContentView()\n        }\n\n        ImmersiveSpace(id: &quot;vrScene&quot;) {\n            VRSceneView()\n        }\n    }\n}\n\n\/\/ Handle deep link to open immersive space\nfunc handleDeepLink(_ url: URL) {\n    if url.path.hasPrefix(&quot;\/vr\/&quot;) {\n        let sceneId = url.lastPathComponent\n        openImmersiveSpace(id: &quot;vrScene&quot;, value: sceneId)\n    }\n}\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">URL Structure for AR\/VR Content<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Recommended Patterns<\/h3>\n\n\n\n<pre><code>AR experiences:\n  \/ar\/{category}\/{model-slug}              \u2192 AR view of a specific model\n  \/ar\/{category}\/{model-slug}?color=blue   \u2192 AR view with parameters\n  \/ar\/scan\/{scene-id}                      \u2192 AR scene with anchored content\n\nVR experiences:\n  \/vr\/spaces\/{space-slug}                  \u2192 Virtual space\/environment\n  \/vr\/tours\/{tour-slug}                    \u2192 Virtual tour\n  \/vr\/events\/{event-slug}                  \u2192 Virtual event\n\n3D content:\n  \/3d\/{model-slug}                         \u2192 3D model viewer (non-AR)\n  \/3d\/{model-slug}.usdz                    \u2192 Direct model download (Apple)\n  \/3d\/{model-slug}.glb                     \u2192 Direct model download (Android)\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Web Fallback Pages for AR Content<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The web page for an AR deep link should include:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Product images<\/strong> (2D fallback for the 3D model).<\/li>\n<li><strong>AR launch button<\/strong> (opens AR on supported devices).<\/li>\n<li><strong>Product details<\/strong> (for SEO and non-AR users).<\/li>\n<li><strong>3D model metadata<\/strong> for structured data:<\/li>\n<\/ol>\n\n\n\n<pre><code class=\"language-html\">&lt;script type=&quot;application\/ld+json&quot;&gt;\n{\n  &quot;@context&quot;: &quot;https:\/\/schema.org&quot;,\n  &quot;@type&quot;: &quot;3DModel&quot;,\n  &quot;name&quot;: &quot;Modern Sofa - Navy&quot;,\n  &quot;contentUrl&quot;: &quot;https:\/\/yourapp.com\/models\/modern-sofa-navy.glb&quot;,\n  &quot;encodingFormat&quot;: &quot;model\/gltf-binary&quot;,\n  &quot;associatedMedia&quot;: {\n    &quot;@type&quot;: &quot;ImageObject&quot;,\n    &quot;contentUrl&quot;: &quot;https:\/\/yourapp.com\/images\/modern-sofa-navy.jpg&quot;\n  }\n}\n&lt;\/script&gt;\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Sharing AR\/VR Content via Deep Links<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">AR Experience Sharing<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">When a user finds a product they like in AR, let them share the experience:<\/p>\n\n\n\n<pre><code class=\"language-swift\">func shareARExperience(model: ARModel, placement: ARPlacement?) {\n    var components = URLComponents(string: &quot;https:\/\/yourapp.com\/ar\/\\(model.category)\/\\(model.slug)&quot;)\n\n    \/\/ Include current configuration\n    var queryItems: [URLQueryItem] = []\n    if let color = model.selectedColor {\n        queryItems.append(URLQueryItem(name: &quot;color&quot;, value: color))\n    }\n    if let scale = placement?.scale {\n        queryItems.append(URLQueryItem(name: &quot;scale&quot;, value: String(scale)))\n    }\n    components?.queryItems = queryItems.isEmpty ? nil : queryItems\n\n    guard let url = components?.url else { return }\n\n    let activityVC = UIActivityViewController(\n        activityItems: [url],\n        applicationActivities: nil\n    )\n    present(activityVC, animated: true)\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The recipient gets a deep link that opens the same AR experience with the same model and configuration.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">VR Event Links<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">For virtual events, the deep link should include timing information:<\/p>\n\n\n\n<pre><code>https:\/\/yourapp.com\/vr\/events\/product-launch-2026?start=2026-07-15T18:00:00Z\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the event has not started, show a countdown. If it is live, join immediately. If it is over, show a recording.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Cross-Platform Considerations<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Model Format Compatibility<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Different platforms support different 3D formats:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Platform<\/th>\n<th>Preferred Format<\/th>\n<th>Fallback<\/th>\n<\/tr>\n<\/thead>\n<tbody><tr>\n<td>iOS\/visionOS<\/td>\n<td>USDZ<\/td>\n<td>GLTF<\/td>\n<\/tr>\n<tr>\n<td>Android<\/td>\n<td>GLB\/GLTF<\/td>\n<td>OBJ<\/td>\n<\/tr>\n<tr>\n<td>Web (WebXR)<\/td>\n<td>GLTF\/GLB<\/td>\n<td>OBJ<\/td>\n<\/tr>\n<tr>\n<td>Meta Quest<\/td>\n<td>GLB\/GLTF<\/td>\n<td>FBX<\/td>\n<\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Your deep link handler should detect the platform and serve the appropriate format:<\/p>\n\n\n\n<pre><code class=\"language-javascript\">\/\/ Web page: detect platform and offer the right AR experience\nfunction getARLink(modelSlug) {\n  const isIOS = \/iPad|iPhone|iPod\/.test(navigator.userAgent);\n  const isAndroid = \/Android\/.test(navigator.userAgent);\n\n  if (isIOS) {\n    return `\/models\/${modelSlug}.usdz`; \/\/ Quick Look\n  } else if (isAndroid) {\n    return `intent:\/\/arvr.google.com\/scene-viewer\/1.0?file=https:\/\/yourapp.com\/models\/${modelSlug}.glb&amp;mode=ar_preferred#Intent;scheme=https;package=com.google.android.googlequicksearchbox;end;`;\n  } else {\n    return `\/3d\/${modelSlug}`; \/\/ Web 3D viewer\n  }\n}\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Tolinku for AR\/VR Deep Links<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/tolinku.com\/features\/deep-linking\">Tolinku<\/a> routes deep links to AR\/VR content across platforms. Configure routes like <code>\/ar\/:category\/:slug<\/code> in the <a href=\"https:\/\/tolinku.com\/docs\/concepts\/deep-linking\/\">Tolinku dashboard<\/a>, and Tolinku handles platform detection, app-installed vs. not-installed routing, and web fallback pages with AR launch buttons.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For more on deep linking trends, see <a href=\"https:\/\/tolinku.com\/blog\/future-mobile-deep-linking\/\">the future of mobile deep linking<\/a>. For wearable deep linking, see <a href=\"https:\/\/tolinku.com\/blog\/deep-linking-wearables\/\">deep linking for wearables<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Build deep links for augmented and virtual reality apps. Handle spatial content linking, scene navigation, and cross-reality experiences.<\/p>\n","protected":false},"author":2,"featured_media":1527,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"rank_math_title":"Deep Linking for AR and VR Applications","rank_math_description":"Build deep links for augmented and virtual reality apps. Handle spatial content linking, scene navigation, and cross-reality experiences.","rank_math_focus_keyword":"deep linking AR VR","rank_math_canonical_url":"","rank_math_facebook_title":"","rank_math_facebook_description":"","rank_math_facebook_image":"https:\/\/tolinku.com\/blog\/wp-content\/uploads\/2026\/03\/og-deep-linking-ar-vr-apps.png","rank_math_facebook_image_id":"","rank_math_twitter_title":"","rank_math_twitter_description":"","rank_math_twitter_image":"https:\/\/tolinku.com\/blog\/wp-content\/uploads\/2026\/03\/og-deep-linking-ar-vr-apps.png","footnotes":""},"categories":[11],"tags":[398,397,395,20,69,399,396,400],"class_list":["post-1528","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-deep-linking","tag-arcore","tag-arkit","tag-augmented-reality","tag-deep-linking","tag-mobile-development","tag-spatial-computing","tag-virtual-reality","tag-visionos"],"_links":{"self":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1528","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/comments?post=1528"}],"version-history":[{"count":4,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1528\/revisions"}],"predecessor-version":[{"id":2738,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1528\/revisions\/2738"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/media\/1527"}],"wp:attachment":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/media?parent=1528"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/categories?post=1528"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/tags?post=1528"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}