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);
},
);