How to access next url from browser click from react-native-webview

2.2k views Asked by At

I have a webview source that I have opened using react-native-webview, I want to access any and every url and console it whenever I click on the webview, so that I can use it as source for another webview. However am unable to figure how to do it

I tried using NavigationStateChange and onShouldLoadSTartwithrequest but that did not help.

below is my code

import React, {useState, useRef, useEffect} from 'react';
import {WebView} from 'react-native-webview';
import {
  View,
  SafeAreaView,
  ActivityIndicator,
  StyleSheet,
  TouchableOpacity,
  Text,
  Linking,
  Alert,
  BackHandler,
} from 'react-native';
import Footer from '../components/Footer';
import {useBackHandler} from '@react-native-community/hooks';
import OnlineConsultationWebviewScreen from './OnlineConsultationWebviewScreen';
export default function ConsultationHomeScreen(props) {
  const uri = props.route.params.uri;
  const [canGoBack, setCanGoBack] = useState(false);
  const [canGoForward, setCanGoForward] = useState(false);
  const [currentUrl, setCurrentUrl] = useState('');
  const webviewRef = useRef(null);

  const renderLoadingView = () => {
    return (
      <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
        <ActivityIndicator size="large" />
      </View>
    );
  };
  const onMessage = (e) => {
    // retrieve event data
    var data = e.nativeEvent.data;
    // maybe parse stringified JSON
    try {
      data = JSON.parse(data);
    } catch (e) {}
    // check if this message concerns us
    if ('object' == typeof data && data.external_url_open) {
      // proceed with URL open request
      return Alert.alert(
        'External URL',
        'Do you want to open this URL in your browser?',
        [
          {text: 'Cancel', style: 'cancel'},
          {text: 'OK', onPress: () => Linking.openURL(data.external_url_open)},
        ],
        {cancelable: false},
      );
    }
  };
  const jsCode = `!function(){var e=function(e,n,t){if(n=n.replace(/^on/g,""),"addEventListener"in window)e.addEventListener(n,t,!1);else if("attachEvent"in window)e.attachEvent("on"+n,t);else{var o=e["on"+n];e["on"+n]=o?function(e){o(e),t(e)}:t}return e},n=document.querySelectorAll("a[href]");if(n)for(var t in n)n.hasOwnProperty(t)&&e(n[t],"onclick",function(e){new RegExp("^https?://"+location.host,"gi").test(this.href)||(e.preventDefault(),window.postMessage(JSON.stringify({external_url_open:this.href})))})}();`;
  return (
    <SafeAreaView style={{flex: 1}}>
      <WebView
        source={{
          uri: uri,
        }}
        renderLoading={renderLoadingView}
        javaScriptEnabled={true}
        domStorageEnabled={true}
        startInLoadingState={true}
        ref={webviewRef}
        injectedJavaScript={jsCode}
        onMessage={onMessage}
        onError={console.error.bind(console, 'error')}
        // onShouldStartLoadWithRequest={(event) => {
        //   if (event.url !== uri ){
        //     Linking.openURL(event.url);
        //     console.log('Event', event.url);
        //     return false;
        //   }
        //   return true;
        // }}
      />
    </SafeAreaView>
  );
}
const styles = StyleSheet.create({
  tabBarContainer: {
    padding: 20,
    flexDirection: 'row',
    justifyContent: 'space-around',
    backgroundColor: '#b43757',
  },
  button: {
    color: 'white',
    fontSize: 24,
  },
});

Am stuck with this since long, please let me know how do I access any and every click and console it, so that I can sue it later as a new source for Webview. Any suggestion would be great.

1

There are 1 answers

0
Tarun Soni On

Try this :

<WebView
   ref="webview"
   source={uri}
   onNavigationStateChange={this._onNavigationStateChange.bind(this)}
   javaScriptEnabled = {true}
   domStorageEnabled = {true}
   injectedJavaScript = {this.state.cookie}
   startInLoadingState={false}
 />

Add this function :

_onNavigationStateChange(webViewState){
 console.log(webViewState.url)
}

FYI webviewState object consists of, use the url property:

{
canGoBack: bool,
canGoForward: bool,
loading: bool,
target: number,
title: string,
url: string,
}

let me know if it helps