Creating Short Referrer Links
Generate short, shareable referrer links that enable user-to-user attribution and track app installs from organic referrals.
Version Requirement: This functionality requires SDK version 3.1.8 or higher. Short links remain active for 30 days after creation.
Overview
What Are Short Referrer Links
Short links transform long, parameter-filled Singular Links into compact, secure URLs convenient for sharing via SMS, social media, or in-app invitations.
Create short links dynamically so users can share them with friends to invite them to download and use your app. Each short link tracks the referring user, enabling you to measure viral growth and attribute new installs to specific advocates.
Implementation Requirements
Required Components
Gather these elements before creating a short referrer link:
- Singular Link: A base tracking link that directs users to your app download. See Singular Links FAQ for setup instructions
- Dynamic Parameters: Optional custom parameters to add context to the link. View available options in Tracking Link Parameters
- Referrer Information: Name and ID of the user sharing the link to enable attribution of new installs back to the referrer
SDK Method
CreateReferrerShortLink
Generate a short referrer link with custom parameters and a callback handler for success and error states.
Method Signature:
static createReferrerShortLink(
baseLink: string,
referrerName: string,
referrerId: string,
passthroughParams: Record<string, any>,
completionHandler: (data: string | null, error?: string) => void
): void
Parameters:
- baseLink: The original Singular tracking link URL
- referrerName: Display name of the referring user
- referrerId: Unique identifier for the referring user
- passthroughParams: Object containing additional dynamic parameters (optional, pass empty object or null if none)
-
completionHandler: Callback function with parameters
(shortLinkURL: string | null, error?: string)
For complete method documentation, see createReferrerShortLink reference.
Basic Usage Example
Create a short link with custom parameters and implement sharing logic in the success callback.
// TurboModule direct API (React Native 0.76+ New Architecture)
import React from 'react';
import { View, Button, Alert, Share } from 'react-native';
import NativeSingular from 'singular-react-native/js/NativeSingular';
export default function ReferralScreen() {
const handleShareReferral = () => {
// Create custom parameters for the link
const parameters = {
channel: 'sms',
campaign_id: 'summer_promo_2025',
referral_type: 'friend_invite'
};
// Generate the short referrer link
NativeSingular.createReferrerShortLink(
'https://sample.sng.link/D52wc/cuvk?pcn=test', // Base Singular Link
'John Doe', // Referrer name
'user_12345', // Referrer ID
parameters, // Custom parameters
(shortLink, error) => {
if (error) {
// Error occurred during link creation
console.error('Error creating short link:', error);
Alert.alert('Error', 'Failed to create share link. Please try again.');
} else if (shortLink) {
// Success - short link was created
console.log('Generated short link:', shortLink);
// Share the link using React Native's Share API
shareLink(shortLink);
}
}
);
};
const shareLink = async (shortLink) => {
try {
const result = await Share.share({
message: `Join me on this awesome app! ${shortLink}`,
url: shortLink // iOS only
});
if (result.action === Share.sharedAction) {
if (result.activityType) {
console.log('Shared with activity type:', result.activityType);
} else {
console.log('Link shared successfully');
}
} else if (result.action === Share.dismissedAction) {
console.log('Share dismissed');
}
} catch (error) {
console.error('Error sharing link:', error);
Alert.alert('Error', 'Failed to share link');
}
};
return (
<View>
<Button title="Share Referral Link" onPress={handleShareReferral} />
</View>
);
}
import React from 'react';
import { View, Button, Alert, Share } from 'react-native';
import { Singular } from 'singular-react-native';
export default function ReferralScreen() {
const handleShareReferral = () => {
// Create custom parameters for the link
const parameters = {
channel: 'sms',
campaign_id: 'summer_promo_2025',
referral_type: 'friend_invite'
};
// Generate the short referrer link
Singular.createReferrerShortLink(
'https://sample.sng.link/D52wc/cuvk?pcn=test', // Base Singular Link
'John Doe', // Referrer name
'user_12345', // Referrer ID
parameters, // Custom parameters
(shortLink, error) => {
if (error) {
// Error occurred during link creation
console.error('Error creating short link:', error);
Alert.alert('Error', 'Failed to create share link. Please try again.');
} else if (shortLink) {
// Success - short link was created
console.log('Generated short link:', shortLink);
// Share the link using React Native's Share API
shareLink(shortLink);
}
}
);
};
const shareLink = async (shortLink) => {
try {
const result = await Share.share({
message: `Join me on this awesome app! ${shortLink}`,
url: shortLink // iOS only
});
if (result.action === Share.sharedAction) {
if (result.activityType) {
console.log('Shared with activity type:', result.activityType);
} else {
console.log('Link shared successfully');
}
} else if (result.action === Share.dismissedAction) {
console.log('Share dismissed');
}
} catch (error) {
console.error('Error sharing link:', error);
Alert.alert('Error', 'Failed to share link');
}
};
return (
<View>
<Button title="Share Referral Link" onPress={handleShareReferral} />
</View>
);
}
Advanced Implementation
Implement a complete referral system with retry logic, loading states, and clipboard fallback.
// TurboModule direct API (React Native 0.76+ New Architecture)
import React, { useState } from 'react';
import { View, Button, Alert, ActivityIndicator } from 'react-native';
import NativeSingular from 'singular-react-native/js/NativeSingular';
import Clipboard from '@react-native-clipboard/clipboard';
export default function ReferralManager({ userId, userName, baseLink }) {
const [isGenerating, setIsGenerating] = useState(false);
const [lastGeneratedLink, setLastGeneratedLink] = useState(null);
const generateShortLink = (retryCount = 0) => {
return new Promise((resolve, reject) => {
const parameters = {
channel: 'in_app',
campaign_id: 'organic_referral',
user_tier: 'premium',
referral_timestamp: Date.now().toString()
};
NativeSingular.createReferrerShortLink(
baseLink,
userName,
userId,
parameters,
(shortLink, error) => {
if (error) {
// Retry logic with exponential backoff
if (retryCount < 3) {
const delay = Math.pow(2, retryCount) * 1000; // 1s, 2s, 4s
console.log(`Retrying in ${delay}ms... (Attempt ${retryCount + 1}/3)`);
setTimeout(() => {
generateShortLink(retryCount + 1)
.then(resolve)
.catch(reject);
}, delay);
} else {
reject(new Error(error));
}
} else if (shortLink) {
setLastGeneratedLink(shortLink);
resolve(shortLink);
} else {
reject(new Error('Unknown error occurred'));
}
}
);
});
};
const handleShare = async () => {
setIsGenerating(true);
try {
const shortLink = await generateShortLink();
console.log('Short link generated:', shortLink);
// Attempt to share
const { Share } = require('react-native');
const result = await Share.share({
message: `${userName} invited you to join! ${shortLink}`,
url: shortLink
});
if (result.action === Share.sharedAction) {
console.log('Link shared successfully');
// Track share event
NativeSingular.event('referral_link_shared');
}
} catch (error) {
console.error('Error in share flow:', error);
// Fallback: Copy to clipboard if available
if (lastGeneratedLink) {
Clipboard.setString(lastGeneratedLink);
Alert.alert(
'Link Copied',
'Failed to share, but the referral link has been copied to your clipboard!',
[{ text: 'OK' }]
);
} else {
Alert.alert(
'Error',
'Failed to generate referral link. Please check your connection and try again.',
[{ text: 'OK' }]
);
}
} finally {
setIsGenerating(false);
}
};
const copyToClipboard = () => {
if (lastGeneratedLink) {
Clipboard.setString(lastGeneratedLink);
Alert.alert('Copied!', 'Referral link copied to clipboard');
} else {
Alert.alert('No Link', 'Please generate a link first');
}
};
return (
<View>
{isGenerating ? (
<ActivityIndicator size="large" />
) : (
<>
<Button
title="Share Referral Link"
onPress={handleShare}
disabled={isGenerating}
/>
{lastGeneratedLink && (
<Button
title="Copy Link"
onPress={copyToClipboard}
/>
)}
</>
)}
</View>
);
}
import React, { useState } from 'react';
import { View, Button, Alert, ActivityIndicator, Clipboard } from 'react-native';
import { Singular } from 'singular-react-native';
export default function ReferralManager({ userId, userName, baseLink }) {
const [isGenerating, setIsGenerating] = useState(false);
const [lastGeneratedLink, setLastGeneratedLink] = useState(null);
const generateShortLink = (retryCount = 0) => {
return new Promise((resolve, reject) => {
const parameters = {
channel: 'in_app',
campaign_id: 'organic_referral',
user_tier: 'premium',
referral_timestamp: Date.now().toString()
};
Singular.createReferrerShortLink(
baseLink,
userName,
userId,
parameters,
(shortLink, error) => {
if (error) {
// Retry logic with exponential backoff
if (retryCount < 3) {
const delay = Math.pow(2, retryCount) * 1000; // 1s, 2s, 4s
console.log(`Retrying in ${delay}ms... (Attempt ${retryCount + 1}/3)`);
setTimeout(() => {
generateShortLink(retryCount + 1)
.then(resolve)
.catch(reject);
}, delay);
} else {
reject(new Error(error));
}
} else if (shortLink) {
setLastGeneratedLink(shortLink);
resolve(shortLink);
} else {
reject(new Error('Unknown error occurred'));
}
}
);
});
};
const handleShare = async () => {
setIsGenerating(true);
try {
const shortLink = await generateShortLink();
console.log('Short link generated:', shortLink);
// Attempt to share
const { Share } = require('react-native');
const result = await Share.share({
message: `${userName} invited you to join! ${shortLink}`,
url: shortLink
});
if (result.action === Share.sharedAction) {
console.log('Link shared successfully');
// Track share event
Singular.event('referral_link_shared');
}
} catch (error) {
console.error('Error in share flow:', error);
// Fallback: Copy to clipboard if available
if (lastGeneratedLink) {
Clipboard.setString(lastGeneratedLink);
Alert.alert(
'Link Copied',
'Failed to share, but the referral link has been copied to your clipboard!',
[{ text: 'OK' }]
);
} else {
Alert.alert(
'Error',
'Failed to generate referral link. Please check your connection and try again.',
[{ text: 'OK' }]
);
}
} finally {
setIsGenerating(false);
}
};
const copyToClipboard = () => {
if (lastGeneratedLink) {
Clipboard.setString(lastGeneratedLink);
Alert.alert('Copied!', 'Referral link copied to clipboard');
} else {
Alert.alert('No Link', 'Please generate a link first');
}
};
return (
<View>
{isGenerating ? (
<ActivityIndicator size="large" />
) : (
<>
<Button
title="Share Referral Link"
onPress={handleShare}
disabled={isGenerating}
/>
{lastGeneratedLink && (
<Button
title="Copy Link"
onPress={copyToClipboard}
/>
)}
</>
)}
</View>
);
}
Implementation Best Practices
Error Handling
Implement robust error handling in the callback to manage network failures, invalid parameters, or server issues.
- Retry Logic: Implement exponential backoff for transient network errors
- User Feedback: Display clear error messages when link creation fails
- Fallback Option: Provide alternative sharing methods (e.g., share the full Singular Link if short link creation fails)
-
Validation: Verify parameters before calling
createReferrerShortLinkto catch issues early
Tracking and Analytics
Leverage referrer information to build viral loops and measure organic growth.
Best Practice: Use consistent referrer IDs that match your internal user identification system. This enables you to:
- Attribute new installs to specific referring users
- Reward users for successful referrals
- Track viral coefficient and K-factor metrics
- Identify your most valuable brand advocates
Link Expiration
Plan for the 30-day link lifecycle in your sharing strategy.
Important: Short links expire after 30 days. For long-term campaigns or persistent share features, generate new short links periodically or use the full Singular Link as a fallback.
Common Use Cases
In-App Referral Programs
Enable users to invite friends directly from your app with personalized referral links.
- Reward System: Track referrals and reward users for successful friend signups
- Social Sharing: Integrate with React Native Share API for SMS, WhatsApp, email, and social media
- Personal Invites: Include referrer name in the shared message for personalization
User-Generated Content
Create shareable links when users generate content they want to share with others.
- Content Attribution: Track which content drives the most app installs
- Creator Recognition: Attribute new users to content creators for gamification
- Campaign Tagging: Add dynamic parameters based on content type or category
Event Invitations
Generate unique links for event invitations that track which attendees bring new users.
- Event Context: Include event ID and details in link parameters
- Attendee Tracking: Measure viral spread from event to event
- Network Effects: Identify events with the highest conversion rates