三类深链接
| 类型 | 示例 | 特点 |
|---|---|---|
| Scheme URL | myapp://products/42 | 私有协议,浏览器不能直接解析,需要中转页 |
| Universal Link (iOS) | https://myapp.com/products/42 | 标准 https,装了 App 直达,未装 App 走 Web |
| App Link (Android) | https://myapp.com/products/42 | 同上,安卓实现 |
步骤一:app.json 配 scheme + 关联域名
{
"expo": {
"scheme": "myapp",
"ios": {
"bundleIdentifier": "com.gufa.myapp",
"associatedDomains": ["applinks:myapp.com"]
},
"android": {
"package": "com.gufa.myapp",
"intentFilters": [
{
"action": "VIEW",
"autoVerify": true,
"data": [{ "scheme": "https", "host": "myapp.com" }],
"category": ["BROWSABLE", "DEFAULT"]
}
]
}
}
}
步骤二:上传验证文件
iOS 要在 https://myapp.com/.well-known/apple-app-site-association Android 要在 https://myapp.com/.well-known/assetlinks.json
// apple-app-site-association(注意:无扩展名,content-type: application/json) { "applinks": { "details": [{ "appID": "TEAMID.com.gufa.myapp", "paths": ["*"] }] } }
// assetlinks.json [{ "relation": ["delegate_permission/common.handle_all_urls"], "target": { "namespace": "android_app", "package_name": "com.gufa.myapp", "sha256_cert_fingerprints": ["AA:BB:CC:..."] } }]
sha256 指纹从哪拿
EAS 签名的包:
EAS 签名的包:
eas credentials 能看到。开发版 keystore:keytool -list -v -keystore ~/.android/debug.keystore。苹果 TeamID 在 developer.apple.com 账户里。
步骤三:在 App 里 URL 自动映射
Expo Router 默认把收到的链接根据文件结构匹配——不用写任何 linking 配置:
收到 https://myapp.com/products/42 → Expo Router 内部路径 /products/42 → 打开 app/products/[id].tsx,id = '42'
收到 myapp://products/42 → 同样映射到 /products/42
测试链接
# iOS 模拟器 xcrun simctl openurl booted "https://myapp.com/products/42" xcrun simctl openurl booted "myapp://products/42" # Android 模拟器 adb shell am start -W -a android.intent.action.VIEW \ -d "https://myapp.com/products/42" com.gufa.myapp # 真机只要装了 App,微信/浏览器点链接即可
动态处理链接
import * as Linking from 'expo-linking'; import { useEffect } from 'react'; useEffect(() => { // 冷启动时 Linking.getInitialURL().then((url) => { if (url) console.log('冷启动链接', url); }); // 运行中再收到 const sub = Linking.addEventListener('url', ({ url }) => { console.log('运行时链接', url); }); return () => sub.remove(); }, []);
一般情况不用自己监听——Expo Router 会自动把 URL 转成路由切换,你在屏幕里用 useLocalSearchParams 拿参数就行。
拆解 URL
import * as Linking from 'expo-linking'; const url = 'https://myapp.com/products/42?ref=social'; const parsed = Linking.parse(url); // { // scheme: 'https', // hostname: 'myapp.com', // path: 'products/42', // queryParams: { ref: 'social' } // }
prefixes:多个域名共存
{
"ios": {
"associatedDomains": [
"applinks:myapp.com",
"applinks:share.myapp.com",
"applinks:m.myapp.com"
]
}
}
同时上传三份 apple-app-site-association 到各域名——一个 App 可关联多个域名,营销活动、短链都能直达。
短链服务
Firebase Dynamic Links 2025 年下线后,Expo 社区偏向自建或用 Branch/AppsFlyer:
自建短链
Web 服务 + SQLite/KV:
https://s.myapp.com/x8k2 → 302 到 https://myapp.com/products/42。这个 302 目标自己是 Universal Link,直接拉起 App。Branch.io
老牌归因平台,支持延迟深链(装完 App 第一次打开仍能跳对)。有免费额度。
未装 App 的降级
Universal Link 最大的好处:未装时浏览器正常打开 Web 同一 URL。这意味着 Web 端也得是 Expo Router 站点,或至少有同样的 /products/:id 页面——第 8 章讲三端一体。
常见坑
iOS 安装后不生效
检查 apple-app-site-association 是否 https、content-type 是否 application/json(不是 text/html)、文件名没有 .json 扩展。可用 https://app-site-association.cdn-apple.com/a/v1/myapp.com 查验 Apple 是否抓到。
Android autoVerify 失败
sha256 指纹要和实际签名一致。release/dev 的指纹不同,建议 assetlinks.json 里列多个。
微信内打不开 App
微信会劫持 https 链接在 webview 里打开,用户需要右上角"用浏览器打开"。中国 Apps 常做 URL Scheme 降级 + 提示引导。
本章小结
- Universal Link/App Link = 用 https 链接直接拉起对应 App,未装时走 Web,兼得 SEO 和 App 转化
- 配置两头:
app.json声明域名 + 服务器放apple-app-site-association/assetlinks.json - Expo Router 无需额外 linking,URL 按文件路径自动映射
xcrun simctl openurl、adb shell am start本地测试链接- 国内场景做好微信 webview 引导,或用 URL Scheme 兜底