Universal Links on iOS and App Links on Android represent the modern, secure, and user-friendly evolution of deep linking. Unlike older custom URI schemes (e.g., mycoolapp://product/123) which often broke if the app wasn't installed, Universal Links and App Links leverage standard HTTP/HTTPS URLs. This means a single URL can intelligently open your app to specific content if it's installed on the user's device, or gracefully fall back to the corresponding page on your website if the app isn't present. This provides a significantly smoother and more reliable user experience, eliminating broken link errors and ensuring content is always accessible.
The core mechanism involves establishing a verifiable association between your web domain and your mobile application. For iOS, you host a apple-app-site-association file (a JSON file) at the root of your domain (yourdomain.com/.well-known/apple-app-site-association). Android uses a similar assetlinks.json file. These files declare which URL paths on your domain your app is authorized to handle. On the client side, your app must declare support for these associated domains: iOS apps use the "Associated Domains" capability in Xcode, and Android apps use <intent-filter> declarations with android:autoVerify="true" in their AndroidManifest.xml.
When a user taps a Universal Link or App Link, the operating system first checks the pre-established trust relationship between the domain and the app. If the association is valid and the app is installed, it opens the app directly to the specified content, providing a seamless transition from web to app. If the app isn't installed, or if the link doesn't match a configured path, the link simply opens in the default web browser. This approach not only enhances user experience but also improves security, as only domains you explicitly control can launch your app, and offers better search engine optimization for app content (especially with App Links and Google Search).
Key Takeaways
- Uses standard HTTP/HTTPS URLs for seamless app or web content delivery.
- Gracefully falls back to the website if the app isn't installed or configured.
- Requires server-side domain verification files (
apple-app-site-association/assetlinks.json). - Requires client-side app configuration (Associated Domains on iOS / Intent Filters with
autoVerifyon Android). - Offers enhanced security, reliability, and improved user experience over custom URI schemes.
Code Example
<!-- In AndroidManifest.xml for an Activity that handles deep links -->
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https"
android:host="www.yourdomain.com"
android:pathPrefix="/products" />
<data android:scheme="https"
android:host="www.yourdomain.com"
android:pathPattern="/items/.*" />
</intent-filter>
</activity>How this code works
This XML code defines how an Android app, specifically the MainActivity, can open directly when a user clicks on specific web links. This feature, known as "App Links," allows the app to take over navigation from a web browser, offering a seamless user experience. The central intent-filter tag declares which types of links the activity is equipped to handle. A crucial detail for App Links is android:autoVerify="true", which tells Android to automatically verify the app's ownership of the specified website domains. If this verification succeeds, the app becomes the default handler for those links, completely bypassing any "open with" dialogs a user might otherwise encounter.
Within this intent-filter, action android:name="android.intent.action.VIEW" indicates the activity can display content associated with a link. The category android:name="android.intent.category.DEFAULT" and android.intent.category.BROWSABLE" tags ensure the app is discoverable and can be launched from a browser. The data tags specify the exact URL patterns. android:scheme="https" ensures only secure web links are matched, and android:host identifies the specific domain. android:pathPrefix="/products" matches any URL beginning with that path, while android:pathPattern="/items/.*" uses a regular expression for more flexible matching, covering all paths under /items/.