Add deep linking to your React Native or Expo app with a single SDK. Works on iOS and Android with full support for deferred deep linking, install attribution, and custom domains.
npx expo install @ulinkly/react-nativeBare React Native: npm install @ulinkly/react-native then npx install-expo-modules@latest. Not supported in Expo Go.
// app.json
{
"expo": {
"plugins": [
["@ulinkly/react-native", {
"scheme": "myapp",
"domains": ["myapp.shared.ly"]
}]
]
}
}Then run npx expo prebuild. The plugin configures iOS Associated Domains + URL scheme and Android intent filters automatically.
import ULink from '@ulinkly/react-native';
// Call once at app startup; always await initialize().
ULink.initialize({ apiKey: 'your-api-key', debug: __DEV__ })
.catch(console.error);import { useEffect } from 'react';
import ULink from '@ulinkly/react-native';
function App() {
useEffect(() => {
// Fires on cold-start, foreground, and deferred install.
const sub = ULink.onDynamicLink((data) => {
const screen = data.parameters?.screen;
// Route the user to the right screen
});
return () => sub.remove(); // do NOT call ULink.dispose() here
}, []);
return <YourNavigator />;
}Expo projects get all native configuration from the config plugin above. For bare React Native (no config plugin), configure the native files manually.
Add the Associated Domains entitlement and a URL scheme in Xcode:
applinks:yourapp.ulink.lyAfter npx install-expo-modules, the SDK's AppDelegate subscriber intercepts links automatically — no manual AppDelegate edits. Ulinkly hosts your AASA file.
Add intent-filters to AndroidManifest.xml:
<activity ...>
<intent-filter android:autoVerify="true">
<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="yourapp.ulink.ly" />
</intent-filter>
</activity>Ulinkly automatically hosts your assetlinks.json file for App Links verification.
Deferred deep linking preserves link context through the app install flow. When a user clicks a link, installs your app, and opens it—they land exactly where you intended.
// Deferred links arrive through the same listener
ULink.onDynamicLink((data) => {
if (data.isDeferred) {
const referralCode = data.parameters?.ref;
const productId = data.parameters?.product;
// Credit referral, navigate to product, etc.
}
});Create a free account and get your API key. Most teams are live in under 30 minutes.