Expo Integration
This guide will help you configure your Expo app for ChottuLink Deep Links.
π Prerequisitesβ
Before integrating ChottuLink into your Expo app, ensure you have the following:
Development Environmentβ
- Node.js
18.0+installed - npm or yarn package manager
- Expo CLI installed globally or locally
- A working Expo project
- Physical devices or simulators/emulators to run your app
π§ Configure ChottuLink Dashboardβ
1. For iOS Click hereβ
2. For Android Click hereβ
π¦ Installationβ
1. Install the required packages:β
Install the ChottuLink SDK(react-native-chottulink-sdk) and expo-dev-client in your Expo React Native project.
The expo-dev-client is required to enable Continuous Native Generation (CNG) and run native code in your Expo app.
Run the following command from your project root:
npx expo install expo-dev-client && npm install react-native-chottulink-sdk --save
After installation, add expo-dev-client to the plugins array in your app.json (or app.config.js).
{
"expo": {
"plugins": ["expo-dev-client"]
}
}
Important: This step is mandatory to ensure native modules work correctly during development.
2. Platform Specific Configurationsβ
Update app.json for iOS & Android.
To enable deep linking with ChottuLink, you must update your Expo configuration for both iOS and Android.
1. iOS Configurationβ
Add the following configuration inside the ios section of your app.json:
{
"ios": {
"bundleIdentifier": "com.yourbrand.package",
"associatedDomains": [
"applinks:yourapp.chottu.link"
]
}
}
2. Android Configurationβ
Add the following configuration inside the android section of your app.json:
{
"android": {
"package": "com.yourbrand.package",
"intentFilters": [
{
"action": "VIEW",
"autoVerify": true,
"data": [
{
"scheme": "https",
"host": "yourapp.chottu.link"
}
],
"category": [
"BROWSABLE",
"DEFAULT"
]
}
]
}
}
Important Replacementsβ
Make sure you replace the following points:
com.yourbrand.packageβ Your actual iOS bundle identifier and Android package nameyourapp.chottu.linkβ The domain assigned to you in the ChottuLink Dashboard
π Initialize the SDKβ
Basic Initializationβ
Initialize the ChottuLink sdk your app entry file:
import { initializeChottuLink } from 'react-native-chottulink-sdk';
// Initialize with your Mobile SDK Integration Key
initializeChottuLink('your-api-key-here');
π Handling Deep Linkβ
π οΈ Handle Initial URL (App Opened from Killed State)β
When your app is completely closed (killed state) and opened via a deep link, you must manually capture the initial URL and pass it to the ChottuLink SDK for processing.
This ensures that deep links work correctly even when the app is launched from a cold start.
import * as Linking from 'expo-linking';
// Set up Event Listener for Initial URL when app is opened through URL in killed state
async function getInitialUrl() {
const url = await Linking.getInitialURL();
if (url) {
handleLink(url);
}
}
getInitialUrl().then();
Important: This logic should run early in your app lifecycle (e.g., during app initialization).
β‘ Handle for Foreground / Paused Deep Link Interceptionβ
- Without Expo Router
- With Expo Router
When your app is already running (foreground) and opened via a deep link, you must manually capture the deep lnk URL and pass it to the ChottuLink SDK for processing.
import * as Linking from 'expo-linking';
// Set up Event Listener for foreground URL when app is opened through URL in paused condition
useEffect(() => {
const subscription = Linking.addEventListener('url', ({ url }) => {
handleLink(url);
});
return () => subscription?.remove();
}, []);
When the app is already running (foreground), deep links are handled differently by the native system when using expo-router.
To properly intercept and process these links, you must create a native intent handler using Expo Routerβs +native-intent.tsx.
This file ensures ChottuLink URLs are correctly captured and resolved while the app is active or paused.
Create the following file at the root of your /app directory:
app/+native-intent.tsx
import { handleLink } from 'react-native-chottulink-sdk';
export function redirectSystemPath({path, initial,}: {path: string; initial: boolean;}) {
const url = new URL(path);
console.log('Host Name:', url.hostname);
console.log('Path Name:', url.pathname);
// Replace yourapp.chottu.link with your selected domain
if (url.hostname === 'yourapp.chottu.link') {
console.log(`Handling ChottuLink URL β ${url.pathname}`);
// Pass the full URL to ChottuLink SDK
handleLink(url.toString());
// Return default path and handle navigation
// via `ChottuLinkDeepLinkResolved` callback
return '/';
}
// Otherwise, return the original path or a fallback route
return path;
}
π± Handling Incoming Linksβ
import { NativeEventEmitter, NativeModules } from 'react-native';
const { ChottuLinkEventEmitter } = NativeModules;
const eventEmitter = new NativeEventEmitter(ChottuLinkEventEmitter);
// Called when a deep link or deferred link is successfully resolved
const deepLinkSubscription = eventEmitter.addListener('ChottuLinkDeepLinkResolved', data => {
// Tip: β‘οΈ Navigate to a specific page or take action based on the link
console.log('Deep link resolved:', data);
console.log('URL:', data.url);
console.log('Metadata:', data.metadata);
// Metadata structure (available since v1.0.5+):
// - isDeferred: boolean Indicates if the link is deferred
// - originalURL: string The resolved destination URL (may be null if not found)
// - resolvedAt: string Timestamp when the link was resolved
// - shortLinkRaw: string The deeplink url which was clicked with all the parameters intact
},
);
// Called when there's an error resolving the deep link
const deepLinkErrorSubscription = eventEmitter.addListener('ChottuLinkDeepLinkError', data => {
console.log('Deep link error:', data);
console.log('Original URL:', data.originalURL);
console.log('Error:', data.error);
},
);