<action android:name="android.intent.action.VIEW" />Deep Linking
This guide covers deep linking into a chat app, extracting a channel ID from the URL, and opening the corresponding conversation.
Best Practices
- Define a single URL pattern and document it for both web and app.
- Validate channel IDs before navigating to avoid empty screens.
- Handle both cold start (
getInitialURL) and foreground events. - Use App Links/Universal Links in production for verified routing.
- Keep deep link parsing isolated so it’s easy to test.
Step 1 - Native Setup
Prerequisite: an app with the Stream Chat React Native SDK integrated.
For Android deep linking, follow this guide.
Creating Intent Filters
Add an intent filter to your AndroidManifest.xml at /android/app/src/main/AndroidManifest.xml.
action- Specify ACTION_VIEW so the intent filter can be reached from Google Search.
data- Add one or more<data>tags. Each represents a URI format and must includeandroid:scheme.
<data android:scheme="http" />
<data android:scheme="https" />
<!-- The URL here must exclude the scheme -->
<data android:host="`YOUR URL HERE`" />category- IncludeDEFAULTandBROWSABLEso links from a browser resolve to your app.
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />Combined:
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<!-- Example: "stream-calls-dogfood.vercel.app” -->
<data android:host="`YOUR URL HERE`" />
</intent-filter>Adding Asset Links
Android App Links open your app directly from website URLs. They use the Digital Asset Links API to verify domain ownership and automatically route matching URLs to your app.
To verify that you own both your app and the website URLs, complete the following steps:
Add intent filters with the
autoVerifyattribute (as above).Declare the association by hosting a Digital Asset Links JSON file at:
https://domain.name/.well-known/assetlinks.jsonUse this tool to generate assetlink.json. Enter the hosting site name, app package name, and package fingerprint (SHA256).
- Hosting site name is the URL of the website which we will use for deep linking in our app.
- App package name can be easily found in the first line of your
MainActivity.javafile as a value topackage. - To get your app package fingerprint (SHA256), follow this guide.
Adding deep linking support in AppDelegate
To add deep linking support on iOS:
- Link
RCTLinkingto handle incoming links. InAppDelegate.morAppDelegate.mm, add:
#import <React/RCTLinkingManager.h>
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [RCTLinkingManager application:application openURL:url options:options];
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
return [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}Setting up a URL scheme
To add a URI scheme, open YOUR_APP_NAME/ios/app-name.xcworkspace in Xcode. Select the project, go to Info > URL types, click +, then add:
- Your app's bundle id.
- A scheme name that acts as the URL prefix.
- Leave the role as
Editor.

Setting up Universal schemes
If you use Universal Links, add the following code as well.
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
return [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}Adding Associated Domains Entitlement
In Xcode, add the Associated Domains entitlement under Signing & Capabilities.

Click the + under Signing & Capabilities, search for Associated Domains, and add it.
In the new field, click + and insert applinks: followed by your domain.
The applinks: prefix tells Xcode this domain is used for Universal Links.
Once you complete this step, a .entitlements file is created in ios/YOUR_APP_NAME.
Now add the AASA (Apple App Site Association) file to your web project:
Create
apple-app-site-associationin the.well-knowndirectory so it’s served athttps://domain.name/.well-known/apple-app-site-association.Now, Paste the following snippet:
{
"applinks": {
"apps": [],
"details": [
{
"appID": ["<TeamID>.com.example.myapp"],
"paths": ["*"]
}
]
}
}Notes:
appIDexpects your Team ID (from the Membership page) plus your Bundle ID.- The
pathsarray lists supported URLs; use*for wildcards. - Leave
appsempty.
That’s all you need for iOS setup.
Step 2 - Using the Linking API
After Android and iOS setup, use the React Native Linking API to handle links and navigate.
If the app isn’t open, it launches and the URL is provided as the initial URL.
Use getInitialURL() to read the initial URL (it returns a Promise).
Parse the URL and act accordingly.
If the app is already open, a url event fires. Use addEventListener('url', callback) to receive callback({ url }).
Example:
const App = () => {
useEffect(() => {
const parseAndSetChannelID = (url: string | null) => {
const matchResponse = url?.match(`YOUR REGEX HERE`); // To match the paths and handle them accordingly
if (matchResponse?.length) {
// Your custom setup here.
}
};
const { remove } = Linking.addEventListener("url", ({ url }) => {
parseAndSetChannelID(url);
});
const configure = async () => {
const url = await Linking.getInitialURL();
parseAndSetChannelID(url);
};
configure();
return remove;
}, []);
};Extract the channel ID from the URL, open the conversation, and navigate to the appropriate screen.