Arpith Siromoney 💬

Server Side React + EJS

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.