React-native: WebView source={require(xxx.html)} is not working on Android Release

Created on 29 Sep 2017  路  11Comments  路  Source: facebook/react-native

Is this a bug report?

Yes

Have you read the Contributing Guidelines?

Yes

Environment

Environment:
OS: macOS Sierra 10.12.6
Node: 6.10.3
Yarn: 0.24.5
npm: 3.10.10
Watchman: 4.7.0
Xcode: Xcode 9.0 Build version 9A235
Android Studio: 2.3 AI-162.4069837

Packages: (wanted => installed)
react: 16.0.0-alpha.12 => 16.0.0-alpha.12
react-native: 0.48.4 => 0.48.4

Steps to Reproduce

(Write your steps here:)

  1. create index.html
<html>
    <head>
        <title>Title</title>
    </head>
    <body>
        <h1>Hello World</h1>
    </body>
</html>
  1. modify index.ios.js and index.android.js
/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  WebView,
  View
} from 'react-native';

export default class WebViewTest extends Component {
  render() {
    return (
      <View style={styles.container}>
        <WebView
          scalesPageToFit={true}
          source={require('WebViewTest/index.html')}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});

AppRegistry.registerComponent('WebViewTest', () => WebViewTest);
  1. Build Release APK
  2. Run On Android

Expected Behavior

Hello World show up on screen.

Actual Behavior

Nothing.
Just Blank Screen

Reproducible Demo

https://github.com/yosimasu/WebViewTest

Stale

Most helpful comment

Issue still occurs on Android. This needs to work the same as on iOS for the same reasons as people have stated above. This is obviously a bug and it is easily reproduce-able (see https://github.com/facebook/react-native/issues/7924)

All 11 comments

The behaviour of the release app is different between iOS and Android.

Pretty sure it works differently on the different platforms. Have you tried doing a platform specific require like so?

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  WebView,
  View,
  Platform
} from 'react-native';

export default class WebViewTest extends Component {
  render() {
    return (
      <View style={styles.container}>
        <WebView
          scalesPageToFit={true}
          source={Platform.OS === 'ios' ? require('./index.html') : {uri: "file:///android_asset/index.html"}}
        /> 
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});

AppRegistry.registerComponent('WebViewTest', () => WebViewTest);

Also stick a copy of the index.html file inside /android/app/src/main/assets

I've seen projects having only the one html file in the android folder and then using

require('../../../android/app/src/main/assets/index.html')

for ios but I've not tested that on a physical device yet.

@jxshco

I know the solution of {uri: "file:///android_asset/index.html"}.
It's annoying to keep sync between *.html and android_asset/*.html.

This situation works on develop.
If someone forget to sync these files, the other needs more time to find what happen on release.

It would be appreciated to be able to load local html, css, js files from within app\ folder.
And do so, crossplatformly, not tweaking solutions and keeping html files on more places.
Would such a thing possible to implement?

@yosimasu @jxshco

+1
for the same behavior on Android as is on iOS

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. If you think this issue should definitely remain open, please let us know why. Thank you for your contributions.

Issue still occurs on Android. This needs to work the same as on iOS for the same reasons as people have stated above. This is obviously a bug and it is easily reproduce-able (see https://github.com/facebook/react-native/issues/7924)

In conjunction with the workaround of using: source={Platform.OS === 'ios' ? require('./index.html') : {uri: "file:///android_asset/index.html"}}

I added a script to copy the files out of my src folder and into android appropriately by throwing this into your build.gradle.

// Android currently requires the HTML files in React Native to be
// in the Android Assets
// https://github.com/facebook/react-native/pull/17304
task copyReactNativeHTML(type: Copy) {
    from '../../src/assets/html'
    into 'src/main/assets/html'
}

// Note that you may need to add other build variants
gradle.projectsEvaluated {
    bundleDebugJsAndAssets.dependsOn(copyReactNativeHTML)
    bundleReleaseJsAndAssets.dependsOn(copyReactNativeHTML)
}

then you would likely want to add the folder you are copying into to your .gitignore

Hi,

I got the same issue while loading the webview using require('./index.html').

The provide workaround doesn't work in my case because I want to access a website and using file protocol I'm facing CORS issue :disappointed:

What I have in mind it's to bundle using webpack into a javascript file my index.html to put the content in a variable and then being able to provide the source.html props.

Do you now any way to read file content and put it into a variable instead (this would prevent me to include a webpack process in my build pipeline)

Hi,

I got the same issue as well, with a HTML file in the assets folder of the react native project. In IOS Simulator, it works fine but after building an APK and installed it on a real android device, I got an 'Access denied' in my webview component.

But I found a workaround: simply put your HTML file directly in your src package and not in an assets folder. It will be bundle like other files of your project and you can access to it by a simple relative path.

this.htmlFile = require('./html/your_custom_page.html');

Worked on Android and IOS.

Hope this will help.

JK

i had this issue
i solved by considering 4 role
1.first use **{uri: "file:///android_asset/ckeditor/index.html"}**
2.copy your _html_ in android/src/main/_assets_/

  1. sure you use this parameter in webview react native
    --domStorageEnabled={true}
    --javaScriptEnabled={true}
  2. if using proguard just remember to uncomment
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
   public *;
}

i hope this help all developer in Release mode of android 馃檹馃檹馃檹

Was this page helpful?
0 / 5 - 0 ratings

Related issues

upbit picture upbit  路  3Comments

oney picture oney  路  3Comments

josev55 picture josev55  路  3Comments

grabbou picture grabbou  路  3Comments

jlongster picture jlongster  路  3Comments