Complete Guide to Universal Links
Everything you need to know about universal links, deep links, and app links for iOS and Android
Skip the setup: one link that opens your app or the right store
- Free plan, no credit card
- App Store and Google Play fallback
- Opens your app on Pro
Table of Contents
What Are Universal Links?
Universal links are URLs that work seamlessly across web and mobile apps. When a user taps a universal link on their iOS device, iOS checks if an app is installed that can handle that link. If the app is installed, it opens directly to the specific content. If not, the link opens in Safari.
On Android, the equivalent technology is called App Links. The concept is the same: one URL that intelligently routes users to either your app or your website.
Someone taps an https link
https://yourdomain.com/products/…
Is an app installed that handles this domain?
Installed
The app opens on that exact content
Not installed
The same URL opens your website
In Safari or the browser
Key Benefits
- Seamless user experience - no prompts or redirects
- Single URL works across all platforms
- Better attribution and analytics
- Improved SEO - standard HTTPS URLs
- Works in email, SMS, social media, and anywhere else
How Universal Links Work
The process involves three key components:
Apple App Site Association (AASA) File
A JSON file hosted on your domain at /.well-known/apple-app-site-association that tells iOS which apps can handle your domain.
App Configuration
Your app must be configured to handle specific domains and URL patterns in its entitlements (iOS) or intent filters (Android).
URL Handling Code
Your app implements code to receive the deep link URL and navigate to the appropriate screen or content.
01 · Your domain
Association file
Tells the OS which apps can handle the domain
Both sides must agree
The OS matches the file against the app
02 · Your app
App configuration
Entitlements on iOS, intent filters on Android: the domains and paths it handles
03 · Your app
URL handling code
Receives the URL inside the app
The right screen
iOS Universal Links Implementation
Step 1: Create the AASA File
Create a file called apple-app-site-association (no file extension) with this structure: apple-app-site-association
{
"applinks": {
"apps": [],
"details": [
{
"appID": "TEAMID.com.yourcompany.yourapp",
"paths": [
"/products/*",
"/articles/*",
"/user/*"
]
}
]
}
}Important
The file must be served over HTTPS with a valid SSL certificate. It must also return Content-Type: application/json header.
Step 2: Configure Your iOS App
In Xcode, add the Associated Domains capability with your domain:
applinks:yourdomain.com
applinks:www.yourdomain.comStep 3: Handle the URL in Your App
// AppDelegate.swift
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL else {
return false
}
// Handle the URL and navigate to appropriate screen
handleUniversalLink(url)
return true
}Android App Links Implementation
Step 1: Create assetlinks.json
Host this file at https://yourdomain.com/.well-known/assetlinks.json:
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.yourcompany.yourapp",
"sha256_cert_fingerprints": [
"XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX"
]
}
}]Step 2: Update AndroidManifest.xml
<activity android:name=".MainActivity">
<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" />
<data android:host="yourdomain.com" />
<data android:pathPrefix="/products" />
</intent-filter>
</activity>Step 3: Handle the Intent
// MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val action = intent.action
val data = intent.data
if (Intent.ACTION_VIEW == action && data != null) {
// Handle the deep link
handleDeepLink(data)
}
}Best Practices & Common Pitfalls
Do's
- ✅ Always use HTTPS for your domain
- ✅ Test on real devices, not just simulators
- ✅ Set a website URL for people without the app (the fallback URL)
- ✅ Add comprehensive analytics tracking
- ✅ Handle all edge cases gracefully
- ✅ Keep your AASA/assetlinks files updated
❌Don'ts
- ❌ Don't use redirects for your AASA/assetlinks files
- ❌ Don't forget to validate JSON syntax
- ❌ Don't hardcode app navigation logic
- ❌ Don't assume the app will always be installed
- ❌ Don't skip testing on different OS versions
Testing & Debugging
iOS Testing
- 1. Use Apple's AASA Validator
- 2. Test links in Notes app, Messages, or Mail
- 3. Check logs in Xcode Console
- 4. Verify domain association in Settings → Developer
Android Testing
- 1. Use adb shell am start -a android.intent.action.VIEW -d "your-url"
- 2. Test in Chrome, Gmail, and messaging apps
- 3. Check verification status with adb shell dumpsys package domain-preferred-apps
- 4. Monitor logcat for errors
Analytics & Attribution
Proper analytics is crucial for understanding how your universal links perform. Track these key metrics:
- Click-through rates from different channels
- App open rate vs website visit rate
- User acquisition cost per channel
- Conversion rates for deep-linked content
- Time to first action after deep link
- Platform-specific performance (iOS vs Android)
Pro Tip
Use a smart link platform like Appy to automatically handle universal links, track analytics, and send people without the app to the store or your website. This saves you weeks of development time and provides enterprise-grade infrastructure.
Try Appy FreeConclusion
Universal links are essential for modern mobile apps. They provide a seamless user experience, improve attribution, and work reliably across platforms. While implementation requires careful attention to detail, the benefits in user experience and analytics make it worthwhile.
Start with the basics, test thoroughly, and iterate based on real-world performance data. And if you want to skip the complexity, consider using a platform like Appy that handles all of this for you automatically.
Related Appy resources
Explore Appy's tools for universal links, deep links, and QR codes to accelerate mobile app growth.
- Universal Link Validator to test iOS Universal Links and Android App Links.
- Branded QR Code Generator for app install campaigns and offline funnels.
- Smart link features like deep links, routing rules, and analytics.
Continue exploring
How In-App Browsers Handle Deep Links: Instagram, TikTok, Facebook, Gmail, Telegram and More
Why a link that opens your app from Safari dies inside Instagram: the three kinds of in-app browser, the iOS and Android rules, and what each app documents, from Facebook to Telegram.
Know Which Link Brought Every Install: Appy’s iOS and Android SDK
Appy now follows your links past the app store: installs, in-app events and revenue for every link, QR code and campaign, and new users who open on the right screen.
Deferred Deep Linking Without an SDK: How It Actually Works Under the Hood
You can carry link intent across an app install without embedding an attribution SDK. What actually survives the store boundary on Android and iOS, what breaks, and what each workaround costs in privacy.
Looking for something else? Browse all topics on the blog.
Skip the complexity. Use Appy.
Appy handles universal links, deep linking, QR codes, and analytics automatically. No coding required.