Deep Links
Deep links allow users to open your app directly from a URL, enabling features like email verification links, social sharing, and custom integrations.
Deep links use URL schemes (like myapp://) to open your app and optionally navigate to specific content within it.
Overview
When you configure deep link schemes in your build.yaml, a0 automatically:
Registers the URL schemes with iOS (Info.plist)
Adds intent filters to Android (AndroidManifest.xml)
Configures Expo to recognize the schemes at runtime
Your app’s bundle ID is automatically added as a scheme, so you always have at least one working deep link scheme without any configuration.
Configuration
Add the schemes property to your .a0/build.yaml file:
general :
runtimeVersion : "exposdk:54.0.0"
schemes :
- myapp
- myapp-dev
ios :
versionName : "1.0.0"
android :
versionName : "1.0.0"
Schemes must be lowercase and start with a letter. They can only contain letters, digits, plus signs (+), hyphens (-), and dots (.).
Handling Deep Links
Use the expo-linking library to handle incoming deep links in your app.
Basic Setup
import * as Linking from 'expo-linking' ;
import { useEffect } from 'react' ;
export default function App () {
useEffect (() => {
// Handle deep link when app is already open
const subscription = Linking . addEventListener ( 'url' , ({ url }) => {
handleDeepLink ( url );
});
// Handle deep link that opened the app
Linking . getInitialURL (). then (( url ) => {
if ( url ) {
handleDeepLink ( url );
}
});
return () => subscription . remove ();
}, []);
const handleDeepLink = ( url : string ) => {
const parsed = Linking . parse ( url );
console . log ( 'Deep link received:' , parsed );
// Navigate based on parsed.path and parsed.queryParams
};
return (
// Your app content
);
}
Creating Deep Link URLs
Generate URLs that open your app:
import * as Linking from 'expo-linking' ;
// Create a URL with your custom scheme
const url = Linking . createURL ( 'profile/123' , {
scheme: 'myapp' ,
queryParams: { ref: 'email' }
});
// Result: myapp://profile/123?ref=email
With React Navigation
If you’re using React Navigation, configure deep linking in your navigation container:
import { NavigationContainer } from '@react-navigation/native' ;
const linking = {
prefixes: [ 'myapp://' , 'myapp-dev://' ],
config: {
screens: {
Home: '' ,
Profile: 'profile/:id' ,
Settings: 'settings' ,
},
},
};
export default function App () {
return (
< NavigationContainer linking = { linking } >
{ /* Your navigators */ }
</ NavigationContainer >
);
}
Testing Deep Links
iOS Simulator
Android Emulator
Physical Device
Use the xcrun command to test deep links on iOS: xcrun simctl openurl booted "myapp://profile/123"
Use adb to test deep links on Android: adb shell am start -a android.intent.action.VIEW -d "myapp://profile/123"
The easiest way to test on a physical device:
Send yourself a message (email, Slack, etc.) containing the deep link URL
Tap the link to open your app
Common Use Cases
Send users a verification link that opens your app and marks their email as verified: // In your email: myapp://verify?token=abc123
const handleDeepLink = ( url : string ) => {
const { path , queryParams } = Linking . parse ( url );
if ( path === 'verify' && queryParams ?. token ) {
verifyEmail ( queryParams . token );
}
};
Allow users to reset their password from an email link: // In your email: myapp://reset-password?token=xyz789
const handleDeepLink = ( url : string ) => {
const { path , queryParams } = Linking . parse ( url );
if ( path === 'reset-password' && queryParams ?. token ) {
navigation . navigate ( 'ResetPassword' , { token: queryParams . token });
}
};
Let users share specific content that opens directly in your app: // Shared link: myapp://post/456
const handleDeepLink = ( url : string ) => {
const { path } = Linking . parse ( url );
const match = path ?. match ( / ^ post \/ ( \d + ) $ / );
if ( match ) {
navigation . navigate ( 'Post' , { id: match [ 1 ] });
}
};
Track referrals by including a code in the deep link: // Referral link: myapp://signup?ref=friend123
const handleDeepLink = ( url : string ) => {
const { queryParams } = Linking . parse ( url );
if ( queryParams ?. ref ) {
// Store referral code for attribution
storeReferralCode ( queryParams . ref );
}
};
Automatic Bundle ID Scheme
Your app’s bundle ID (e.g., dev.a0.apps.myapp) is automatically registered as a URL scheme. This ensures you always have a unique, collision-free scheme available even without explicit configuration.
While the bundle ID scheme works, custom schemes like myapp:// are shorter and more user-friendly for sharing.