What are Deferred Deep Links?
Deferred deep links send users to a specific in-app destination even if the app isn’t installed yet. The user taps a smart link, installs the app, and on first launch lands on the intended screen with preserved context (campaign, referrer, product ID, etc.).
How deferred linking works
- User clicks an SDDL link (from ads, email, SMS, social, etc.).
- SDDL stores the intent and keeps context across install.
- If the app isn’t present, the user is sent to the App Store / Play Store.
- On first launch, the app asks SDDL to resolve the payload and routes the user to the right screen.
iOS setup (Universal Links)
Enable Associated Domains in Xcode and add:
applinks:{YOUR_ID}.sddl.me
OR
applinks:{your.custom.domain}
You do not host apple-app-site-association
yourself — SDDL publishes it automatically from your App settings.
SwiftUI integration (official SDDL iOS SDK)
import SwiftUI
import SDDLSDK
struct ContentView: View {
var body: some View {
Color.clear
// 1) Universal Link delivered directly
.onOpenURL { url in
SDDLHelper.resolve(url,
onSuccess: handlePayload(_:),
onError: handleError(_:))
}
// 2) Universal Link via NSUserActivity
.onContinueUserActivity(NSUserActivityTypeBrowsingWeb) { activity in
SDDLHelper.resolve(activity.webpageURL,
onSuccess: handlePayload(_:),
onError: handleError(_:))
}
// 3) Cold start (no URL at launch)
.onAppear {
SDDLHelper.resolve(nil,
onSuccess: handlePayload(_:),
onError: handleError(_:),
readClipboard: false)
}
}
}
private func handlePayload(_ payload: [String: Any]) {
// Navigate based on payload (e.g., product_id)
}
private func handleError(_ error: String) {
// Optional: log or show a non-blocking message
}
Add the CocoaPods dependency in your Podfile
:
platform :ios, '13.0'
use_frameworks!
target 'YourApp' do
pod 'SDDLSDK', '~> 2.0.7' # use the latest version
end
Android setup (App Links)
SDDL auto-publishes assetlinks.json
based on your App Links configuration (package name and SHA256 fingerprints) in the SDDL dashboard.
In your project, add the repository and dependency:
// settings.gradle.kts
pluginManagement {
repositories {
gradlePluginPortal()
google()
mavenCentral()
maven("https://jitpack.io")
}
}
// app/build.gradle.kts
dependencies {
implementation("com.github.nonanerz:sddl-android-sdk:2.0.9") // use the latest version
}
Declare App Links in your AndroidManifest.xml
:
<uses-permission android:name="android.permission.INTERNET" />
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop">
<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="{YOUR_ID}.sddl.me OR {your.custom.domain}"
android:pathPrefix="/" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Using the SDDL Android SDK
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
SDDLHelper.resolve(this, intent, ::routeWith, ::handleDeepLinkError, readClipboard = false)
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
SDDLHelper.resolve(this, intent, ::routeWith, ::handleDeepLinkError, readClipboard = false)
}
private fun routeWith(payload: JsonObject) {
// navigate based on payload (e.g., product_id)
}
private fun handleDeepLinkError(error: String) {
// optional: log/report
}
}
Getting SHA256 fingerprints
# Debug
keytool -list -v -alias androiddebugkey -keystore ~/.android/debug.keystore -storepass android -keypass android
# Release
keytool -list -v -alias YOUR_ALIAS -keystore /path/to/your-release-key.jks
Add both Debug and Release fingerprints in SDDL → App Links Configuration.
Testing & Troubleshooting
- Domains: use
{YOUR_ID}.sddl.me
or your verified custom domain connected in SDDL. - iOS: Associated Domains must be verified (no warnings in Xcode). After changing entitlements, delete and reinstall the app to refresh Universal Links.
- AASA: SDDL publishes it automatically; ensure it’s reachable and not served with redirects. (No manual hosting needed.)
- Android: set
android:autoVerify="true"
. Verify withadb shell pm verify-app-links your.package.name
and ensure fingerprints in SDDL match your build. - Cold start: call
SDDLHelper.resolve(nil)
(iOS) orSDDLHelper.resolve(this, intent)
(Android) on launch so deferred context is restored.
FAQ
Do I need to host AASA or assetlinks.json?
No. SDDL automatically publishes both based on your app settings.
Is the SDK required?
The SDKs are the easiest way to integrate and restore context, but a pure REST flow is possible if you prefer.
Related guides
Continue exploring-
Deep Links — The Complete Guide
Guide -
Universal Links (iOS) — Setup & Troubleshooting
Guide -
Firebase Dynamic Links Alternative
Guide -
Branch.io Alternative
Guide -
App Links (Android)
Guide -
Troubleshooting Playbook
Guide -
QA Playbook
Guide -
E-commerce Deep Links
Guide -
Deep Links for Ads
Guide -
QR Codes to App — Deferred Deep Links
Guide -
Email & SMS Deep Links
Guide -
Creator & Affiliate Deep Links
Guide -
Gaming Deep Links — Rewards, Quests
Guide -
Deferred Deep Links in React Native — Setup Guide
Guide