I am developing a React Native app with a WebView to load an HTML package from the local file system. I am focusing on iOS development first and will work on Android later.
Below is the code I’m using to load the HTML file:
App.js
<code>import RNFS from 'react-native-fs';
Platform.OS === 'android'
? 'file:///android_asset/samples/index.html'
: `${RNFS.MainBundlePath}/samples/index.html`;
allowUniversalAccessFromFileURLs={true}
onError={syntheticEvent => {
const {nativeEvent} = syntheticEvent;
console.log('WebView error:', nativeEvent);
onHttpError={syntheticEvent => {
const {nativeEvent} = syntheticEvent;
console.log('HTTP error:', nativeEvent);
console.log('WebView log:', event.nativeEvent.data);
<code>import RNFS from 'react-native-fs';
const pathURI =
Platform.OS === 'android'
? 'file:///android_asset/samples/index.html'
: `${RNFS.MainBundlePath}/samples/index.html`;
<WebView
source={{uri: pathURI}}
style={styles.webview}
originWhitelist={['*']}
javaScriptEnabled={true}
allowFileAccess={true}
allowUniversalAccessFromFileURLs={true}
onError={syntheticEvent => {
const {nativeEvent} = syntheticEvent;
console.log('WebView error:', nativeEvent);
}}
onHttpError={syntheticEvent => {
const {nativeEvent} = syntheticEvent;
console.log('HTTP error:', nativeEvent);
}}
onMessage={event => {
console.log('WebView log:', event.nativeEvent.data);
}}
/>
</code>
import RNFS from 'react-native-fs';
const pathURI =
Platform.OS === 'android'
? 'file:///android_asset/samples/index.html'
: `${RNFS.MainBundlePath}/samples/index.html`;
<WebView
source={{uri: pathURI}}
style={styles.webview}
originWhitelist={['*']}
javaScriptEnabled={true}
allowFileAccess={true}
allowUniversalAccessFromFileURLs={true}
onError={syntheticEvent => {
const {nativeEvent} = syntheticEvent;
console.log('WebView error:', nativeEvent);
}}
onHttpError={syntheticEvent => {
const {nativeEvent} = syntheticEvent;
console.log('HTTP error:', nativeEvent);
}}
onMessage={event => {
console.log('WebView log:', event.nativeEvent.data);
}}
/>
index.html
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="stylesheet" href="css/style.css" />
<div class="loaderwrap">LOADING...</div>
<script src="js/index.js"></script>
<code><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="stylesheet" href="css/style.css" />
</head>
<body>
<div class="loaderwrap">LOADING...</div>
<script src="js/index.js"></script>
</body>
</html>
</code>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="stylesheet" href="css/style.css" />
</head>
<body>
<div class="loaderwrap">LOADING...</div>
<script src="js/index.js"></script>
</body>
</html>
index.js
<code>window.addEventListener('load', evt => {
console.log('Window Loaded');
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
console.log('onreadystatechange', xhttp.status, xhttp.readyState);
if (xhttp.readyState === XMLHttpRequest.DONE) {
if (xhttp.status === 200) {
console.log('Response:', xhttp.responseText);
console.log('Error:', xhttp.statusText);
xhttp.open('GET', 'data.json', true);
console.log('Window onload code executed');
<code>window.addEventListener('load', evt => {
console.log('Window Loaded');
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
console.log('onreadystatechange', xhttp.status, xhttp.readyState);
if (xhttp.readyState === XMLHttpRequest.DONE) {
if (xhttp.status === 200) {
console.log('Response:', xhttp.responseText);
} else {
console.log('Error:', xhttp.statusText);
}
}
};
xhttp.open('GET', 'data.json', true);
xhttp.send();
console.log('Window onload code executed');
});
</code>
window.addEventListener('load', evt => {
console.log('Window Loaded');
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
console.log('onreadystatechange', xhttp.status, xhttp.readyState);
if (xhttp.readyState === XMLHttpRequest.DONE) {
if (xhttp.status === 200) {
console.log('Response:', xhttp.responseText);
} else {
console.log('Error:', xhttp.statusText);
}
}
};
xhttp.open('GET', 'data.json', true);
xhttp.send();
console.log('Window onload code executed');
});
Issue:
The index.html and index.js files load successfully, and the window.onload function executes. However, the XMLHttpRequest does not execute because it requires a web server to function.
To solve this, I used the react-native-static-server package with the following code:
<code>import StaticServer from 'react-native-static-server';
Platform.OS === 'android'
? 'file:///android_asset/samples'
: `${RNFS.MainBundlePath}/samples`;
const server = new StaticServer(8080, pathURI, {
server.start().then(url => {
console.log(`Server started at ${url}`);
<code>import StaticServer from 'react-native-static-server';
const pathURI =
Platform.OS === 'android'
? 'file:///android_asset/samples'
: `${RNFS.MainBundlePath}/samples`;
useEffect(() => {
const server = new StaticServer(8080, pathURI, {
localOnly: true,
});
server.start().then(url => {
console.log(`Server started at ${url}`);
});
}, []);
</code>
import StaticServer from 'react-native-static-server';
const pathURI =
Platform.OS === 'android'
? 'file:///android_asset/samples'
: `${RNFS.MainBundlePath}/samples`;
useEffect(() => {
const server = new StaticServer(8080, pathURI, {
localOnly: true,
});
server.start().then(url => {
console.log(`Server started at ${url}`);
});
}, []);
Error:
When I run the above code, I get the following error:
Error: FPStaticServer.start(): Error while converting JavaScript argument 2 to Objective C type BOOL. Objective C type BOOL is unsupported.
I’ve ensured that localOnly: true
is included, but I’m not sure where I’m going wrong.
I’ve attached the package.json file in case it helps to understand the installed libraries and their versions.
package.json
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"react-native": "^0.76.5",
"react-native-fs": "^2.20.0",
"react-native-linear-gradient": "^2.8.3",
"react-native-static-server": "^0.5.0",
"react-native-webview": "^13.12.5"
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.3",
"@babel/runtime": "^7.25.0",
"@react-native-community/cli": "15.0.1",
"@react-native-community/cli-platform-android": "15.0.1",
"@react-native-community/cli-platform-ios": "15.0.1",
"@react-native/babel-preset": "0.76.3",
"@react-native/eslint-config": "0.76.3",
"@react-native/metro-config": "0.76.3",
"@react-native/typescript-config": "0.76.3",
"@types/react": "^18.2.6",
"@types/react-test-renderer": "^18.0.0",
"react-native-clean-project": "^4.0.3",
"react-test-renderer": "18.3.1",
<code>{
"name": "OliveQSolDemo",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"lint": "eslint .",
"start": "react-native start",
"test": "jest"
},
"dependencies": {
"react": "18.3.1",
"react-native": "^0.76.5",
"react-native-fs": "^2.20.0",
"react-native-linear-gradient": "^2.8.3",
"react-native-static-server": "^0.5.0",
"react-native-webview": "^13.12.5"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.3",
"@babel/runtime": "^7.25.0",
"@react-native-community/cli": "15.0.1",
"@react-native-community/cli-platform-android": "15.0.1",
"@react-native-community/cli-platform-ios": "15.0.1",
"@react-native/babel-preset": "0.76.3",
"@react-native/eslint-config": "0.76.3",
"@react-native/metro-config": "0.76.3",
"@react-native/typescript-config": "0.76.3",
"@types/react": "^18.2.6",
"@types/react-test-renderer": "^18.0.0",
"babel-jest": "^29.6.3",
"eslint": "^8.19.0",
"jest": "^29.6.3",
"prettier": "2.8.8",
"react-native-clean-project": "^4.0.3",
"react-test-renderer": "18.3.1",
"typescript": "5.0.4"
},
"engines": {
"node": ">=18"
}
}
</code>
{
"name": "OliveQSolDemo",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"lint": "eslint .",
"start": "react-native start",
"test": "jest"
},
"dependencies": {
"react": "18.3.1",
"react-native": "^0.76.5",
"react-native-fs": "^2.20.0",
"react-native-linear-gradient": "^2.8.3",
"react-native-static-server": "^0.5.0",
"react-native-webview": "^13.12.5"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.3",
"@babel/runtime": "^7.25.0",
"@react-native-community/cli": "15.0.1",
"@react-native-community/cli-platform-android": "15.0.1",
"@react-native-community/cli-platform-ios": "15.0.1",
"@react-native/babel-preset": "0.76.3",
"@react-native/eslint-config": "0.76.3",
"@react-native/metro-config": "0.76.3",
"@react-native/typescript-config": "0.76.3",
"@types/react": "^18.2.6",
"@types/react-test-renderer": "^18.0.0",
"babel-jest": "^29.6.3",
"eslint": "^8.19.0",
"jest": "^29.6.3",
"prettier": "2.8.8",
"react-native-clean-project": "^4.0.3",
"react-test-renderer": "18.3.1",
"typescript": "5.0.4"
},
"engines": {
"node": ">=18"
}
}
Can someone help me identify the issue or provide guidance on how to resolve this error?