React native webview: The comprehensive guide you need to know

React native is a term that is no longer unfamiliar to any developers as well as programmers. In fact, it is a well-known JavaScript-based mobile app framework that allows you to build native-looking iOS and Android apps. But what is a React native review? Then, have you ever heard about it? If NO, ArrowHiTech will deliver you a lot of helpful information about React native web view, in particular, the comprehensive guide to help you master it as soon as possible. So, let’s explore it right now!

What does React native webview mean?

Firstly, simply speaking, React native webview is a component that allows your React Native app to load webpages. Besides, in the previous time, it used to be included in React Native out of the box. But it has since been removed from the core and added to the React Native Community library. Then, nowadays, if you want to utilize it, you must install the react-native-webview library.

React native webview

React Native WebView: The comprehensive guide for you to get started

To begin, you have to use the following command to install the library.

// with yarn

$ yarn add react-native-webview

// with npm

$ npm install –save react-native-webview

After that, you must connect the dependencies. Auto-linking will handle the linking procedure starting with react-native 0.60, but you must keep in mind to remember to execute pod install beforehand. What’s more, Native Objective-C, Swift, Java, or Kotlin code in React Native modules must be “linked”. As a result,  the compiler will know to include it in the app.

Then, let’s run the following command to link it:

$ react-native link react-native-webview

For iOS

Now, you should follow like below in case you’re using CocoaPods in the ios/ directory:

$ pod install

Meanwhile, with Android, this will be different. Then, you must make sure AndroidX is enabled in your project if you’re using react-native-webview version ≥6.X.X by editing android/gradle.properties and adding the two lines below:

android.useAndroidX=true

android.enableJetifier=true

Also read: React native review: Everything you should know in 2021

Basic quickstart with React native WebView

Firstly, you have to start with a review of WebView’s basic properties. So, let’s refer to codes below:

import React, { Component } from ‘react’;

import { WebView } from ‘react-native-webview’;

class MyWeb extends Component {

  render() {

    return (

      <WebView

        source={{ uri: ‘https://logrocket.com/’ }}

        style={{ marginTop: 20 }}

      />

    );

  }

}

After that, as you can see through codes above, the source attribute is first used to obtain content from a URL or HTML. What’s more, you must pass an object with the field uri to load a webpage by its URL. So, it will demonstrate as below:

<WebView

  source={{ uri: ‘https://logrocket.com/’ }}

/>

guide of React native webview

What about loading inline HTML in WebView?

In the previous part, you surely know how to load a webpage using its URL. However, you can utilize the html property in WebView’s source property in order to load HTML directly. Then, you can run it like below:

<WebView

  originWhitelist={[‘*’]}

  source={{ html: ‘<h1>Hello world</h1>’ }}

/>

What does originWhitelist property mean in Webview?

Firstly, in the simple way, the originWhitelist plays a role to determine where visitors can go in your WebView. Besides, the default whitelisted origins are http:// and https://, and it accepts an array of strings. For instance, in order to make sure that users can only go to URIs that start with https:// or git:/, all you need to do is following the codes below. Then, explore it now!

<WebView

  source={{ uri: ‘https://logrocket.com/’ }}

  originWhitelist={[‘https://*’, ‘git://*’]}

/>

How to load HTML files in React native WebView?

In fact, you might have HTML files that you’d like to load in WebView alongside your app. What’s more, if you’re an iOs user, you just need to simply import the HTML file as any other asset of it, as illustrated below:

import React, { Component } from ‘react’;

import { WebView } from ‘react-native-webview’;

const myHtmlFile = require(“./my-asset-folder/local-site.html”);

class MyWeb extends Component {

  render() {

    return (

      <WebView source={myHtmlFile} />

    );

  }

}

Nevertheless, with Android, your HTML files must be placed in the Android assets directory. If you wish to use logrocket.html  in your Android app, for example, you must place it in the Android assets directory, which is yourProject/android/src/main/assets/.

The HTML file can then be loaded, as you can seen in the example below:

import React, { Component } from ‘react’;

import { WebView } from ‘react-native-webview’;

class MyWeb extends Component {

  render() {

    return (

      <WebView source={{ uri: “file:///android_asset/logrocket.html” }} />

    );

  }

}

User-controlled navigation state changes

In simple terms, when the WebView loading begins or ends, the function onNavigationStateChange is called. In reality, this is the ideal technique to handle navigation state changes and do something other than navigate there in the WebView. Then, for more detail, you should consider the following scenario:

import React, { Component } from ‘react’;

import { WebView } from ‘react-native-webview’;

class MyWeb extends Component {

  webview = null;

  render() {

    return (

      <WebView

        ref={ref => (this.webview = ref)}

        source={{ uri: ‘https://logrocket.com/’ }}

        onNavigationStateChange={this.handleWebViewNavigationStateChange}

      />

    );

  }

  handleWebViewNavigationStateChange = newNavState => {

    // newNavState looks something like this:

    // {

    //   url?: string;

    //   title?: string;

    //   loading?: boolean;

    //   canGoBack?: boolean;

    //   canGoForward?: boolean;

    // }

    const { url } = newNavState;

    if (!url) return;

    // handle certain doctypes

    if (url.includes(‘.pdf’)) {

      this.webview.stopLoading();

      // open a modal with the PDF viewer

    }

    // one way to handle a successful form submit is via query strings

    if (url.includes(‘?message=success’)) {

      this.webview.stopLoading();

      // maybe close this view?

    }

    // one way to handle errors is via query string

    if (url.includes(‘?errors=true’)) {

      this.webview.stopLoading();

    }

    // redirect somewhere else

    if (url.includes(‘google.com’)) {

      const newURL = ‘https://logrocket.com/’;

      const redirectTo = ‘window.location = “‘ + newURL + ‘”‘;

      this.webview.injectJavaScript(redirectTo);

    }

  };

}

Moreover, you must take a note that if the hash URL changes (for example, from https://logrocket.com/users#list to https://logrocket.com/users#help), this function will not be called. However, starting with version 8.0.0, if you use onNavigationStateChange on iOS, it will now fire when the URL # changes.

A quick way to add support for file uploads in WebView

Firstly, if you want to let file uploads in WebView, you’ll need to add the permissions listed as below. As you can see below, they have been broken down by task and platform so you can find exactly what you need.

Quick way to add support for file uploads in WebView

For iOS

Firstly, with the iOS users, all they have to do is set the permissions in the ios/[project]/Info.plist file.

Firstly, with the goal of photo capture:

<key>NSCameraUsageDescription</key>

<string>Take pictures for certain activities</string>

Besides, for gallery selection, use the following codes:

<key>NSPhotoLibraryUsageDescription</key>

<string>Select pictures for certain activities</string>

Finally is for video recording. Then, let’s refer to codes below to know more:

<key>NSMicrophoneUsageDescription</key>

<string>Need microphone access for recording videos</string>

For Android

With Android, in order to add support for file uploads, you have to add the permission in AndroidManifest.xml (/android/app/src/main/AndroidManifest.xml). Then, you should refer to codes below:

<manifest …>

  ……

  <!– this is required only for Android 4.1-5.1 (api 16-22)  –>

  <uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE” />

  ……

</manifest>

Moreover, although Android 4.4 KitKat doesn’t support file upload using <input type=”file” />, if you want to see if file upload is supported, the best way you can adapt is using the isFileUploadSupported(). So, let’s see the codes below:

WebView.isFileUploadSupported().then(res => {

  if (res === true) {

    // file upload is supported

  } else {

    // file upload is not supported

  }

});

React native webview – Controlling multiple file uploads

In any case, you can take advantage of the multiple attribute on your input element to control single and multiple file uploads. Then, you should refer to it through following instance:

// multiple file selection

<input type=”file” multiple />

// single file selection

<input type=”file” />

How to add support for file downloads in Webview?

In order to let users be able to download files from your WebView, the most important thing is give them permission. So, in the section below, we will show you the way to add support for file downloads for both iOS and Android.

For iOS

Firstly, for iOS, setting the permissions in the ios/[project]/Info.plist file is all you need to do if you want to add support for file downloads. 

In order to save to gallery, let’s run codes below:

<key>NSPhotoLibraryAddUsageDescription</key>

<string>Save pictures for certain activities.</string>

With Android

In terms of Android in this case, you must add permission in AndroidManifest.xml,  specifically in /android/app/src/main/AndroidManifest.xml:

<manifest …>

  ……

  <!– this is required to save files on Android  –>

  <uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE” />

  ……

</manifest>

The simple guide to inject JavaScript in React native WebView

In addition, if you expect to use the WebView to run JavaScript, you can take advantage of three options like below.

#1. Firstly, the injectedJavaScript prop

#2. Secondly, the injectJavaScript method

#3. Finally, the postMessage method and onMessage prop

Now, we will show you about each method in detail.

The injectedJavaScript prop in React native Webview

As soon as the webpage loads for the first time, this method executes your specified script. Even if the page is reloaded or the user navigates away, it only executes once. So, you should consider the following scenario:

import React, { Component } from ‘react’;

import { View } from ‘react-native’;

import { WebView } from ‘react-native-webview’;

export default class App extends Component {

  render() {

    const myScript = `

      document.body.style.backgroundColor = ‘red’;

      setTimeout(function() { window.alert(‘hi’) }, 2000);

      true; // note: this is required, or you’ll sometimes get silent failures

    `;

    return (

      <View style={{ flex: 1 }}>

        <WebView

          source={{

            uri:

              ‘https://github.com/react-native-community/react-native-webview’,

          }}

          injectedJavaScript={runFirst}

        />

      </View>

    );

  }

}

Then, as you can see in the image below, I set the background color to red and alert “hi” after two seconds in the preceding script. Once the page has loaded, myScript will begin to run.

What’s going on internally?

Firstly, in iOS, injectedJavaScript calls the evaluateJavaScript:completionHandler: method on WebView. On the other hand, on Android, injectedJavaScript calls the evaluateJavascriptWithFallback function on the Android WebView. Moreover, as previously stated, the injectedJavaScript prop executes after the content has been loaded. So, in case you want to run the JavaScript code before loading the content, you must ask another prop called injectedJavaScriptBeforeContentLoaded for help. Even if the page is reloaded or the user navigates away, it only executes once. When you wish to inject something into the window, localStorage, or document before the code runs, you can use this prop. Then, you can see the codes below:

import React, { Component } from ‘react’;

import { View } from ‘react-native’;

import { WebView } from ‘react-native-webview’;

export default class App extends Component {

  render() {

    const runFirst = `

      window.isNativeApp = true;

      true; // note: this is required, or you’ll sometimes get silent failures

    `;

    return (

      <View style={{ flex: 1 }}>

        <WebView

          source={{ uri: ‘https://logrocket.com/’ }}

          injectedJavaScriptBeforeContentLoaded={runFirst}

        />

      </View>

    );

  }

}

The injectJavaScript method

Unfortunately, the injectedJavaScript prop has the disadvantage of only running once. So, this is the reason why the injectJavaScript method was created on the WebView ref. Then, you can see the injectJavaScript prop that can be used in the following way:

import React, { Component } from ‘react’;

import { View } from ‘react-native’;

import { WebView } from ‘react-native-webview’;

export default class App extends Component {

  render() {

    const run = `

      document.body.style.backgroundColor = ‘blue’;

      true;

    `;

    setTimeout(() => {

      this.webref.injectJavaScript(run);

    }, 3000);

    return (

      <View style={{ flex: 1 }}>

        <WebView

          ref={r => (this.webref = r)}

          source={{ uri: ‘https://logrocket.com/’ }}

        />

      </View>

    );

  }

}

After that, the code will run in three seconds and turn the backdrop blue.

What’s going on internally?

In fact, WebView’s evaluateJS:andThen: is called by injectJavaScript on iOS. Meanwhile, on Android, injectJavaScript will call the evaluateJavascriptWithFallback function of the Android WebView.

The postMessage method and onMessage prop in React native Webview

Firstly, as you probably see, the prior methods for injecting JavaScript code using properties are really useful. However, if the webpage wants to communicate with your React Native code, you must utilize the ReactNativeWebView.postMessage and the onMessage prop.

Specifically, you have to put onMessage or the window.ReactNativeWebView.postMessage method won’t be injected into the webpage, as illustrated like below. So, let’s see now!

import React, { Component } from ‘react’;

import { View } from ‘react-native’;

import { WebView } from ‘react-native-webview’;

export default class App extends Component {

  render() {

    const html = `

      <html>

      <head></head>

      <body>

        <script>

          setTimeout(function () {

            window.ReactNativeWebView.postMessage(“Hello!”)

          }, 2000)

        </script>

      </body>

      </html>

    `;

    return (

      <View style={{ flex: 1 }}>

        <WebView

          source={{ html }}

          onMessage={event => {

            alert(event.nativeEvent.data);

          }}

        />

      </View>

    );

  }

}

As a result, the code will generate a “Hello!” alert. So, you can see it in the image below:

comprehensive guide of react native webview

In conclusion

To sum up, this blog is an overview of React native webview, specifically all the comprehensive guides to help you work well with it. All in all, if you have any questions, let’s CONTACT US right away. Then, with many years of experience in React Native App Development Services, we will solve it for you in the shortest time. 

Tags

Share