Deeplink setup (email → app)
Make billing-recovery and win-back email buttons open your app on the right flow. Apple Universal Links, Google Play App Links, the dashboard field, and the SDK handler.
What you need
RedChurn appends flow, source=email, and campaign to your base URL when it renders email CTAs. Your job is to (1) declare a URL your OS can route into the app, (2) paste that base URL in Dashboard → Scenarios → Email → Branding, and (3) mount the SDK deeplink handler so the app routes to the right flow.
Prefer an HTTPS universal link such as https://app.example.com/r: it opens the app when installed and falls back to a web page otherwise. A custom scheme such as myapp://redchurn also works but is less reliable from email clients.
- Dashboard deeplink base URL, e.g. https://app.example.com/r or myapp://redchurn
- iOS Associated Domains + apple-app-site-association file on your domain
- Android intent filters + assetlinks.json on your domain (for HTTPS links)
- SDK handler: useRedChurnDeeplinkHandler (RN/Expo) or Redchurn.shared.handleDeeplink (Swift)
1. Dashboard: deeplink base URL
Open Dashboard → Scenarios → Email and expand Branding. Set Deeplink base URL (optional) to the prefix RedChurn should use for email CTAs, without query params.
RedChurn will turn a billing-recovery button into something like https://app.example.com/r?flow=billing_recovery&source=email&campaign=<id>. If the field is empty, emails keep using your default web CTA URL (App Store, billing portal, etc.).
2. iOS (Apple): Universal Links
Universal Links let https://yourdomain.com/... open your app directly from Mail and Safari when it is installed.
- Pick a path prefix you control, e.g. https://app.example.com/r. This becomes your dashboard deeplink base URL.
- In Apple Developer → Identifiers → your App ID → enable Associated Domains.
- In Xcode → Signing & Capabilities → Associated Domains, add applinks:app.example.com (no https://).
- Host apple-app-site-association (no file extension) at https://app.example.com/.well-known/apple-app-site-association served as application/json with your app's team ID and bundle ID.
- Include the /r/* path (or your chosen prefix) in the AASA paths array so only RedChurn links are claimed.
- Rebuild and install on a physical device. Universal Links do not work reliably in the Simulator.
- Swift: forward URLs to the SDK with .onOpenURL { url in Task { await Redchurn.shared.handleDeeplink(url) } }.
3. Android (Google Play): App Links
App Links verify that https://yourdomain.com belongs to your app so Android opens it without a disambiguation dialog.
- Use the same HTTPS base as iOS, e.g. https://app.example.com/r.
- In AndroidManifest.xml, add an intent-filter with android:autoVerify="true" on your main activity for https, host app.example.com, and pathPrefix /r.
- Host assetlinks.json at https://app.example.com/.well-known/assetlinks.json listing your package name and SHA-256 signing cert fingerprint (Play App Signing cert for production builds).
- Run adb shell pm verify-app-links --re-verify your.package.name after installing a release/signed build.
- React Native / Expo: declare the same host and path in app.json (see below) so EAS/prebuild generates the manifest entries.
- Mount useRedChurnDeeplinkHandler (or useRedChurnOpenHandler) near your root. It listens to Linking and handles cold-start URLs.
4. Expo (app.json)
Expo prebuild generates native Universal Link / App Link config from app.json.
- Rebuild with eas build or npx expo prebuild. Expo Go cannot test custom native links.
- Set dashboard deeplink base URL to https://app.example.com/r (HTTPS) or myapp://redchurn (custom scheme).
{
"expo": {
"scheme": "myapp",
"ios": {
"bundleIdentifier": "com.example.app",
"associatedDomains": ["applinks:app.example.com"]
},
"android": {
"package": "com.example.app",
"intentFilters": [
{
"action": "VIEW",
"autoVerify": true,
"data": [
{ "scheme": "https", "host": "app.example.com", "pathPrefix": "/r" }
],
"category": ["BROWSABLE", "DEFAULT"]
}
]
}
}
}5. React Native (bare)
Bare React Native uses the same native steps as above. Configure Associated Domains in Xcode and intent filters in AndroidManifest.xml manually, or use a config plugin.
- iOS: Info.plist URL types for custom schemes if you use myapp://; plus Associated Domains for HTTPS.
- Android: intent-filter with autoVerify for your HTTPS host/path.
- npm: no extra RedChurn package. Use useRedChurnDeeplinkHandler from @redchurn/react-native-sdk.
6. SDK handler & attribution
Once the OS delivers the URL to your app, the SDK parses flow / source / campaign and fires a LINK_OPENED event for dashboard attribution.
- billing_recovery and win_back are the flows set automatically on email CTAs.
- If nothing happens when you tap the email button, the native link is not reaching the app. Fix AASA / assetlinks first, then the SDK handler.
import { useRedChurnOpenHandler } from "@redchurn/react-native-sdk";
useRedChurnOpenHandler({
onBillingRecovery: () => billing.check(),
onWinBack: () => winBack.check(),
});