Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove android default error page on react native webview

I'm using a webview in react native and I want to display a custom error message when some error occurs (e.g. no internet connection).

My code:

<WebView 
  renderError={() => (
    <MissingConnection />
  )}
  other params....
/>

When there is an error loading the webpage, for a fraction of a second the webview displays the default android error, such as: enter image description here then my MissingConnection component pops up, hiding the webview.

Is there a way to completely remove the default android error screen? It flashes for just a fraction of a second and the result feels really wrong.

like image 634
gbalduzzi Avatar asked Oct 27 '25 00:10

gbalduzzi


2 Answers

First of all: You are doing it right.

I observed the same problem recently and did some investigation. The problem lies not in your code or React Native or react-native-webview.

This is just the default behavior for Android's WebView. Many Java developers encounter the same problem, examples for related threads on SO:

webview error while loading a page without internet

Prevent WebView from displaying "web page not available"

Android WebView onReceivedError()

The usual proposals to work around are:

  • check the internet connection before trying to load anything (prevent failing)

  • remove the error content quickly and show your own content in the onReceivedError ( which basically maps to your renderError method in react-native-webview). Sometimes with loading a local url like done in Java here.

  • take care of having an overlay which is removed in case there is no error at all. react-native-webview does it the other way round, showing an overlay when there is an error. But the Activity indicator overlay is a good example, it says until loading has finished or encountered an error.

As far as I know there is nothing we can do about except these disappointing ways, as I would prefer not to fight against the system.

Edit: Firefox Focus for Android does the same with quickly replacing content in the error handler.

Thats done in Java in their source here:

https://github.com/mozilla-mobile/focus-android/blob/c789362b9c331b2036755a8398e3770be43b50b8/app/src/main/java/org/mozilla/focus/webview/FocusWebViewClient.java#L330

and

https://github.com/mozilla-mobile/focus-android/blob/63339d2d9a5d132bf4a1fffc4c46c0ce393abe87/app/src/main/java/org/mozilla/focus/webview/ErrorPage.java#L126.

So I assume we are in good company!

Edit 2: I am curious if this is really visible when not in debug mode on a real Android device. My educated guess is that the code executes way faster and it shouldn`t be visible at all. Btw this page is probably only shown for 404 (Not found) errors which are unlikely if you use hardcoded urls and your own servers.

Edit 3: The native error page is visible running on a real device in release mode. The only way to prevent this flickering would be to create an overlay. I opened an issue related to another error which also addresses this one with react-native-webview here https://github.com/react-native-community/react-native-webview/issues/474#issuecomment-487022106.

like image 117
Frederik Winkelsdorf Avatar answered Oct 28 '25 16:10

Frederik Winkelsdorf


My solutions is Alert function

import React, { Component } from 'react';
import { Alert } from 'react-native';
import { View, Spinner } from 'native-base';
import { WebView } from 'react-native-webview';

export default class ExampleScreen extends Component {

  displaySpinner() {
    return (
      <View style={{ flex: 1 }}>
        <Spinner color="blue" />
      </View>
    );
  }

  displayError() {
    Alert.alert(
      "no_internet",
      "require_internet_connection",
      [
        { text: 'OK', onPress: () => this.props.navigation.goBack() },
      ],
      { cancelable: false });
  }

  render() {
    return (
      <WebView onError={() => this.displayError()}
        startInLoadingState={true}
        renderLoading={() => {
          return this.displaySpinner();
        }}
        source={{ uri: 'https://example.com' }} />
    );
  }
};

enter image description here

like image 40
Nijat Aliyev Avatar answered Oct 28 '25 14:10

Nijat Aliyev