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:

"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>' }}

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(() => {
    }).catch(error => {
  }, []);

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

  return (
    <View style={styles.container}>
          html: html,

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.


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.