自定义链接

编辑页面

了解在使用 Expo Router 时如何通过 +native-intent 进行链接重定向并使用第三方深度链接。


For the complete documentation index, see llms.txt. Use this Use this file to discover all available pages.

Expo Router 使用一种扩展版的 Web 标准来在应用内进行导航。然而,原生应用并不总是符合基于服务器的路由。这在集成任何第三方服务时都可能导致不一致。例如,应用可以通过任意字符串或 intent 对象启动,而不是 URL。你可能需要自定义链接的常见场景有两种:

  • 应用已关闭:当应用未打开时,传入的深度链接 URL 可能需要重写,以确保无缝导航。

  • 应用已打开:当应用已经打开时,可能需要根据特定业务逻辑或用户交互来自定义 URL。这种逻辑可以是整个应用范围的全局逻辑,也可以局限于一组路由。

设置链接

有关如何在应用中设置和测试链接的说明,请参阅将链接引入你的应用指南。

重写传入的原生深度链接

Expo Router 始终会在“该 URL 指向应用内某个特定页面”的假设下解析 URL。然而,在实践中,这些 URL 的性质可能各不相同:

  • 来自第三方提供商的唯一/推荐 URL:这类 URL 通常遵循特定的 schema,例如 <my-scheme>://<provider-hostname>/<uuid>,由外部来源生成,用于将用户导航到应用内指定内容。
  • 来自旧版本的过期 URL:应用用户可能会遇到来自旧版本应用的 URL,这些 URL 可能指向过时或不存在的内容。妥善处理此类情况对于确保顺畅的用户体验至关重要。

在这类场景中,需要对 URL 进行重写,以便正确地指向某个路由。

为此,请在项目的 src/app 目录顶层创建一个名为 +native-intent.tsx 的特殊文件。此文件导出一个特殊的 redirectSystemPath 方法,用于处理 URL/path。调用时,它会接收一个包含两个属性的 options 对象:pathinitial

src
app
  +native-intent.tsx

下面是一个示例,展示了如何在 +native-intent.tsx 文件中使用 redirectSystemPath。参考此示例,你可以确保应用的 URL 处理功能稳定可靠,并降低意外错误和崩溃的风险。

src/app/+native-intent.tsx
import ThirdPartyService from 'third-party-sdk'; export function redirectSystemPath({ path, initial }) { try { if (initial) { // 虽然参数名为 `path`,但不能保证它一定是路径或有效的 URL const url = new URL(path, 'myapp://app.home'); // 对第三方 URL 的检测会因提供商而异 if (url.hostname === '<third-party-provider-hostname>') { return ThirdPartyService.processReferringUrl(url).catch(() => { // 出了点问题 return '/unexpected-error'; }); } return path; } return path; } catch { // 不要让这个函数崩溃!相反,你应该将用户重定向 // 到一个用于处理意外错误的自定义路由,让他们能够报告事件 return '/unexpected-error'; } }

重写传入的 Web 深度链接

在 Web 上处理深度链接与原生平台不同,因为初始路由流程的执行方式不同。Expo Router 无法为 Web 提供与 +native-intent 直接对应的方案,因为 Web 路由是在网站的 JavaScript 执行之前解析的,并且会因部署产物和你选择的提供商而有所不同。

因此,你应该根据自身需求实现以下模式之一:

  • 服务器重定向:由于所有网站(包括静态页面)都托管在服务器上,因此可以考虑利用部署提供商提供的服务端重定向或中间件选项。这种方式非常适合面向 serverstatic 输出的部署。
  • 客户端重定向:或者,你也可以在应用根目录的 _layout 中管理 URL 重定向。这种方式非常适合目标为客户端渲染、且只有单一输出格式的项目。

请选择与你的部署策略和技术需求相匹配的模式,以确保在 Web 平台上无缝处理传入的深度链接。

重写 URL

当你的应用处于打开状态时,你可以在 _layout 文件中使用 usePathname() hook 来响应 URL 变化。_layout 的位置决定了订阅的作用域。

  • 全局:将逻辑添加到根 _layout 文件中
  • 局部:在现有目录中添加 _layout 文件(或创建一个新的组目录
src/app/_layout.tsx
import { Slot, Redirect } from 'expo-router'; export default function RootLayout() { const pathname = usePathname(); if (pathname && !isUserAllowed(pathname)) { return <Redirect href="/home" />; } return <Slot />; }

使用 redirectSystemPath

在原生应用中,重写 URL 的另一种方法是在 redirectSystemPath 方法中处理它。对于某些用例,这种方式可能更简单,但也有一些缺点:

  • 仅适用于原生:此方法无法在 Web 上使用,因为 +native-intent 仅在原生应用中可用。
  • 缺乏上下文+native-intent 在应用上下文之外处理。这意味着你无法访问额外的逻辑,例如用户认证状态或当前路由状态。

将导航事件发送给第三方服务

下面是一个将导航事件发送到外部服务(例如分析或日志服务)的基本示例。请向你的提供商咨询具体说明。

src/app/_layout.tsx
import ThirdPartyService from 'third-party-sdk'; import { Slot, usePathname } from 'expo-router'; const thirdParty = new ThirdPartyService(); export default function RootLayout() { const pathname = usePathname(); // 执行服务初始化逻辑 useEffect(() => { thirdParty.register(); return () => { thirdParty.deregister(); }; }, [thirdParty]); // 将 pathname 变化发送给第三方 useEffect(() => { thirdParty.sendEvent({ pathname }); }, [pathname]); return <Slot />; }

Expo Router 不需要为 Universal Links 和多个域名进行额外配置。传递给你的 App 的所有 URL 都会被解析。若要自定义应用的 URL scheme,请在应用配置中自定义 scheme

强制使用 Web 链接

如果你希望 URL 首先由用户的浏览器进行解析,请将地址写为带有 http/https scheme 的完全限定 URL(FQDN)。使用完整 URL 可确保该链接被解释为 Web URL,并默认在用户的浏览器中打开。

这种方式适用于将用户引导到外部网站,或为其他应用提供 Universal Links。

<Link href="https://my-website.com/router/introduction" />

legacy_subscribe

重要 legacy_subscribe 处于alpha 阶段,并在 SDK 52 中可用。

如果你正在使用一个不支持 Expo Router、但支持通过 Linking.subscribe 函数为现有项目提供 React Navigation 的第三方提供商,那么你可以使用 legacy_subscribe 作为替代 API。

不建议在新项目或集成中使用此 API。它与服务器端路由和静态渲染不兼容,并且在离线或低网络连接环境下会较难管理。