Platform Linking and Share
Cross-platform branches, deep links out of the app, share sheets, and system dialogs.
Search across all documentation pages
Cross-platform branches, deep links out of the app, share sheets, and system dialogs.
Branch on "ios" | "android" | "web" when APIs or UX truly differ.
import { Platform, Text } from "react-native";
const label = Platform.OS === "ios" ? "Hold to reorder" : "Long-press to reorder";
return <Text>{label}</Text>;Pick values (styles, components, numbers) per platform in one expression.
const hit = Platform.select({ ios: 12, android: 16, default: 12 });Gate features that need a minimum OS version (Android API level is numeric; iOS is a string version).
const supportsFeature =
Platform.OS === "android" ? Number(Platform.Version) >= 33 : true;Open https, tel, mailto, or custom schemes in another app.
import { Linking } from "react-native";
await Linking.openURL("https://expo.dev");On iOS, declare schemes in Info.plist / app config and check before opening.
const url = "twitter://user?screen_name=expo";
if (await Linking.canOpenURL(url)) await Linking.openURL(url);
else await Linking.openURL("https://twitter.com/expo");Read the URL that launched a cold start (pair with Expo Router linking config).
const initial = await Linking.getInitialURL();
if (initial) handleUrl(initial);Handle links while the app is already running.
useEffect(() => {
const sub = Linking.addEventListener("url", ({ url }) => handleUrl(url));
return () => sub.remove();
}, []);Present the OS share sheet with text and optional URL.
import { Share } from "react-native";
await Share.share({ message: "Check this out", url: "https://example.com" });Copy text with expo-clipboard for a consistent Expo API.
import * as Clipboard from "expo-clipboard";
await Clipboard.setStringAsync(inviteCode);Send users to system settings when permissions are blocked.
import { Linking } from "react-native";
await Linking.openSettings();Read app config, extra, and execution environment from expo-constants.
import Constants from "expo-constants";
const apiUrl = Constants.expoConfig?.extra?.apiUrl as string | undefined;Query device name/model when useful for support diagnostics (avoid over-collecting PII).
import * as Device from "expo-device";
const summary = `${Device.osName} ${Device.modelName ?? "unknown"}`;Surface native app version in settings/about screens.
import Constants from "expo-constants";
const version = Constants.nativeAppVersion ?? Constants.expoConfig?.version;System alert with buttons - fine for destructive confirms without a custom modal.
import { Alert } from "react-native";
Alert.alert("Delete item?", "This cannot be undone.", [
{ text: "Cancel", style: "cancel" },
{ text: "Delete", style: "destructive", onPress: onDelete },
]);iOS-only action sheet for lightweight menus; use a cross-platform library on Android.
import { ActionSheetIOS, Platform } from "react-native";
if (Platform.OS === "ios") {
ActionSheetIOS.showActionSheetWithOptions(
{ options: ["Cancel", "Edit", "Delete"], cancelButtonIndex: 0, destructiveButtonIndex: 2 },
(i) => {
if (i === 1) onEdit();
if (i === 2) onDelete();
},
);
}Stack versions: React 19.2.3 · React Native 0.86.0 · Expo SDK 57
Reviewed by Chris St. John·Last updated Jul 18, 2026