I’m building an application using React an Apollo 2 and I’m trying to write a script to generate static html files for server-side rendering.
I’m currently using this logic to render my React component on the server and it’s working fine:
export default (Page) => (req, res) => {
const App = (
<ApolloProvider client={client(fetch)}>
<Main>
<Page />
</Main>
</ApolloProvider>
);
getDataFromTree(App).then(() => {
const data = {
html: ReactDOMServer.renderToString(App),
seo: { title: "Home", description: "" }
};
res.render("index", { data });
});
}
But I wanted to generate the .html
files so I could serve them statically, without running this method every time. I tried to compile the result of renderToString
to an .ejs
file and then write to a file using fs
, but it didn’t work. This is the code:
const component = ReactDOMServer.renderToString(App);
const template = ejs.compile(fs.readFileSync(path.join(__dirname, 'landing_template.ejs'), 'utf-8'));
const html = template({ component });
fs.writeFile(
path.join(__dirname, "../views/landing.ejs"),
html,
err => {
if(err) console.log(err);
else console.log("done.");
});
The file was written successfully but If I open my Page Source the part added by the compile method is grayed out and seems to be ignored:
I also tried just reading the file and replacing the string using .replace
and inserting a dummy div
, but it’s always the same result.
// using compile
const template = ejs.compile(fs.readFileSync(path.join(__dirname, 'landing_template.ejs'), 'utf-8'));
const html = template({ component });
const template = ejs.compile(fs.readFileSync(path.join(__dirname, 'landing_template.ejs'), 'utf-8'));
const html = template({ component: "<div>teste</div>" });
// using readFile
const template = fs.readFileSync(path.join(__dirname, 'landing_template.ejs'), 'utf-8');
const html = template.replace("<%- component %>", component);
const template = fs.readFileSync(path.join(__dirname, 'landing_template.ejs'), 'utf-8');
const html = template.replace("<%- component %>", "<div>teste</div>");
// maybe this is the problem?
fs.writeFile(
path.join(__dirname, "../views/landing.ejs"),
html,
{ encoding: "utf8" },
err => {
if(err) console.log(err);
else console.log("done.");
});
I guess the browser is not recognizing this new text as HTML and failing to parse it. Does any one know a way I can make this work?
Thanks!
2
Answers
What a cool idea! This is probably happening because, as you mentioned, the browser is not recognizing the fact that you are sending html. Try explicitly setting the
Content-Type
header totext/html
before calling render:Edit:
Ah I see it now! You cannot self-close
<script>
tags in HTML unfortunately, and this is tripping the browser up. Close the script tag in your header like so:That should fix the problem.
<script />
is wrong. You have to use this: