Reputation: 4352
I am trying to render the whole page in React
only then sending it to the browser. I am getting the following error:
Invariant Violation: Invalid tag:
<!doctype html>
The line that is producing this error is ReactDOMServer.renderToString(el);
:
fs.readFile('./public/index.html',"utf8", function (err, data){
/*res.writeHead(200, {'Content-Type': 'text/html','Content-Length':data.length});
res.write(data);
res.end();*/
var el = React.createElement(data);
console.log("React element was successfully created!");
-----> var html = ReactDOMServer.renderToString(el);
res.send(html);
});
The html
file looks the following way:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
...
<title>React App</title>
</head>
<body>
<div id="root"></div>
<script type="text/javascript" src="bundle.js" charset="utf-8">
</script>
</body>
</html>
How to fix the error? Any suggestions would be greatly appreciated.
Update
I tried to do the following:
var mainData = prepareDataForScatterChart(result);
const html = ReactDOMServer.renderToString(`<App
mainData=${mainData}/>`);
fs.readFile('./public/index.html',"utf8", function (err, data){
const document = data.replace(/<div id="app"><\/div>/, `<div
id="app">${html}</div>`);
res.send(document);
The error is gone, but after I load the page there are errors that mean that the data was not passed to the App
.
Update
I got it working on the server by adding babel-node
, but browser still somehow is not getting the data. So, in the App
I am printing out the mainData
and it is there in the node
console, but in browser it is shown as undefined
. Here is the code that I am using now:
const html = ReactDOMServer.renderToString(<App mainData={mainData}/>);
Upvotes: 6
Views: 5360
Reputation: 854
I'm using the streaming variant.
You can do this (working with express
and react-dom
, but should work with any stream):
function streamingRender(code, res, component) {
res.status(code)
res.write("<!DOCTYPE html>")
renderToNodeStream(component).pipe(res)
}
Upvotes: 2
Reputation: 21
import React from 'react';
import { renderToString } from 'react-dom/server';
// import your app component containing the html structure.
import App from './App.jsx';
// Get your data as required.
const mainData = {};
res.send(
renderToString(`<!DOCTYPE html>${<App mainData={mainData}/>}`)
);
Using fs
to load a static html file and using replace()
are unnecessary unless you have compelling reasons to do so.
Upvotes: 2