Yesterday, I mentioned that my app’s webpages (at constellational.com) were being generated by joining strings. This is a way around that, using EJS to place the server side react data into an html template. The template itself is simple:
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
<meta name='viewport' content='width=device-width, initial-scale=1' />
<link rel='stylesheet' type='text/css' href='/style.css'
<title>Constellational</title>
</head>
<body>
<div id='react-mount'><%- react -%></div>
<script src='/main.js' type='text/javascript'></script>
</body>
</html>
All I’ve done is add <%- react -%> where I want my react string to be inserted. I’ve placed this file in a folder called templates, and made a small change to the code that serves the user pages:
var render = require('koa-ejs');
render(app, {root: 'templates'});
app.use(function *() {
var splitURL = this.url.split('/');
splitURL.shift();
var username = splitURL.shift().toLowerCase();
var id = splitURL.shift();
var user = yield fetchUser(username).then((user) => {
if ((id) && (user.posts.indexOf(id) > 0)) {
user.posts.splice(user.posts.indexOf(id), 1);
user.posts.unshift(id);
}
var promiseArr = user.posts.map(id => fetchPost(username, id));
return Promise.all(promiseArr).then((data) => {
user.posts = data;
return user;
});
});
var reactString = ReactDOMServer.renderToString(React.createElement(views.User, user));
yield this.render('layout', {react: reactString});
});
Add koa-ejs to your list of dependencies (in your package.json) and Heroku will take care of the rest! This fixes #11.