{"id":1525,"date":"2026-06-20T13:00:00","date_gmt":"2026-06-20T18:00:00","guid":{"rendered":"https:\/\/tolinku.com\/blog\/?p=1525"},"modified":"2026-03-07T03:53:07","modified_gmt":"2026-03-07T08:53:07","slug":"deep-linking-wearables","status":"publish","type":"post","link":"https:\/\/tolinku.com\/blog\/deep-linking-wearables\/","title":{"rendered":"Deep Linking for Wearables: Apple Watch and Wear OS"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Wearable apps receive deep links differently than phone apps. There is no web browser on an Apple Watch. Wear OS has limited browser capability. Screen real estate is tiny. Interactions are measured in seconds, not minutes. These constraints change how you think about deep linking for wearables.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This guide covers the practical implementation for both Apple Watch (watchOS) and Wear OS. For the foundational deep linking concepts, see <a href=\"https:\/\/tolinku.com\/blog\/universal-links-everything-you-need-to-know\/\">Universal Links<\/a> and <a href=\"https:\/\/tolinku.com\/blog\/android-app-links-complete-guide\/\">Android App Links<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><img decoding=\"async\" src=\"https:\/\/tolinku.com\/blog\/wp-content\/uploads\/2026\/03\/wearable-devices.jpeg\" alt=\"Person wearing smartwatch and using wearable technology\">\n<em>Photo by <a href=\"https:\/\/www.pexels.com\/@cottonbro\" rel=\"nofollow noopener\" target=\"_blank\">Cottonbro Studio<\/a> on Pexels<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How Deep Links Reach Wearables<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Apple Watch<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Deep links arrive on Apple Watch through several paths:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Notifications:<\/strong> A push notification on the paired iPhone gets mirrored to the Watch. Tapping the notification opens the Watch app to the relevant screen.<\/li>\n<li><strong>Handoff:<\/strong> The user views content on iPhone, then raises their wrist. The Watch can continue the activity via <a href=\"https:\/\/developer.apple.com\/documentation\/foundation\/nsuseractivity\" rel=\"nofollow noopener\" target=\"_blank\">Handoff<\/a>.<\/li>\n<li><strong>Complications:<\/strong> Watch face complications can link to specific screens in the Watch app.<\/li>\n<li><strong>Siri:<\/strong> Voice commands can trigger App Intents that open the Watch app.<\/li>\n<li><strong>Companion app forwarding:<\/strong> The iPhone app receives a deep link and forwards the relevant data to the Watch app via <a href=\"https:\/\/developer.apple.com\/documentation\/watchconnectivity\" rel=\"nofollow noopener\" target=\"_blank\">WatchConnectivity<\/a>.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Wear OS<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Deep links reach Wear OS devices through:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Notifications:<\/strong> Bridged notifications from the phone app.<\/li>\n<li><strong>Tiles:<\/strong> Quick-glance content cards that can launch the app to a specific screen.<\/li>\n<li><strong>Complications:<\/strong> Watch face complications that launch specific activities.<\/li>\n<li><strong>Google Assistant:<\/strong> Voice commands that trigger App Actions.<\/li>\n<li><strong>Standalone browsing:<\/strong> Wear OS 3+ supports limited web browsing, which can trigger App Links.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Apple Watch: Implementation<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Handling Universal Links via Notifications<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">When a notification contains a Universal Link, the Watch app receives it through <code>UNUserNotificationCenter<\/code>:<\/p>\n\n\n\n<pre><code class=\"language-swift\">\/\/ WatchApp\/ExtensionDelegate.swift\nimport UserNotifications\nimport WatchKit\n\nclass NotificationController: WKUserNotificationHostingController&lt;NotificationView&gt; {\n    var deepLinkPath: String?\n\n    override func didReceive(_ notification: UNNotification) {\n        let userInfo = notification.request.content.userInfo\n\n        if let urlString = userInfo[&quot;deep_link&quot;] as? String,\n           let url = URL(string: urlString) {\n            deepLinkPath = url.path\n        }\n    }\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Handoff Between iPhone and Watch<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Use <code>NSUserActivity<\/code> to pass context from the iPhone app to the Watch:<\/p>\n\n\n\n<pre><code class=\"language-swift\">\/\/ iPhone app: advertise the current activity\nfunc viewProduct(_ product: Product) {\n    let activity = NSUserActivity(activityType: &quot;com.yourapp.viewProduct&quot;)\n    activity.title = product.name\n    activity.userInfo = [&quot;productId&quot;: product.id]\n    activity.isEligibleForHandoff = true\n    activity.webpageURL = URL(string: &quot;https:\/\/yourapp.com\/products\/\\(product.slug)&quot;)\n\n    self.userActivity = activity\n    activity.becomeCurrent()\n}\n\n\/\/ Watch app: receive the handoff\nclass InterfaceController: WKInterfaceController {\n    override func handleUserActivity(_ userInfo: [AnyHashable: Any]?) {\n        guard let productId = userInfo?[&quot;productId&quot;] as? String else { return }\n        navigateToProduct(productId)\n    }\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Watch Complications as Deep Links<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Complications are the most visible entry point on Apple Watch. Each complication can link to a specific screen:<\/p>\n\n\n\n<pre><code class=\"language-swift\">import WidgetKit\nimport SwiftUI\n\nstruct OrderStatusComplication: Widget {\n    var body: some WidgetConfiguration {\n        StaticConfiguration(\n            kind: &quot;OrderStatus&quot;,\n            provider: OrderStatusProvider()\n        ) { entry in\n            OrderStatusView(entry: entry)\n                .widgetURL(URL(string: &quot;yourapp:\/\/orders\/\\(entry.orderId)&quot;))\n        }\n        .configurationDisplayName(&quot;Order Status&quot;)\n        .description(&quot;Track your current order&quot;)\n        .supportedFamilies([.accessoryCircular, .accessoryRectangular, .accessoryInline])\n    }\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">WatchConnectivity for Deep Link Forwarding<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">When the iPhone app receives a deep link, forward the relevant context to the Watch:<\/p>\n\n\n\n<pre><code class=\"language-swift\">import WatchConnectivity\n\nclass PhoneSessionManager: NSObject, WCSessionDelegate {\n    static let shared = PhoneSessionManager()\n\n    func forwardDeepLink(_ url: URL) {\n        guard WCSession.default.isWatchAppInstalled else { return }\n\n        let message: [String: Any] = [\n            &quot;type&quot;: &quot;deepLink&quot;,\n            &quot;path&quot;: url.path,\n            &quot;params&quot;: url.queryParameters\n        ]\n\n        if WCSession.default.isReachable {\n            WCSession.default.sendMessage(message, replyHandler: nil)\n        } else {\n            try? WCSession.default.updateApplicationContext(message)\n        }\n    }\n}\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Wear OS: Implementation<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">App Links on Wear OS<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Wear OS 3+ (based on Android) supports standard App Links. Declare intent filters in the Watch app manifest:<\/p>\n\n\n\n<pre><code class=\"language-xml\">&lt;!-- wear\/src\/main\/AndroidManifest.xml --&gt;\n&lt;activity android:name=&quot;.OrderDetailActivity&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;\/orders\/&quot; \/&gt;\n    &lt;\/intent-filter&gt;\n&lt;\/activity&gt;\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The same <code>assetlinks.json<\/code> verification works for both phone and Watch apps if they share the same package name.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Tiles as Deep Link Entry Points<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Wear OS <a href=\"https:\/\/developer.android.com\/training\/wearables\/tiles\" rel=\"nofollow noopener\" target=\"_blank\">Tiles<\/a> are glanceable cards. Each tile element can launch a specific activity:<\/p>\n\n\n\n<pre><code class=\"language-kotlin\">import androidx.wear.tiles.*\n\nclass OrderTileService : TileService() {\n    override fun onTileRequest(requestParams: RequestBuilders.TileRequest) =\n        Futures.immediateFuture(\n            Tile.Builder()\n                .setResourcesVersion(&quot;1&quot;)\n                .setTileTimeline(\n                    Timeline.Builder().addTimelineEntry(\n                        TimelineEntry.Builder().setLayout(\n                            Layout.Builder().setRoot(\n                                Text.Builder()\n                                    .setText(&quot;Order #1234: Ready for pickup&quot;)\n                                    .setModifiers(\n                                        Modifiers.Builder()\n                                            .setClickable(\n                                                Clickable.Builder()\n                                                    .setOnClick(\n                                                        ActionBuilders.LaunchAction.Builder()\n                                                            .setAndroidActivity(\n                                                                AndroidActivity.Builder()\n                                                                    .setPackageName(&quot;com.yourapp&quot;)\n                                                                    .setClassName(&quot;com.yourapp.OrderDetailActivity&quot;)\n                                                                    .addKeyToExtraMapping(&quot;orderId&quot;,\n                                                                        AndroidStringExtra.Builder().setValue(&quot;1234&quot;).build())\n                                                                    .build()\n                                                            ).build()\n                                                    ).build()\n                                            ).build()\n                                    ).build()\n                            ).build()\n                        ).build()\n                    ).build()\n                ).build()\n        )\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Data Layer for Phone-Watch Communication<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Use the <a href=\"https:\/\/developer.android.com\/training\/wearables\/data-layer\" rel=\"nofollow noopener\" target=\"_blank\">Data Layer API<\/a> to forward deep link context from the phone to the Watch:<\/p>\n\n\n\n<pre><code class=\"language-kotlin\">\/\/ Phone app: forward deep link data to Watch\nclass PhoneDeepLinkForwarder(private val context: Context) {\n    private val dataClient = Wearable.getDataClient(context)\n\n    fun forwardToWatch(path: String, params: Map&lt;String, String&gt;) {\n        val putDataReq = PutDataMapRequest.create(&quot;\/deep-link&quot;).run {\n            dataMap.putString(&quot;path&quot;, path)\n            params.forEach { (key, value) -&gt; dataMap.putString(key, value) }\n            dataMap.putLong(&quot;timestamp&quot;, System.currentTimeMillis())\n            asPutDataRequest().setUrgent()\n        }\n        dataClient.putDataItem(putDataReq)\n    }\n}\n\n\/\/ Watch app: receive deep link data\nclass WatchDeepLinkReceiver : WearableListenerService() {\n    override fun onDataChanged(dataEvents: DataEventBuffer) {\n        dataEvents.forEach { event -&gt;\n            if (event.type == DataEvent.TYPE_CHANGED &amp;&amp;\n                event.dataItem.uri.path == &quot;\/deep-link&quot;) {\n                val dataMap = DataMapItem.fromDataItem(event.dataItem).dataMap\n                val path = dataMap.getString(&quot;path&quot;)\n                handleDeepLink(path)\n            }\n        }\n    }\n}\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Design Considerations for Wearable Deep Links<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Content Adaptation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The same deep link URL should render different content on phone vs. watch:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Deep Link<\/th>\n<th>Phone Experience<\/th>\n<th>Watch Experience<\/th>\n<\/tr>\n<\/thead>\n<tbody><tr>\n<td><code>\/orders\/1234<\/code><\/td>\n<td>Full order details with items, map, tracking<\/td>\n<td>Order status, ETA, one-tap action<\/td>\n<\/tr>\n<tr>\n<td><code>\/products\/shoes<\/code><\/td>\n<td>Full product page with images, reviews<\/td>\n<td>Price, quick add to cart<\/td>\n<\/tr>\n<tr>\n<td><code>\/messages\/inbox<\/code><\/td>\n<td>Full message list with previews<\/td>\n<td>Unread count, latest message snippet<\/td>\n<\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Navigation Depth<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Keep watch navigation shallow. A deep link on the phone might open a screen 4 levels deep. On the watch, flatten the hierarchy:<\/p>\n\n\n\n<pre><code>Phone: Home \u2192 Orders \u2192 Order #1234 \u2192 Tracking Details\nWatch: Deep link \u2192 Order #1234 status (single screen)\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Offline Handling<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Wearables frequently lose connectivity. Handle deep links that arrive when the watch cannot fetch data:<\/p>\n\n\n\n<pre><code class=\"language-swift\">func handleDeepLink(_ path: String) {\n    if let cachedData = cache.get(path) {\n        display(cachedData)\n    } else if isConnected {\n        fetchAndDisplay(path)\n    } else {\n        showOfflineMessage(&quot;Connect to your phone to view this content&quot;)\n    }\n}\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Tolinku and Wearable Deep Links<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/tolinku.com\/features\/deep-linking\">Tolinku<\/a> handles the web-side routing for deep links that ultimately reach wearable apps. When a deep link URL is accessed (from a notification, a shared link, or a web search), Tolinku routes to the phone app via Universal Links or App Links. The phone app then forwards the context to the companion Watch app via WatchConnectivity or the Data Layer API.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Configure your deep link routes in the <a href=\"https:\/\/tolinku.com\/docs\/concepts\/deep-linking\/\">Tolinku dashboard<\/a>. The same routes work for both phone and wearable destinations.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Implement deep linking for wearable apps. Handle Apple Watch, Wear OS, and companion app linking with platform-specific considerations.<\/p>\n","protected":false},"author":2,"featured_media":1524,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"rank_math_title":"Deep Linking for Wearables: Apple Watch and Wear OS","rank_math_description":"Implement deep linking for wearable apps. Handle Apple Watch, Wear OS, and companion app linking with platform-specific considerations.","rank_math_focus_keyword":"deep linking wearables","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-wearables.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-wearables.png","footnotes":""},"categories":[11],"tags":[25,391,20,24,69,394,392,393],"class_list":["post-1525","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-deep-linking","tag-android","tag-apple-watch","tag-deep-linking","tag-ios","tag-mobile-development","tag-watchos","tag-wear-os","tag-wearables"],"_links":{"self":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1525","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=1525"}],"version-history":[{"count":4,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1525\/revisions"}],"predecessor-version":[{"id":2737,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1525\/revisions\/2737"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/media\/1524"}],"wp:attachment":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/media?parent=1525"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/categories?post=1525"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/tags?post=1525"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}