What’s actually crashing on Android? On modern Android (targetSdk 31+/API 30+), any time you fire off an ACTION_VIEW intent (which is exactly what Linking.openURL() does under the hood), the system first checks your app’s package visibility. If you haven’t told Android “Hey, I might want to open web URLs,” it can’t find any browser to handle that intent—and you get an uncaught ActivityNotFoundException that kills your WebView (often silently in Expo builds).
- Emulator often uses more‑permissive settings or older WebView versions. - iOS has no such restriction at all. - Real Android devices in production builds enforce it strictly.
Always guard your openURL calls
import { Linking, Alert } from 'react-native';
async function openExternal(url) {
try {
const supported = await Linking.canOpenURL(url);
if (supported) {
await Linking.openURL(url);
} else {
Alert.alert('Oops!', `Cannot open this URL: ${url}`);
}
} catch (err) {
console.error('Failed to open URL:', err);
Alert.alert('Error', 'Couldn’t open the link.');
}
}
Prevents crashes if there’s no browser or handler.
Lets you show a friendly message instead of a hard crash.
import React, { useRef } from 'react';
import { WebView } from 'react-native-webview';
export default function MyInertiaWebView() {
const webviewRef = useRef(null);
return (
<WebView
ref={webviewRef}
source={{ uri: 'https://your-inertia-app.com' }}
originWhitelist={['*']}
// iOS + (newer) Android
onShouldStartLoadWithRequest={({ url }) => {
const isExternal = !url.startsWith('https://your-inertia-app.com');
if (isExternal) {
openExternal(url);
return false; // stop WebView
}
return true;
}}
// fallback for older Android
onNavigationStateChange={(navState) => {
const { url } = navState;
if (url.startsWith('http') && !url.startsWith('https://your-inertia-app.com')) {
openExternal(url);
webviewRef.current.stopLoading();
}
}}
/>
);
}
Guard every Linking.openURL with canOpenURL + try/catch.
Intercept external links in your WebView callbacks and call your safe openExternal() wrapper.
Declare HTTP/HTTPS intent queries in your Android manifest (via Expo plugin or by editing AndroidManifest.xml).