Choose your SDK version below:
- Apptrove SDK → Recommended for all projects (Latest: v2.x.x)
- Trackier SDK → Will be deprecated in August 2026 (Latest legacy: v1.x.xx)
Use the tabs below for SDK-specific snippets.
Deep Linking with Cordova SDK
Deep linking enables seamless navigation to specific in-app content, enhancing user engagement by directing users to targeted screens within your Cordova application. The Apptrove Cordova SDK supports both immediate deep linking (for users with the app installed) and deferred deep linking (for users who install the app via a deep link).
What is Deep Linking?
Deep linking allows users to navigate directly to specific content within your app using URLs. The Cordova SDK handles two scenarios:
- Immediate Deep Linking: When the app is already installed, the deep link opens the app and navigates to the specified screen.
- Deferred Deep Linking: When the app is not installed, the deep link directs users to the app store. After installation, the SDK navigates to the specified screen upon first app launch.

Prerequisites
Before implementing deep linking, ensure you have:
- Apptrove Cordova SDK installed and initialized in your project
- Apptrove account with access to the Apptrove Panel
- Cordova 9.0 or later
- For Android: Android API 21 (Android 5.0) or later
- For iOS: iOS 10.0 or later, Xcode 12.0 or later
- Basic knowledge of JavaScript, Cordova, and platform-specific configurations
Quick Start
Step 1: Platform Configuration
Android Setup
- Update AndroidManifest.xml
Open
platforms/android/app/src/main/AndroidManifest.xmland add the intent filter:
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="yourdomain.u9ilnk.me"
android:pathPrefix="/d/" />
</intent-filter>
</activity>
- Test Deep Link
cordova build android
# Install APK and test with your UniLink URL (example): https://yourdomain.u9ilnk.me/d/PGJ2m4NtPd
iOS Setup
-
Get App Identifiers
- Log into Apple Developer Account
- Navigate to Certificates, IDs & Profiles > Identifiers > App IDs
- Copy your Prefix ID and App Bundle ID
-
Configure Apptrove
- Log into your Apptrove Panel
- Select your application → Action → UniLink
- Create a template and add your Prefix ID and App Bundle ID

-
Configure Xcode
- Open
platforms/ios/[YourAppName].xcworkspacein Xcode - Select your project → Capabilities tab
- Enable Associated Domains
- Add:
applinks:subdomain.unilink.me
- Open
-
Test Universal Links
cordova build ios
# Install on device and test with Universal Link
Step 2: SDK Implementation
JavaScript Implementation
- ✓ Apptrove SDK (Recommended)
- Trackier SDK (Deprecating August 2026)
document.addEventListener('deviceready', function() {
initializeDeepLinking();
});
async function initializeDeepLinking() {
try {
// 1. Initialize Config
var key = "your-sdk-key-here";
var appTroveConfig = new AppTroveConfig(key, AppTroveEnvironment.Development);
// 2. Set up deferred deep link listener BEFORE SDK initialization
var observable = AppTroveCordovaPlugin.setDeferredDeeplinkCallbackListener();
observable.subscribe(function(deepLinkUrl) {
console.log('User installed via deeplink:', deepLinkUrl);
handleDeepLink(deepLinkUrl);
});
// 3. Initialize SDK
await AppTroveCordovaPlugin.initializeSDK(appTroveConfig);
console.log("SDK initialized successfully");
// 4. Parse immediate deep links AFTER SDK initialization
if (window.location.href) {
await AppTroveCordovaPlugin.parseDeepLink(window.location.href);
console.log("Immediate deep link parsed successfully");
}
} catch (error) {
console.error("Deep linking initialization error:", error);
}
}
// Handle deep link navigation
function handleDeepLink(deepLinkUrl) {
console.log("Processing deep link:", deepLinkUrl);
// Parse the deep link URL to extract parameters
try {
const url = new URL(deepLinkUrl);
const deepLinkValue = url.searchParams.get('dlv');
// Navigate based on deep link value
switch(deepLinkValue) {
case "FirstProduct":
window.location.href = "#/product";
break;
case "standard":
window.location.href = "#/standard";
break;
default:
console.log("Default navigation");
break;
}
console.log("Deep link navigation completed");
} catch (error) {
console.error("Error parsing deep link:", error);
}
}
document.addEventListener('deviceready', function() {
initializeDeepLinking();
});
async function initializeDeepLinking() {
try {
// 1. Initialize Config
var key = "your-sdk-key-here";
var trackierConfig = new TrackierConfig(key, TrackierEnvironment.Development);
// 2. Set up deferred deep link listener (v1.6.81+ Object Support)
var observable = TrackierCordovaPlugin.setDeferredDeeplinkCallbackListener();
observable.subscribe(function(deepLink) {
console.log('Deferred deep link received');
console.log('URL:', deepLink.url);
console.log('Is Deferred:', deepLink.isDeferred);
console.log('Deep Link Value:', deepLink.deepLinkValue);
console.log('Partner ID:', deepLink.partnerId);
console.log('Campaign:', deepLink.campaign);
console.log('Campaign ID:', deepLink.campaignId);
console.log('Ad:', deepLink.ad);
console.log('Ad Set:', deepLink.adSet);
console.log('Channel:', deepLink.channel);
console.log('P1-P5:', deepLink.p1, deepLink.p2, deepLink.p3, deepLink.p4, deepLink.p5);
if (deepLink.sdkParams) {
console.log('SDK Params:', JSON.stringify(deepLink.sdkParams));
}
handleDeepLink(deepLink);
});
// 3. Initialize SDK
await TrackierCordovaPlugin.initializeSDK(trackierConfig);
console.log("SDK initialized successfully");
// 4. Parse immediate deep links AFTER SDK initialization
if (window.location.href) {
await TrackierCordovaPlugin.parseDeepLink(window.location.href);
console.log("Immediate deep link parsed successfully");
}
} catch (error) {
console.error("Deep linking initialization error:", error);
}
}
// Handle deep link navigation
function handleDeepLink(deepLink) {
console.log("Processing deep link:", deepLink.url);
if (deepLink.deepLinkValue) {
// Navigate based on deepLinkValue
}
}
Ionic/Angular Implementation
- ✓ Apptrove SDK (Recommended)
- Trackier SDK (Deprecating August 2026)
import { Component, OnInit } from '@angular/core';
import { AppTroveCordovaPlugin, AppTroveConfig, AppTroveEnvironment } from 'com.apptrove.cordova_sdk/ionic-native/apptrove/ngx';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html'
})
export class AppComponent implements OnInit {
constructor(private apptroveCordovaPlugin: AppTroveCordovaPlugin) {}
ngOnInit() {
this.initializeDeepLinking();
}
private async initializeDeepLinking() {
try {
// 1. Config SDK
const key = "your-sdk-key-here";
const appTroveConfig = new AppTroveConfig(key, AppTroveEnvironment.Development);
// 2. Set up deferred deep link listener BEFORE SDK initialization
const observable = this.apptroveCordovaPlugin.setDeferredDeeplinkCallbackListener();
observable.subscribe((deepLinkUrl: string) => {
console.log('User installed via deeplink:', deepLinkUrl);
this.handleDeepLink(deepLinkUrl);
});
// 3. Initialize SDK
await this.apptroveCordovaPlugin.initializeSDK(appTroveConfig);
console.log("SDK initialized successfully");
// 4. Parse immediate deep links AFTER SDK initialization
if (window.location.href) {
await this.apptroveCordovaPlugin.parseDeepLink(window.location.href);
console.log("Immediate deep link parsed successfully");
}
} catch (error) {
console.error("Deep linking initialization error:", error);
}
}
private handleDeepLink(deepLinkUrl: string) {
console.log("Processing deep link:", deepLinkUrl);
// Parse the deep link URL to extract parameters
try {
const url = new URL(deepLinkUrl);
const deepLinkValue = url.searchParams.get('dlv');
// Navigate based on deep link value
switch(deepLinkValue) {
case "FirstProduct":
this.router.navigate(['/product']);
break;
case "standard":
this.router.navigate(['/standard']);
break;
default:
console.log("Default navigation");
break;
}
console.log("Deep link navigation completed");
} catch (error) {
console.error("Error parsing deep link:", error);
}
}
}
import { Component, OnInit } from '@angular/core';
import { TrackierCordovaPlugin, TrackierConfig, TrackierEnvironment } from '@awesome-cordova-plugins/trackier/ngx';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html'
})
export class AppComponent implements OnInit {
constructor(private trackierCordovaPlugin: TrackierCordovaPlugin) {}
ngOnInit() {
this.initializeDeepLinking();
}
private async initializeDeepLinking() {
try {
// 1. Config SDK
const key = "your-sdk-key-here";
const trackierConfig = new TrackierConfig(key, TrackierEnvironment.Development);
// 2. Set up deferred deep link listener (v1.6.81+ Object Support)
const observable = this.trackierCordovaPlugin.setDeferredDeeplinkCallbackListener();
observable.subscribe((deepLink: TrackierDeepLink) => {
console.log('Deferred Deep Link Received');
console.log('URL:', deepLink.url);
console.log('Is Deferred:', deepLink.isDeferred);
console.log('Value:', deepLink.deepLinkValue);
console.log('Partner:', deepLink.partnerId);
console.log('Campaign:', deepLink.campaign);
console.log('Campaign ID:', deepLink.campaignId);
console.log('Ad:', deepLink.ad);
console.log('AdSet:', deepLink.adSet);
console.log('Channel:', deepLink.channel);
console.log('P1-P5:', deepLink.p1, deepLink.p2, deepLink.p3, deepLink.p4, deepLink.p5);
if (deepLink.sdkParams) {
console.log('SDK Params:', JSON.stringify(deepLink.sdkParams));
}
this.handleDeepLink(deepLink);
});
// 3. Initialize SDK
await this.trackierCordovaPlugin.initializeSDK(trackierConfig);
console.log("SDK initialized successfully");
// 4. Parse immediate deep links AFTER SDK initialization
if (window.location.href) {
await this.trackierCordovaPlugin.parseDeepLink(window.location.href);
console.log("Immediate deep link parsed successfully");
}
} catch (error) {
console.error("Deep linking initialization error:", error);
}
}
private handleDeepLink(deepLink: TrackierDeepLink) {
console.log("Processing deep link:", deepLink.url);
if (deepLink.deepLinkValue) {
// Navigate based on deepLinkValue
}
}
}
Expected Outcomes
When a user clicks a deep link:
| Scenario | Behavior |
|---|---|
| App Installed | App opens immediately and navigates to specified content |
| App Not Installed | Redirects to app store → After installation, app opens with deferred deep link |
The SDK handles both scenarios through the configured callbacks. Note that deferred deep linking support may vary between platforms and SDK versions.
Implementation Pattern
The Cordova SDK supports both immediate and deferred deep linking:
- Initialize Config object
- Set up deferred deep link listener using
setDeferredDeeplinkCallbackListener()BEFORE initializing the SDK - Initialize SDK with your configuration
- Parse immediate deep links using
parseDeepLink()AFTER SDK initialization - Handle navigation based on deep link parameters
Starting from v1.6.81, the Trackier SDK callback returns a structured TrackierDeepLink object instead of a plain URL string.
Deep Link Resolver
The Apptrove Cordova SDK provides a resolveDeeplinkUrl method to resolve deferred deep links and get instant access to the deep link URL.
JavaScript Implementation
- ✓ Apptrove SDK (Recommended)
- Trackier SDK (Deprecating August 2026)
function resolveDeepLinkExample() {
const deepLinkUrl = "https://trackier58.u9ilnk.me/d/NKmWH9E7b1";
AppTroveCordovaPlugin.resolveDeeplinkUrl(deepLinkUrl)
.then(function(result) {
console.log("Resolved URL:", result.url);
console.log("SDK Parameters:", result.sdkParams);
})
.catch(function(error) {
console.error("Failed to resolve deep link:", error);
});
}
function resolveDeepLinkExample() {
const deepLinkUrl = "https://trackier58.u9ilnk.me/d/NKmWH9E7b1";
TrackierCordovaPlugin.resolveDeeplinkUrl(deepLinkUrl)
.then(function(result) {
console.log("Resolved URL:", result.url);
console.log("SDK Parameters:", result.sdkParams);
})
.catch(function(error) {
console.error("Failed to resolve deep link:", error);
});
}
Ionic/Angular Implementation
- ✓ Apptrove SDK (Recommended)
- Trackier SDK (Deprecating August 2026)
import { Injectable } from '@angular/core';
import { AppTroveCordovaPlugin } from 'com.apptrove.cordova_sdk/ionic-native/apptrove/ngx';
@Injectable({
providedIn: 'root'
})
export class DeepLinkResolverService {
constructor(private apptroveCordovaPlugin: AppTroveCordovaPlugin) { }
async resolveDeepLinkExample() {
try {
const urlToResolve = 'https://yourdomain.u9ilnk.me/d/NKmWH9E7b1';
const result = await this.apptroveCordovaPlugin.resolveDeeplinkUrl(urlToResolve);
console.log('Resolved deep link result:', result);
return result;
} catch (error) {
console.error('Error resolving deep link:', error);
return null;
}
}
}
import { Injectable } from '@angular/core';
import { TrackierCordovaPlugin } from '@awesome-cordova-plugins/trackier/ngx';
@Injectable({
providedIn: 'root'
})
export class DeepLinkResolverService {
constructor(private trackier: TrackierCordovaPlugin) { }
async resolveDeepLinkExample() {
try {
const urlToResolve = 'https://yourdomain.u9ilnk.me/d/NKmWH9E7b1';
const result = await this.trackier.resolveDeeplinkUrl(urlToResolve);
console.log('Resolved deep link result:', result);
return result;
} catch (error) {
console.error('Error resolving deep link:', error);
return null;
}
}
}
Resolver Response Structure
The resolveDeeplinkUrl method returns a result object with the following structure:
{
url: "https://resolved-final-url.com/product/123?param=value",
sdkParams: {
dlv: "product_detail",
productid: "123",
quantity: "2",
campaign: "summer_sale"
}
}
Deep Link URL Structure
Example Deep Link URL
https://yourdomain.u9ilnk.me/d/PGJ2m4NtPd?dlv=FirstProduct&quantity=10&pid=sms
URL Components
- Base URL:
https://yourdomain.u9ilnk.me/d/ - Campaign ID:
PGJ2m4NtPd - Deep Link Value:
dlv=FirstProduct - Additional Parameters:
quantity=10&pid=sms
Steps to Test Deferred Deep Linking
Follow these comprehensive steps to properly test deferred deep linking functionality:
- APK File: Ensure you have the APK file integrated with the Apptrove SDK
- Test Device: Android device with File Manager or WhatsApp access
- Test URL: Valid deferred deep link URL with all required parameters
Step-by-Step Testing Process
1. Prepare the APK
- Store the APK file locally on your device
- Keep it accessible in File Manager or WhatsApp (as a file message)
- Ensure the APK contains the latest SDK integration
2. Trigger the Deferred Link Click on the test deep link containing all required parameters:
https://yourdomain.u9ilnk.me/d/Af2xeLPI77?pid=Ron+Media+Source&cost_value=0&cost_currency=GBP&lbw=1d&camp=Ron+Referral+Test&dlv=RonTestClass&p2=param_2_value&sdk_param=sdk_param_value
The link should redirect you to the Google Play Store page of your app.
3. Install from Local APK (Instead of Play Store)
- Once redirected to the Play Store, minimize it (don't install from there)
- Open the File Manager (or WhatsApp) where the prepared APK is stored
- This simulates the deferred deep link scenario without using the actual Play Store
4. Install the APK Manually
- Tap on the APK file and install it on the device
- Grant necessary permissions during installation
- Complete the installation process
5. Launch the App
- Open the freshly installed app
- The SDK should automatically process the deferred deep link
- Verify that the deep link parameters are correctly received and processed
- Always test with fresh app installations to simulate real user scenarios
- Verify that the SDK is properly initialized before processing deep links
- Test on both development and production environments
- Ensure network connectivity during testing
Best Practices
Do's
- Test thoroughly on both Android and iOS platforms
- Use unique schemes for Android to avoid conflicts
- Secure unilink subdomain configuration in Apptrove
- Handle null URLs with proper fallback logic
- Log deep link data for debugging during development
- Comply with privacy regulations (GDPR, CCPA)
Don'ts
- Don't assume deep links will always work immediately
- Don't forget to handle edge cases (null URLs, invalid parameters)
- Don't skip testing on actual devices
- Don't ignore platform-specific configurations
Troubleshooting
Common Issues & Solutions
| Issue | Solution |
|---|---|
| Deep links not opening app | Verify URL structure and platform configuration in AndroidManifest.xml/iOS settings |
| Universal Links failing (iOS) | Check that apple-app-site-association file is hosted correctly and accessible |
| Parameter parsing issues | Ensure deep link URL includes expected parameters and parse them correctly |
| Deferred deep links not working | Verify deferred callback is properly configured in SDK initialization |
| Deep link listener not receiving data | Check that listener is set up before SDK initialization |
| Platform-specific issues | Ensure platform configuration is complete (AndroidManifest.xml/iOS Associated Domains) |
Support
For further assistance:
Ready to implement deep linking? Follow the step-by-step guide above and test your implementation thoroughly!