Arpith Siromoney 💬

Displaying your webpage

Today’s story is a quick look at what happens when someone visits  constellational.com/you.


The visitor’s request first goes to iwantmyname.com — they host my DNS records — who point them (well, the visitor’s browser) to constellational.herokuapp.com (constellational is currently running on Heroku). Heroku passes the request to the dyno that runs this nodejs code (written using koa).

app.use(serve('public'));
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;
   });
 });
 this.body = generateHTML(user);
});

The code first checks that your request can’t be served with a static file, before splitting the url to get the username (it also tries to figure out the post id if the visitor wanted to see constellational.com/you/yourpost).

function fetchUser(username) {
 return fetch(USER_URL + '/' + username).then(res => res.json());
}
function fetchPost(username, url) {
 return fetch(POST_URL + '/' + username + '/' + url).then(res => res.json());
}

The code then converts your username to lowercase and fetches a file off ofS3 (via cloudfront) that contains the list of urls to your posts. It can then fetch the individual posts before generating HTML (using ReactDOMServer.renderToString()) that’s (finally!) passed back to the visitor. Er, to their browser, atleast.

function generateHTML(user) {
 var contentType = "<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>";
 var viewport = "<meta name='viewport' content='width=device-width, initial-scale=1' />";
 var stylesheet = "<link rel='stylesheet' type='text/css' href='" + CSS_URL + "'>";
 var head = contentType + viewport + stylesheet;
 var reactString = ReactDOMServer.renderToString(React.createElement(views.User, user));
 var body = "<body><div id='react-mount'>" + reactString + "</div></body><script src='" + JS_URL + "'></script></html>";
 return "<html>" + head + body + "</html>";
}

Phew! That code’s a mess, huh? Using a templating system should fix that! I’m also putting the site behind Cloudflare, should write about that!

What’s Constellational? Glad you asked! It’s a home for your notes online, a pleasant way to write and share them. Sign up here!