Skip to main content

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-native installed 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.

Unified vs. Dynamic Links

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'.

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;
}
}
Required & key fields
  • 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 same externalId on 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, externalId for 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.

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;
}
Unified link fields
  • 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

  • Use externalId for 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 awaitcreateLink is 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.

Next Steps