How to Set Up Deep Links in Expo
Universal links for iOS and App Links for Android in Expo. The `app.json` config, the Apple AASA file, and how to test both before you ship.
Universal links for iOS and App Links for Android in Expo. The `app.json` config, the Apple AASA file, and how to test both before you ship.
Universal links for iOS and App Links for Android in Expo, with the AASA and assetlinks config I use across shipped apps.
Prerequisites
Open https://yourapp.com/share/abc123 on a phone with your app installed and it opens your app directly on the share screen. Open it without your app installed and it falls back to a web page you control.
expo-linking and Expo Router.https endpoint that can serve the apple-app-site-association file and the assetlinks.json file.app.jsonAdd an associatedDomains entry for iOS and intentFilters for Android:
{
"expo": {
"scheme": "aiappfactory",
"ios": {
"associatedDomains": ["applinks:yourapp.com"]
},
"android": {
"intentFilters": [
{
"action": "VIEW",
"data": [{ "scheme": "https", "host": "yourapp.com" }],
"category": ["BROWSABLE", "DEFAULT"],
"autoVerify": true
}
]
}
}
}
Apple looks for https://yourapp.com/.well-known/apple-app-site-association. No redirects. No trailing whitespace. application/json content type.
{
"applinks": {
"apps": [],
"details": [
{
"appID": "TEAMID.com.yourcompany.yourapp",
"paths": ["/share/*", "/invite/*"]
}
]
}
}
assetlinks.json for AndroidAt https://yourapp.com/.well-known/assetlinks.json:
[
{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.yourcompany.yourapp",
"sha256_cert_fingerprints": ["YOUR:SHA:256:FINGERPRINT"]
}
}
]
Get the fingerprint from eas credentials or your upload keystore.
With Expo Router, a file at app/share/[id].tsx handles the route. useLocalSearchParams() gives you the id. Old style: Linking.addEventListener(''url'').
https://branch.io/resources/aasa-validator/ to sanity-check the AASA file. Then test with xcrun simctl openurl booted https://yourapp.com/share/abc.adb shell am start -a android.intent.action.VIEW -d "https://yourapp.com/share/abc".The AASA file is cached by Apple. If you upload a new one, expect ~24 hours before iOS picks it up. Do not panic when it does not work immediately after the upload.
AI App Factory ships app.json with the deep link config, the AASA and assetlinks templates, and a /share/[id] Expo Router screen as a reference. You swap the domain and ship.
Everything in this guide is already pre-configured in AI App Factory. 11 AI agents automate the rest.