WebView contents incorrectly rendered as plain text

Please provide the following:

  1. SDK Version: 35.0.1
  2. Platforms(Android/iOS/web/all):Android

Tried these ways to load a HTML in the assets folder and the contents are rendered a plain text instead of DOM elements:

  <WebView
    source={require('./assets/index.html'}
    //or:source={{uri:Asset.fromModule(require('./assets/index.html').uri}}
    //or:source={Asset.fromModule(require('./assets/index.html')}
     javaScriptEnabled={true}
     originWhitelist={['*']}
 </>
//package.json
"dependencies": {
    "expo": "^35.0.1",
    "react": "^16.8.3",
    "react-dom": "^16.8.3",
    "react-native": "^0.59.10"
  },

And here’s the output… Any ideas? Thanks!

I can’t see a way to make it work the way you want it to.
There does not appear to be a way to specify the content-type.

If your approach did work, you’d need to use something like source={{ html: ... }}, though, I think.

If you can inline the HTML you could do it like this:

        <WebView source={{ html: '<h1 style="color:red;font-size:64px">Testing testing 1 2 3</h1>' }}
             originWhitelist={['*']}
        />

Otherwise you will need to read the HTML into a string and then use that in the source param. I have not tried this.

Thanks but I need to load external scripts in my HTML that can’t be localized so can’t really go inline (script tags won’t work inline) - any alternatives/workarounds?

OK, I have not played around with the FileSystem API much before, but I think it might form part of your solution.

The following works for me, but I haven’t worked out how to get the file:/// URL of an asset, so I just wrote an HTML file before reading it in again. But maybe it gives you some ideas:

import React, { useEffect, useState } from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { WebView } from 'react-native-webview';
import * as FileSystem from 'expo-file-system';
import { Asset } from 'expo-asset';
import Constants from 'expo-constants';

export default () => {
  const [written, setWritten] = useState(false);
  const [html, setHtml] = useState(null);
  const contents = '<h1 style="color:red;font-size:64px">Testing testing 1 2 3</h1>';

  useEffect(() => {
    FileSystem.writeAsStringAsync(FileSystem.documentDirectory + 'test.html', contents).then(() => {
      setWritten(true);
    }).catch(error => {
      alert(JSON.stringify(error));
    })
  }, []);

  useEffect(() => {
    if (written) {
      FileSystem.readAsStringAsync(FileSystem.documentDirectory + 'test.html').then(data => {
        setHtml(data);
      }).catch(error => {
        alert(JSON.stringify(error));
      });
    }
  }, [written]);

  return (
    <View style={styles.container}>
      <WebView
        source={{
          html: html,
        }}
        originWhitelist={['*']}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
});

EDIT: I have an idea that this post by @adamjnav might also be relevant, but I haven’t thought about it too hard.

Thanks but the thing is I couldn’t get script tags to work when loading the HTML as content string … at least for expo v35 <script src...> inside a string passed to source:{{html}} does not seem to work… any ideas?

JavaScript works fine for me on my Galaxy S8 using SDK 35:

If you’re loading external resources you might need to specify baseUrl in addition to html.

1 Like

Thanks and false alarm - my script is getting loaded so my bad! Turns out it hit an error when trying to access cookies:

SecurityError: Failed to read the "cookies" property from 'Document': Cookies are disabled inside 'data':URLs

Any ideas?

Wild guess:

I know the following is not React Native, let alone Expo, but maybe it will help if you specify baseUrl. If that doesn’t work, I’m out of ideas.

http://tobias-johansson.github.io/post/android-webview-cookies/

Thinking about it some more, the baseUrl thing does make sense. I assume you tried it and it did not help?

Cookies are tied to a domain, so if there’s no domain (because you’re not loading the HTML from a server) I would not be surprised for the cookies to be disabled. But if you manually specify a domain (by providing a baseUrl), then there’s no reason that cookies couldn’t work.

Whether or not baseUrl does cause cookies to be enabled, I don’t know. Anyway, good luck.

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.