Add the this.onShouldStartLoadWithRequest function. Return TRUE or FALSE based on whether or not you want to follow the link in your WebView. This is basically the equivalent of the UIWebViewDelegate implementation you would use when you implement it in native code (Swift or Objective-C).
onShouldStartLoadWithRequest = (event) => {
Linking.canOpenURL(event.url).then(supported => {
if (supported) {
Linking.openURL(event.url);
} else {
console.log('Don\'t know how to open URI: ' + event.url);
}
return false
});
}
Make sure to import Linking as well in your javascript source:
import { AppRegistry, View, WebView, Linking } from 'react-native';
import React, { Component } from 'react';
import { WebView, Linking } from 'react-native';
export default class WebViewThatOpensLinksInNavigator extends Component {
render() {
const uri = 'http://stackoverflow.com/questions/35531679/react-native-open-links-in-browser';
return (
<WebView
ref={(ref) => { this.webview = ref; }}
source=\{\{ uri }}
onNavigationStateChange={(event) => {
if (event.url !== uri) {
this.webview.stopLoading();
Linking.openURL(event.url);
}
}}
/>
);
}
}
It uses a simple WebView, intercepts any url change, and if that url differs from the original one, stops the loading, preventing page change, and opens it in the OS Navigator instead.
In addition to the excellent answer https://stackoverflow.com/a/40382325/10236907:
When using source=\{\{html: '...'}}, you can check for an external url change using:
if (!/^data:text/.test(event.url)) {
A big issue with using "stopLoading()" is that on Android it disables further taps on any other links from that source page.
The WebView component is being split out of core RN and into the community's hands. If you use that version instead (https://github.com/react-native-community/react-native-webview), you can use "onShouldStartLoadWithRequest" prop on both iOS and Android, which makes this a lot more elegant.
Building off of Damien Varron's really helpful answer, here's an example for how you'd leverage that prop to avoid stopLoading that works cross platform:
I had many issues with this solution while using local HTML file only at iOS.
For instance, when I had Instagram embed in my webview it opened it automatically.
In order to solve it I've added (only for iOS):