Create Dynamic Links in React Native
Create dynamic or unified links programmatically from your TypeScript/JavaScript code using the @ulinkly/react-native SDK.
Prerequisites
Before creating links, ensure you've completed the SDK setup:
SDK Integration
@ulinkly/react-nativeinstalled and the native config applied (config plugin or manual)ULink.initialize(...)called and awaited with a valid API key
Ulinkly Dashboard Configuration
- API key generated from Dashboard → Settings → API Keys → Generate API Key
- Domain configured in your project (Domains → Add Domain)
If you haven't completed these steps, follow the React Native Getting Started guide.
Understanding Link Types
Unified Links
- Redirect users based on platform (iOS / Android / desktop)
- Do not carry parameters into the app
- Best for: marketing campaigns, App Store redirects, simple sharing
Dynamic Links
- Include structured parameters for deep linking
- Best for: in-app navigation, personalized content, campaign tracking
The SDK uses a single createLink method for both. You select the type with the type field: 'dynamic' or 'unified'.
1. Create Dynamic Links
Dynamic links carry parameters your app uses for navigation and personalization.
import ULink from '@ulinkly/react-native';
async function createPromoLink(): Promise<string | null> {
try {
const response = await ULink.createLink({
domain: 'myapp.shared.ly', // required: your configured Ulinkly domain
type: 'dynamic',
slug: 'spring-promo', // optional: unique per domain; auto-generated if omitted
// externalId deduplicates repeat calls — if a link with this ID already exists
// on the domain, the existing link is returned instead of creating a new one.
externalId: 'promo-launch-2024',
fallbackUrl: 'https://example.com/promo', // web fallback
iosFallbackUrl: 'https://apps.apple.com/app/id123456789', // App Store
androidFallbackUrl: 'https://play.google.com/store/apps/details?id=com.myapp', // Play Store
parameters: {
screen: 'promo',
campaign: 'spring',
productId: '12345',
},
socialMediaTags: {
ogTitle: 'Spring Sale — 50% Off!',
ogDescription: "Don't miss our biggest sale of the year.",
ogImage: 'https://example.com/sale-image.jpg',
},
});
if (response.success && response.url) {
console.log('Link created:', response.url);
return response.url;
}
console.warn('Failed to create link:', response.error ?? 'Unknown error');
return null;
} catch (e) {
console.error('Error creating link:', e);
return null;
}
}
domain— required for all link types. Must be a domain configured in your dashboard.fallbackUrl— where users land if the app isn't installed (recommended for dynamic links).externalId— optional idempotency key. Reusing the sameexternalIdon a domain returns the existing link instead of creating a duplicate. See Idempotent Link Creation.slug— must be unique per domain. If you pass a slug that already exists, the API returns an error; use a different slug,externalIdfor idempotency, or update the existing link.
Response Structure
createLink resolves to a ULinkResponse:
interface ULinkResponse {
success: boolean;
url?: string; // the created link URL
data?: ULinkResolvedData; // resolved link details
error?: string; // error message if creation failed
}
Always check response.success before using response.url. On failure the SDK throws a ULinkError for transport/native errors and returns { success: false, error } for API-level rejections — wrap calls in try/catch and check success.
2. Create Unified Links
Unified links redirect based on platform without carrying parameters. Set type: 'unified' and provide the per-platform destination URLs.
async function createAppDownloadLink(): Promise<string | null> {
const response = await ULink.createLink({
domain: 'myapp.shared.ly',
type: 'unified',
slug: 'app-download', // optional
iosUrl: 'https://apps.apple.com/app/id123456789', // iOS destination
androidUrl: 'https://play.google.com/store/apps/details?id=com.myapp', // Android destination
fallbackUrl: 'https://example.com', // desktop / fallback
socialMediaTags: {
ogTitle: 'Download MyApp',
ogDescription: 'Get the best experience with our mobile app.',
ogImage: 'https://example.com/app-preview.jpg',
},
});
return response.success ? response.url ?? null : null;
}
iosUrl/androidUrl— where each platform redirects.fallbackUrl— desktop and fallback destination.parameters— not used by unified links. Use a dynamic link if you need to pass data into the app.
3. Complete Example
A screen with a "Share" button that creates a link and opens the native share sheet:
import { useState } from 'react';
import { View, Text, Button, Share, ActivityIndicator } from 'react-native';
import ULink from '@ulinkly/react-native';
type Props = { productId: string; productName: string };
export function ProductShareScreen({ productId, productName }: Props) {
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
async function onShare() {
setLoading(true);
setError(null);
try {
const response = await ULink.createLink({
domain: 'myapp.shared.ly',
type: 'dynamic',
// Idempotent per product: re-sharing the same product reuses the link.
externalId: `product-${productId}`,
fallbackUrl: `https://myshop.com/products/${productId}`,
iosFallbackUrl: 'https://apps.apple.com/app/id123456789',
androidFallbackUrl: 'https://play.google.com/store/apps/details?id=com.myshop',
parameters: { screen: 'product', productId, productName },
socialMediaTags: {
ogTitle: productName,
ogDescription: `Check out ${productName} in our app`,
ogImage: `https://myshop.com/images/${productId}.jpg`,
},
});
if (response.success && response.url) {
await Share.share({ message: response.url });
} else {
setError(response.error ?? 'Failed to create link');
}
} catch (e: any) {
setError(e?.message ?? String(e));
} finally {
setLoading(false);
}
}
return (
<View style={{ padding: 16 }}>
<Text style={{ fontSize: 20, fontWeight: '600' }}>{productName}</Text>
{loading ? (
<ActivityIndicator style={{ marginTop: 24 }} />
) : (
<Button title="Create Share Link" onPress={onShare} />
)}
{error ? <Text style={{ color: 'red', marginTop: 16 }}>{error}</Text> : null}
</View>
);
}
Best Practices
Link Creation
- Use
externalIdfor idempotency — keying off a stable ID (order ID, product ID, user ID) prevents duplicate links when a create path runs more than once. - Slugs are unique per domain — pass a unique slug or let Ulinkly generate one.
- Validate before sharing — always check
response.success. - Always
await—createLinkis async; never fire-and-forget.
Social Media Tags
- Always include OG tags for better link previews and click-through.
- Use high-quality OG images (at least 1200×630).
- Keep descriptions under ~200 characters.
Parameters
- Keep parameters flat (string key → value) for best compatibility.
- Never put passwords, tokens, or PII in parameters.
- Establish a consistent key convention (
screen,productId,userId).
Query-Parameter Passthrough
You can configure a link to forward query params appended to its URL directly into your app's parameters. This is opt-in per link via the allowQueryPassthrough flag.
Enable it via the dashboard, the REST API, or the MCP server — the SDK's createLink API does not expose this field directly.
# A link created with allowQueryPassthrough: true
https://myapp.shared.ly/promo-123?productId=456&ref=email
# → app receives parameters: { screen: 'promo', productId: '456', ref: 'email' }
Passthrough values always arrive as strings and override any stored parameter with the same key. See the Query-Parameter Passthrough guide for full details.
In-App Browser & Social Webview Behavior (iOS)
Two boolean fields control what happens when someone taps a link on iOS. Neither is exposed on the SDK's createLink API, and neither is accepted by the link-creation API or the MCP server — both are set in the dashboard, on the link's edit screen.
-
iosSocialBreakout(dashboard: "Show an 'Open App' screen on iOS") — applies to dynamic links opened on iOS, in any browser: Safari, Chrome, and in-app webviews such as TikTok, Instagram and Facebook. On by default once your project's iOS app configuration is complete: the Team ID and bundle identifier publish the Universal Link association that Open App depends on, and without them no tap could reach your app, so it stays off. The visitor is sent to a ULink launch domain (hop.shared.ly) showing an Open App button and a Download from App Store button. The user still has to tap — nothing opens automatically. Untick the dashboard toggle to turn it off for a link.In-app webviews only honor Universal Links for a real tap and, in TikTok's case, drop custom URL schemes entirely, so without this screen the deep link is simply lost there. In Safari it covers a different gap: when iOS suppresses the Universal Link — a typed URL, a same-host navigation, or the visitor having chosen to stay in the browser — no "Open" banner appears, and this screen is the only working control on the page.
-
iosBrowserAutoOpen— applies only in real iOS browsers (Safari, Chrome, Firefox, Edge — never in-app webviews). The redirect page automatically tries the app's custom URL scheme, then falls back to the link'siosFallbackUrlafter about 2.5 seconds.
When both are on, iosBrowserAutoOpen wins in a real browser: it is an explicit per-link choice, and the "Open App" screen is usually an implicit default, so the default does not override it. In-app webviews are unaffected — auto-open never runs there — so they still get the screen. See Troubleshoot & Test Deep Links for the in-app-browser troubleshooting flow.
Next Steps
- Receive Links → React Native — handle incoming links in your app
- Troubleshoot & Test Deep Links — debug and verify your links